kubeadm bootstraps a cluster, but it assumes each host is already prepared: a container runtime installed, the kernel configured for container networking, and the kubelet able to manage resources. Its preflight checks will stop you if some of these are wrong, and the CKA can ask you to fix a host that fails them.
Start with the container runtime. containerd is the most common choice. Install it, generate a default config with containerd config default > /etc/containerd/config.toml, and make sure the runc runtime options set SystemdCgroup = true. On systemd-based distributions the kubelet uses the systemd cgroup driver by default when configured by kubeadm, and the runtime must use the same driver. If the kubelet and the runtime disagree on the cgroup driver, Pods and even the node can become unstable. Restart containerd after editing the file.
Next, swap. Historically the kubelet refused to start with swap enabled, and the standard preparation step is still to disable it: swapoff -a for the running system and comment out swap lines in /etc/fstab so it stays off after a reboot. Newer Kubernetes releases have added configurable swap support, but unless a task tells you otherwise, disabling swap is the safe expectation.
Container networking needs two kernel modules. overlay supports the overlay filesystem that container images use, and br_netfilter makes bridged traffic visible to iptables. Load them now with modprobe and persist them in a file under /etc/modules-load.d/. Then set sysctls so the kernel forwards packets and passes bridged traffic through iptables.
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay && sudo modprobe br_netfilter
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
sudo sysctl --system
Finally, ports. Control plane nodes need 6443 (API server), 2379 and 2380 (etcd client and peer), 10250 (kubelet API), 10257 (controller-manager) and 10259 (scheduler) reachable as appropriate. Worker nodes need 10250 plus the NodePort range, 30000 to 32767 by default. Your CNI plugin may need its own ports as well. Install kubeadm, kubelet and kubectl at matching versions from the Kubernetes package repository and hold them so routine updates do not upgrade them by surprise (for example apt-mark hold kubelet kubeadm kubectl).
Key terms
- cgroup driver
- How the kubelet and runtime create control groups; both must use the same one, normally systemd.
- br_netfilter
- A kernel module that lets iptables see traffic crossing a Linux bridge.
- net.ipv4.ip_forward
- The sysctl that allows the kernel to route packets between interfaces, required for Pod traffic.
- Preflight checks
- Tests kubeadm runs before init or join to catch host misconfiguration.
kubeadm init fails preflight with a message that /proc/sys/net/ipv4/ip_forward contents are not set to 1. You add net.ipv4.ip_forward = 1 to /etc/sysctl.d/k8s.conf, run sysctl --system, and rerun init, which now passes.
SystemdCgroup = true in the containerd config and restart containerd whenever you touch it.Check yourself
Which two kernel modules are loaded when preparing a kubeadm host, and why?
overlay for the container image filesystem and br_netfilter so bridged Pod traffic passes through iptables.
Where do you persist sysctl settings so they survive a reboot?
In a file under /etc/sysctl.d/, applied with sysctl --system.
What is the default NodePort range that must be open on nodes?
30000 to 32767.