Building a cluster from nothing is the least glamorous and most under-practised skill on the CKA exam. Most candidates drill workloads, networking, and troubleshooting until those are reflexes, then freeze when a task says “initialise a control plane on this node and join node01 to it.” The commands are short, but the order matters, one missed prerequisite leaves the API server refusing to come up, and forgetting the CNI leaves every pod stuck in Pending with a confusing error.
This guide walks the full kubeadm bootstrap the way the exam frames it: the host prerequisites the kubelet needs before it will start, kubeadm init on the control plane, installing a pod network (CNI), joining worker nodes, and regenerating a join command when the original scrolled off the screen. It pairs directly with the CKA cluster upgrade guide — installation and upgrade are the two halves of Domain 1’s lifecycle work — and with the CKA networking deep dive, which explains what the CNI you install is actually doing. If you are still scoping your prep, start with the CKA exam guide for 2026.
Why kubeadm Installation Is on the Exam
The CKA “Cluster Architecture, Installation & Configuration” domain is worth roughly a quarter of the exam, and one of its explicit competencies is “use kubeadm to install a basic Kubernetes cluster.” The graders are not testing whether you can memorise a vendor’s install script — they are testing whether you understand the ordered dependency chain that turns a bare Linux host into a working node:
- The container runtime must be running and reachable.
- The kubelet must be installed and able to start.
kubeadm initbootstraps the control plane and writes the admin kubeconfig.- A CNI plugin must be applied before nodes report
Ready. - Workers join with a token-authenticated
kubeadm join.
Break the chain at any link and the symptom shows up several steps later, which is exactly why this topic separates candidates who understand the machinery from those who copy commands. kubeadm itself is just an orchestrator — it does not install a runtime, and it does not install networking. Knowing what it does not do is half the battle.
Prerequisites: What Every Node Needs First
Before kubeadm will run cleanly, each node — control plane and workers alike — needs a short list of host-level settings. On the exam these are often pre-configured, but when they are not, a missing one produces a preflight error that you must be able to read and fix.
| Requirement | Why it matters | How to satisfy it |
|---|---|---|
| Swap disabled | The kubelet refuses to start with swap on (by default) | swapoff -a and remove the swap line from /etc/fstab |
br_netfilter module | Bridged traffic must be visible to iptables | modprobe br_netfilter |
| Bridged traffic sysctls | Enables the CNI/kube-proxy dataplane | Set net.bridge.bridge-nf-call-iptables=1 and net.ipv4.ip_forward=1 |
| Container runtime | kubeadm needs a CRI endpoint | Install/enable containerd (or CRI-O) |
| kubeadm, kubelet, kubectl | The tooling itself | Install matching versions from the Kubernetes apt/yum repo |
A minimal prerequisite block looks like this:
# 1. Turn off swap for this boot and permanently
swapoff -a
sed -i '/ swap / s/^/#/' /etc/fstab
# 2. Load the bridge netfilter module and make it persistent
modprobe br_netfilter
echo "br_netfilter" | tee /etc/modules-load.d/k8s.conf
# 3. Kernel networking parameters kubeadm's preflight checks expect
cat <<EOF | tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sysctl --system
The single most common preflight failure is swap still enabled. If kubeadm init aborts complaining about swap, swapoff -a and rerun. Memorise that reflex — it is worth easy points.
Step 1: kubeadm init on the Control Plane
With prerequisites in place, you bootstrap the first control-plane node. The one flag you almost always care about is --pod-network-cidr, because the value must match what your CNI expects.
kubeadm init \
--pod-network-cidr=10.244.0.0/16 \
--apiserver-advertise-address=192.168.1.10
--pod-network-cidr— the address range pods will be allocated from. Flannel wants10.244.0.0/16; Calico defaults to192.168.0.0/16. Pick the value your CNI documents, or pods never get IPs.--apiserver-advertise-address— the IP other nodes will use to reach the API server. Set it explicitly on a multi-NIC host so kubeadm does not guess the wrong interface.
kubeadm init runs preflight checks, generates the cluster’s certificate authority, writes the control-plane static pod manifests into /etc/kubernetes/manifests, starts the kubelet, and — critically — prints the kubeadm join command you will need for workers. Copy that join line somewhere safe immediately. Losing it is the most common self-inflicted wound in this task; you can regenerate it (covered below), but on a timed exam that is wasted minutes.
Configure kubectl Access
init writes an admin kubeconfig to /etc/kubernetes/admin.conf. To use kubectl as a normal user, copy it into place:
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
# Verify the control-plane components are up
kubectl get pods -n kube-system
If you are working as root on the exam node, you can instead export KUBECONFIG=/etc/kubernetes/admin.conf. Either way, confirm you can talk to the API server before moving on.
Step 2: Install a Pod Network (CNI)
Right after init, run kubectl get nodes and you will see the control-plane node stuck in NotReady. That is expected and not a bug — Kubernetes has no built-in pod networking. Until a CNI plugin is installed, the network is not ready, so the node cannot be scheduled onto and CoreDNS stays Pending.
Apply a CNI manifest to fix it:
# Example: install a pod-network add-on from its manifest URL
kubectl apply -f <cni-manifest-url>
# Watch the node flip to Ready once the CNI pods are running
kubectl get nodes -w
Within a minute or two the node should report Ready and the CoreDNS pods in kube-system should move from Pending to Running. If the node stays NotReady after applying the CNI, the usual culprit is a CIDR mismatch — the --pod-network-cidr you passed to init does not match what the CNI manifest configures. The CKA networking deep dive covers just enough CNI awareness to reason about this on exam day; you do not need to know a plugin’s internals, only that the CIDRs must agree.
Step 3: Join Worker Nodes
On each worker (after completing the same prerequisites and runtime install), run the kubeadm join command that init printed. It looks like this:
kubeadm join 192.168.1.10:6443 \
--token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:<hash>
The three pieces do distinct jobs:
192.168.1.10:6443— the API server endpoint the node will register against.--token— a short-lived bootstrap token that authorises the join. Default tokens expire after 24 hours.--discovery-token-ca-cert-hash— lets the joining node verify it is talking to the real control plane and not an imposter, by pinning the CA public key.
Back on the control plane, confirm the worker registered:
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# controlplane Ready control-plane 6m v1.32.0
# node01 Ready <none> 40s v1.32.0
A freshly joined worker briefly shows NotReady while the CNI pods schedule onto it — give it a moment before assuming something is wrong.
Regenerating a Join Command
This is an exam favourite: the join command has scrolled off the screen, or the token has expired, and you need to add a node. Do not re-run kubeadm init. Instead, generate a fresh, complete join command in one shot:
kubeadm token create --print-join-command
That single command mints a new token and prints the full kubeadm join ... line, CA hash included — ready to paste onto the worker. If you only need to inspect existing tokens or the hash separately:
# List active bootstrap tokens and their TTLs
kubeadm token list
# Compute the CA cert hash manually (rarely needed if you use the command above)
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt \
| openssl rsa -pubin -outform der 2>/dev/null \
| openssl dgst -sha256 -hex | sed 's/^.* //'
Commit kubeadm token create --print-join-command to memory. It is the fastest recovery from a lost or expired token and turns a potentially panicky moment into a two-second fix.
Highly-Available Control Planes (Conceptual)
The CKA also expects awareness of “manage a highly-available control plane.” You are unlikely to build a full multi-master HA cluster from scratch under time pressure, but you should understand the shape of it.
An HA cluster runs three or more control-plane nodes behind a load balancer, so the failure of any one API server does not take the cluster down. There are two topologies:
| Topology | Where etcd runs | Trade-off |
|---|---|---|
| Stacked etcd | etcd runs on the same nodes as the control-plane components | Simpler to set up; losing a node loses both an API server and an etcd member |
| External etcd | etcd runs on its own dedicated nodes | More resilient and easier to scale; more machines to manage |
The mechanics that make HA work:
- A load balancer fronts the API servers;
kubeadm inituses--control-plane-endpointto point every node at that stable address rather than a single node’s IP. - Additional control-plane nodes join with
kubeadm join --control-plane(note the extra flag), which copies certificates and adds another API server, scheduler, and controller-manager. - etcd is a quorum system — it needs a majority of members alive to accept writes. That is why you run an odd number (3, 5): a three-member cluster tolerates one failure, a five-member cluster tolerates two.
If you want to go deeper on the etcd side of HA — and on protecting cluster state generally — the etcd backup and restore guide is the natural next read, since a healthy backup is your last line of defence when a control-plane node is lost.
Verifying the Cluster Is Actually Healthy
Installation is not finished when kubectl get nodes shows Ready. Run a quick health sweep the way you would on any handover:
# All nodes Ready?
kubectl get nodes
# Control-plane and CoreDNS pods Running?
kubectl get pods -n kube-system
# Component health (static-pod control planes)
kubectl get --raw='/readyz?verbose'
# Can you actually schedule a workload?
kubectl run smoke --image=nginx --restart=Never
kubectl get pod smoke -o wide # confirm it lands on a worker and goes Running
kubectl delete pod smoke
That last smoke test — schedule a pod, confirm it runs on a worker, delete it — is the fastest end-to-end proof that the runtime, kubelet, scheduler, and CNI are all cooperating. Keep the CKA troubleshooting guide in mind for when one of these checks fails: a NotReady node almost always traces back to the kubelet or the CNI, and a Pending pod almost always traces back to networking or scheduling constraints.
Common Mistakes That Cost Points
- Forgetting the CNI. Nodes sit
NotReadyand CoreDNS staysPending. Apply a pod network before you conclude anything is broken. - CIDR mismatch.
--pod-network-cidrmust match the CNI’s expected range. When in doubt, use the value the CNI’s own manifest documents. - Swap left on.
kubeadm initaborts at preflight.swapoff -aand rerun. - Running commands on the wrong node.
kubeadm initruns on the control plane;kubeadm joinruns on the worker. Mixing them up wastes time. - Re-running
initto recover a lost token. Never. Usekubeadm token create --print-join-command. - Not configuring kubeconfig. After
init,kubectlfails with a connection-refused error until you copyadmin.confinto place or exportKUBECONFIG. - Skipping
sysctl --system. If bridged-traffic sysctls are not applied, pod-to-pod networking behaves strangely even after the CNI is installed.
From Reading to Reflex
You can read this sequence and follow every step — and still lose points if you have only ever read it. The kubeadm bootstrap rewards muscle memory: prerequisites, init, kubeconfig, CNI, join, verify. Under the exam clock, hesitating over “wait, do I install the CNI before or after joining workers?” is exactly the kind of friction that turns a five-minute task into fifteen.
That is the gap realistic practice closes. The Certified Kubernetes Administrator (CKA) Mock Exam Bundle puts you in a live cluster running performance-lab tasks — bootstrapping control planes, joining nodes, and fixing the failures above — so the ordered chain becomes automatic before exam day. Pair it with the 30-day CKA study plan to schedule your hands-on reps, keep the kubectl cheat sheet nearby for the flags, and follow with the cluster upgrade guide to complete the cluster-lifecycle picture.
Frequently Asked Questions
Do I need to install a container runtime before kubeadm?
Yes. kubeadm does not install a runtime — it expects one already running with a CRI endpoint (containerd or CRI-O). On many exam nodes the runtime is pre-installed, but if kubeadm init fails a preflight check about the container runtime, install and enable containerd first, then rerun.
Why is my node NotReady right after kubeadm init?
Because no pod network is installed yet. Kubernetes has no built-in CNI, so the node cannot become Ready until you apply a network add-on. Run kubectl apply -f <cni-manifest> and the node should flip to Ready within a minute or two.
How do I get the join command if I lost it?
Run kubeadm token create --print-join-command on the control-plane node. It creates a fresh bootstrap token and prints the complete kubeadm join line, including the CA cert hash. Never re-run kubeadm init just to recover a token.
How long is a kubeadm bootstrap token valid?
Default bootstrap tokens expire after 24 hours. If a worker fails to join with a token-related error, the token has likely expired — generate a new join command with kubeadm token create --print-join-command.
What is the difference between kubeadm join for a worker and for a control-plane node?
A worker join uses kubeadm join <endpoint> --token ... --discovery-token-ca-cert-hash .... Adding another control-plane node in an HA cluster uses the same command plus --control-plane, which copies the necessary certificates and starts an additional API server, scheduler, and controller-manager.
Does the CKA require me to build a highly-available cluster from scratch?
Building a full multi-master HA cluster under time pressure is uncommon on the exam, but you are expected to understand the concept: three or more control-plane nodes behind a load balancer, stacked versus external etcd, and why etcd needs an odd number of members for quorum. Focus your hands-on time on the single-control-plane init/join flow, and know the HA shape conceptually.