CKA — Cluster Architecture and the Control-Plane Components — and How to Troubleshoot Them
The exam does not reward memory. It rewards a named architecture walked as a chain, and stopping at the first broken link.
Architecture and troubleshooting are not two topics. They are one skill: name the components as a chain, and diagnosis becomes a walk to the first broken link.
§ IFrame
The CKA is a performance exam. There is no multiple choice. You are dropped onto a live cluster with a terminal and a list of tasks, and you are graded on whether the cluster does what the task asked when time runs out. This changes how you study. Memorizing definitions earns nothing. Being able to find the broken thing and fix it, fast, earns everything.
Two domains carry most of that grade. Cluster architecture, installation, and configuration is a quarter of the exam. Troubleshooting is nearly a third. Together they are more than half the points, and they are the same knowledge seen from two directions. Architecture is knowing the parts of the control plane and what each one does. Troubleshooting is knowing which part failed when a symptom appears. Learn the architecture as a set of loops, the way this morning's Ops lesson framed it, and troubleshooting stops being guesswork and becomes a decision tree you can run under pressure.
Today's trio drills exactly this spine. The Ops lesson gave you the control plane as a room of reconciliation loops. The Dev lesson had you write one. This cert lesson takes the same components and asks the exam's real question: when a Pod will not run, which loop stopped turning, and how do you prove it in sixty seconds.
§ IIDomain Foundations — Architecture and Troubleshooting Share One Spine
Every troubleshooting scenario on the CKA reduces to a single method: follow the claim from where it entered the cluster to where it should have become a running process, and find the first component in that chain that is not doing its job. The chain is fixed, so the method is fixed.
A claim enters at the API server, rests in etcd, is turned into Pods by a controller, is placed on a node by the scheduler, and is run by a kubelet. That is five components in a line. When something is wrong, the fault is at exactly one of them, or at the network or storage a Pod depends on. The exam never asks you to invent a diagnosis. It asks you to walk the chain and stop at the first broken link. This is why the architecture and troubleshooting domains are one study target: you cannot walk a chain whose links you cannot name.
Burns and his coauthors lay out these components in the cluster-deployment chapter that grounds this lesson, and the CKA expects the same list to be automatic for you. Not the definitions. The failure signatures. What does the cluster look like when etcd is down versus when the scheduler is down versus when one node's kubelet has stopped reporting. Those three look nothing alike, and telling them apart on sight is most of the troubleshooting domain.
§ IIIObjective Flavor — The Control-Plane Components as Failure Signatures
The exam wants each component understood by what breaks when it is gone.
The API server is the single door. Everything talks to kube-apiserver and nothing talks to anything else directly. The failure signature is total: if the API server is down, kubectl itself stops working, returning connection-refused. The tell is unmistakable, and the fix on a kubeadm cluster is to check that the API server static Pod is running, because it is not managed by a Deployment. It is a static Pod the kubelet runs from a manifest on disk.
etcd is the memory, and it is where kubeadm keeps everything. If etcd is unhealthy, writes fail and the cluster cannot record new claims. On the exam, etcd questions cluster around backup and restore: you will be asked to snapshot etcd with etcdctl snapshot save and sometimes to restore it. Know the flags cold, because they are fiddly and the exam gives partial credit for nothing. You pass --endpoints, --cacert, --cert, and --key, and you get them from the etcd static Pod manifest at /etc/kubernetes/manifests/etcd.yaml.
Static Pods are the trick under the whole control plane. On a kubeadm cluster the API server, the scheduler, the controller manager, and etcd all run as static Pods. A static Pod is one the kubelet runs directly from a manifest file in /etc/kubernetes/manifests/, with no involvement from the scheduler or the control plane at all. This is the bootstrap answer to a chicken-and-egg problem: the control plane cannot schedule itself, so the kubelet runs it from disk. The exam tests this constantly. Move or edit a file in that directory and the kubelet restarts the corresponding control-plane Pod. If someone asks you why a scheduler change did not take, the first place to look is that manifest.
The scheduler and controller manager are the reconcilers. If kube-scheduler is down, new Pods are created but never assigned a node, so they sit in Pending forever with no events explaining why. That specific signature, Pods stuck Pending with nothing wrong in their spec, points straight at the scheduler. If kube-controller-manager is down, higher-order reconciliation stops: delete a Pod from a Deployment and no replacement appears, because the loop that would notice the gap is not running.
The kubelet is the hands, and its failures are per-node. If one node's kubelet has stopped, that node goes NotReady, its Pods eventually get evicted, and nothing new schedules there. The kubelet runs as a systemd service on the node, not as a Pod, so you debug it with systemctl status kubelet and journalctl -u kubelet, not with kubectl. This is the most common troubleshooting scenario on the exam: a node reports NotReady, and the fix lives in the kubelet's systemd unit or its config, reachable only by SSHing to that node.
§ IVObjective Flavor — The Troubleshooting Method Under the Clock
The troubleshooting domain rewards a fixed procedure over cleverness. Run the same walk every time.
Start where the symptom is and move toward the cause. If a Pod is misbehaving, kubectl get pod tells you its phase, and the phase names the loop that stalled. Pending means it was never scheduled, so look at the scheduler or at whether any node has room. ContainerCreating stuck for a while means the kubelet is trying and failing, usually an image pull or a missing volume, and kubectl describe pod will show the exact event. CrashLoopBackOff means the container starts and dies, so the fault is inside your workload, and kubectl logs --previous shows you why the last attempt died.
The single most valuable command in the exam is kubectl describe. It prints the object's events at the bottom, and the events are the reconciliation history: what each loop tried to do to this object and whether it worked. A FailedScheduling event names the scheduler's reason in plain text. A FailedMount event names a storage problem. You rarely need to reason about a Kubernetes failure. You need to read the events, because the components already wrote down what went wrong.
When the object's own events run out, climb one level. For node problems, kubectl get nodes and then kubectl describe node show conditions like MemoryPressure or NotReady. For control-plane problems on a kubeadm cluster, kubectl get pods -n kube-system shows the static Pods, and if the API server itself is down so kubectl fails, you SSH to the control-plane node and use crictl ps to inspect the containers directly, below the level of the API server. That last move, dropping to crictl when kubectl is dead, separates people who pass the hard troubleshooting questions from people who stall on them.
§ VWorked Scenario — A Node Goes NotReady
Read a scenario the way the exam presents one. A task says: a workload is not running on node-2; investigate and restore it. You have a terminal and the clock is going.
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
cp-1 Ready control-plane 40d v1.30.2
node-1 Ready <none> 40d v1.30.2
node-2 NotReady <none> 40d v1.30.2
# kubectl works -> API server + etcd are up. Fault is at the node -> kubelet.
$ ssh node-2
$ systemctl status kubelet # dead
$ journalctl -u kubelet | tail # cannot reach container runtime
$ systemctl status containerd # inactive (dead)
$ systemctl start containerd
$ systemctl restart kubelet # node-2 returns to Ready within seconds
Walk the chain. kubectl get nodes shows node-2 as NotReady. That single fact eliminates most of the chain at once: the API server is up, because kubectl works; etcd is up, because reads work; the problem is at the node, which means the kubelet. kubectl describe node node-2 confirms the Ready condition is false and shows the kubelet stopped posting status. Now you leave kubectl behind, because a node's kubelet is a systemd service, and SSH to node-2.
On the node, systemctl status kubelet shows the service dead. journalctl -u kubelet shows the reason, and on the exam it is usually one of a small set: a bad --config path, a certificate problem, a full disk, or a container runtime that is not running. Suppose the log shows the kubelet cannot reach the container runtime. systemctl status containerd confirms containerd is down, you start it and restart the kubelet, and within a few seconds node-2 returns to Ready. The reconciliation loops do the rest without you: the scheduler sees a healthy node again, the kubelet pulls the Pods it owns, and the workload comes back.
Notice what made that fast. You did not try things at random. You walked a chain whose links you had already named, eliminated the healthy links by the symptom, and arrived at the kubelet because the signature, a single node NotReady, could not point anywhere else. That is the whole troubleshooting domain: a named architecture turns a mystery into a lookup.
§ VIPractice Questions
Answer each before reading the resolution. On the real exam you would be doing, not choosing, but the reasoning is identical.
kubectl on your workstation returns The connection to the server was refused. Every node was healthy an hour ago. Where do you look first, and why can you not use kubectl to look there?
A newly created Pod has sat in Pending for five minutes. kubectl describe pod shows one event: FailedScheduling: 0/3 nodes are available: 3 Insufficient cpu. Which loop is behaving correctly here, and what is the actual fix?
On a kubeadm cluster you edit /etc/kubernetes/manifests/kube-scheduler.yaml to add a flag. You did not run any kubectl apply. Will the change take effect, and what component applied it?
A node shows NotReady. You run kubectl logs against the kubelet and get an error that no such Pod exists. What did you get wrong about how the kubelet runs, and what is the correct command?
You must back up etcd on a kubeadm control-plane node. etcdctl snapshot save fails with a connection error. What four pieces of information does the command need, and where on the node do you find them?
§ VIIQuestion Resolutions
kubectl, talks only to kube-apiserver, its failure is total and self-concealing: you cannot use the API to diagnose the API. SSH to the control-plane node and inspect the containers directly with crictl ps, and check the API server static Pod manifest at /etc/kubernetes/manifests/kube-apiserver.yaml. This is the scenario that forces you below kubectl.FailedScheduling is the scheduler doing its job, not failing at it./etc/kubernetes/manifests/ directly. Editing the manifest causes the kubelet to restart the scheduler Pod with the new spec. The kubelet applied it, with no scheduler and no kubectl involved. This is why static Pods are the bootstrap answer for the control plane.kubectl logs cannot see it. The kubelet is a systemd service on the node itself. SSH to the node and use systemctl status kubelet and journalctl -u kubelet to read its state and logs. Confusing the kubelet for a Pod is the single most common wrong turn in node troubleshooting.--endpoints (usually https://127.0.0.1:2379), --cacert, --cert, and --key. All four are in the etcd static Pod manifest at /etc/kubernetes/manifests/etcd.yaml, listed as the container's command flags. Copy them from there rather than guessing paths, and set ETCDCTL_API=3 if the tool defaults to v2.§ VIIIClosing
The CKA does not reward memory. It rewards a named architecture walked as a chain. A claim enters at the API server, rests in etcd, becomes Pods through the controllers, is placed by the scheduler, and is run by the kubelet, and when anything is wrong the fault is at exactly one of those links, or at the storage or network a Pod needs. Know the failure signature of each component, read events with kubectl describe before you reason, and drop to crictl and journalctl when the API server or a kubelet takes kubectl away from you. That is more than half the exam, and it is the same loop your Ops lesson named and your Dev lesson wrote.
Before the next K8s day, take a cluster you can break and break it on purpose. Stop containerd on a worker and watch the node go NotReady. Move the scheduler manifest out of the manifests directory and watch new Pods pile up in Pending. Each deliberate break teaches you a signature you will recognize instantly under the clock, which is the only place recognition counts.
Paired lessons → Ops 01-Earth-DevOps/Synthesis-Lessons/2026-07-23-the-kubernetes-reconciliation-loop-... · Dev Polyglot-Dev/Python/2026-07-23-writing-a-kubernetes-controller-in-python-...
Filed 2026-07-23 Thursday Fajr · Cert-Prep lesson · CKA-emphasis (k8s_day #0) · Kubernetes deep-mastery track
Backward-Synergy-Reach → today's Ops reconciliation loop + Dev controller · Terraform Associate 003 (Wed 07-22)
Grounded in Kubernetes: Up and Running 3ed Ch 3–4 + current CKA blueprint · HTML shipped in-cycle per HARD DISCIPLINE · aether-accent