⌂ Home

Kubernetes Control Plane Troubleshooting

Interactive guide: architecture, symptoms, checks, and recovery paths for API Server, Scheduler, Controller Manager, and etcd.

Control plane architecture

Every control plane component coordinates through the API Server. Cluster state lives in etcd; controllers and the scheduler read and write desired state via the API.

kube-apiserver REST + auth etcd consistent store Scheduler binds pods → nodes Controller Manager reconcile loops watch/list/write via API persist keys

Interaction rule Schedulers and controllers never talk to etcd directly in a standard cluster—they use the API Server, which validates and persists changes.

Quick reference: who does what

API Server Front door for kubectl and components; admission, authn/z, validation; watches.
Scheduler Assigns unscheduled Pods to Nodes (filters + scores).
Controller Manager Runs controllers (Deployment, ReplicaSet, Job, Node, etc.).
etcd Stores all Kubernetes object data; quorum required for writes.

Common failures

  • OOM API Server killed under memory pressure—check node resources and request limits.
  • Certs Expired or mismatched TLS between apiserver ↔ etcd or clients.
  • etcd Unreachable or unhealthy—API returns errors or timeouts on writes.
  • Port Another process bound to 6443 (or configured secure port).
  • RBAC Misconfigured ClusterRoleBindings—symptoms look like “forbidden” for controllers or users.

Diagnosis flow

SymptomCheckDiagnoseFix direction
kubectl hangs / TLS errorsCerts, connectivity to VIP/LBOpenSSL / apiserver logsRotate certs, fix SANs, fix LB
500s / timeout on mutating APIetcd health, disketcdctl, apiserver logsRestore quorum, free disk
Pod CrashLoop (static pod)describe, node logsOOMKilled, args, mountsIncrease memory, fix flags
“Forbidden” for system accountsRBAC objectsauth can-i, auditRepair RoleBindings

Key commands

kubectl get --raw /healthz
kubectl get --raw /livez
kubectl get --raw /readyz
# systemd control plane (many kubeadm clusters)
sudo journalctl -u kube-apiserver -f

# Pod-based control plane
kubectl logs -n kube-system kube-apiserver-<node-name> -f
crictl ps | grep kube-apiserver
ss -tlnp | grep 6443

Sample: failing API Server pod

kubectl describe pod -n kube-system kube-apiserver-control-plane often shows exit reason, OOM, mount failures, or bad flags.

Name:             kube-apiserver-control-plane
Namespace:        kube-system
...
State:            Waiting
  Reason:         CrashLoopBackOff
Last State:       Terminated
  Reason:         OOMKilled
  Exit Code:      137
...
Events:
  Warning  BackOff  12s (x15)  kubelet  Back-off restarting failed container kube-apiserver

Common failures

  • Pods stuck in Pending with scheduling events.
  • Scheduler static pod / deployment not running on control plane nodes.
  • Control plane or worker resource pressure (CPU, memory, ephemeral storage).

Diagnosis

Use events and Pod details—scheduling failures are usually explicit in Events.

kubectl get events -A --sort-by=.lastTimestamp | tail -40
kubectl describe pod <pod> -n <ns>
kubectl get pods -n kube-system | grep scheduler
kubectl logs -n kube-system kube-scheduler-<node-name> --tail=100

Scenarios

  • Resources “0/X nodes available: insufficient cpu/memory”—raise limits, add nodes, or reduce requests.
  • Taints “didn’t tolerate taint”—add tolerations or remove taints where appropriate.
  • Affinity node/pod affinity rules too strict—relax requiredDuringScheduling or fix labels.
  • PDB PodDisruptionBudget blocking eviction—not a scheduler bug; check voluntary disruption constraints.

Common failures

  • ReplicaSet not creating Pods or not matching Deployment generation.
  • Deployment stuck progressing—ReplicaSets exist but readiness never converges.
  • Jobs not completing—controller not creating Pods or stuck on backoff limits.

Diagnosis

Correlate Deployment → ReplicaSet → Pod graph with events. Controller-manager logs show sync errors, quota denials, or API errors.

kubectl describe deployment <name> -n <ns>
kubectl get rs -n <ns> -l app=<label>
kubectl logs -n kube-system kube-controller-manager-<node-name> --tail=200

Scenario: “1/3 replicas available”

  1. Confirm three ReplicaSet Pods exist: kubectl get pods -l app=...
  2. If Pods exist but not Ready, debug probes, mounts, and image pull—not controller-manager.
  3. If fewer than three Pods, check RS spec, quota, and controller-manager logs for sync failures.
  4. Check PDB and rollout strategy maxUnavailable—may throttle creation during surge.

Common failures

  • Quorum loss Majority of members down—cluster read-only or API failures.
  • Latency Slow fsync/disk—watch delays, timeouts.
  • Disk Full or high usage—etcd raises alarms, compaction needed.
  • Backup/restore Wrong member set, version skew, or corrupt snapshot.

Diagnosis (etcdctl)

Set endpoints and TLS flags to match your cluster. Example with TLS:

export ETCDCTL_API=3
export ETCDCTL_ENDPOINTS="https://127.0.0.1:2379"
export ETCDCTL_CACERT=/etc/kubernetes/pki/etcd/ca.crt
export ETCDCTL_CERT=/etc/kubernetes/pki/apiserver-etcd-client.crt
export ETCDCTL_KEY=/etc/kubernetes/pki/apiserver-etcd-client.key

etcdctl endpoint health
etcdctl endpoint status -w table
etcdctl alarm list

Key metrics (watch in monitoring)

  • WAL fsync duration — sustained spikes imply storage or overload.
  • Backend commit duration — high values correlate with API slowness.
  • Member leader changes — network or resource instability.

Recovery: snapshot restore (high level)

  1. Stop kube-apiserver (and often etcd members) per your runbook—avoid split-brain.
  2. Restore snapshot with etcdctl snapshot restore into clean data dirs for members.
  3. Reconcile static pod manifests or systemd units so all members start with consistent state.
  4. Start etcd, verify endpoint health, then start API Server; validate with kubectl get nodes.

See etcd backup & restore for the dedicated walkthrough.

Decision tree: what’s broken?

kubectl errors / TLS? → API Server tab: /healthz, /readyz, certs, port 6443, apiserver logs All workloads Pending? → Scheduler tab: events, describe pod, scheduler pod logs Deployments / Jobs not moving? → Controller Manager tab: describe deploy/rs, controller-manager logs API timeouts + etcd alarms / quorum? → etcd tab: endpoint health, alarms, disk; restore runbook Pods Ready/Probe issues? → ./health-probes.html

Commands by component

ComponentCommands
API Serverkubectl get --raw /healthz|/livez|/readyz; journalctl -u kube-apiserver; kubectl logs -n kube-system kube-apiserver-<node>; ss -tlnp | grep 6443
Schedulerkubectl get events; kubectl describe pod; kubectl logs -n kube-system kube-scheduler-<node>
Controller Managerkubectl describe deploy/rs; kubectl logs -n kube-system kube-controller-manager-<node>
etcdetcdctl endpoint health; etcdctl endpoint status; etcdctl alarm list; snapshot restore workflow
Generalkubectl get pods -n kube-system; crictl ps; node and disk checks on control plane

CKA tips (troubleshooting domain)

  • Start from symptoms: get events, describe, then narrow to the failing component.
  • Know the difference between /livez (running) and /readyz (accepting traffic)—useful under load or startup.
  • For scheduling, quote the exact event reason in your answer (e.g. FailedScheduling message).
  • Practice etcdctl with TLS env vars; quorum loss is a common exam narrative.
  • Time-box: fix the smallest change that proves the theory (one flag, one taint, one binding).