- Bootstrapping Clusters with kubeadm → Creating a Cluster with kubeadm
- Installing kubeadm / kubelet / kubectl
- Ubuntu 22.04 LTS VMs (
controlplane,node01,node02) - containerd as the container runtime
- Calico as the CNI plugin
- kubeadm/kubelet/kubectl installed from the official apt repository
Before you begin: follow the official kubeadm docs while performing the steps:
Environment (used in this demo)
Overview — Main steps
- Install required packages and prerequisites.
- Load kernel modules and set sysctl params required by Kubernetes.
- Install and configure containerd with
SystemdCgroup = true. - Install
kubeadm,kubelet, andkubectl. - Ensure kubelet binds to the node IP used for cluster traffic.
- Initialize the control-plane with
kubeadm init. - Install a CNI plugin (Calico in this lesson).
- Join worker nodes to the cluster.
- Validate with an NGINX Deployment and a NodePort service.
1 — Install basic utilities on all nodes
Run oncontrolplane, node01, and node02:
2 — Load kernel modules and set sysctl parameters
Kubernetes requires packet forwarding and bridge network settings. Apply these on all nodes:3 — Install and configure containerd
Installcontainerd and configure it to use systemd cgroups (recommended):
Why
SystemdCgroup = true? Kubelet commonly uses the systemd cgroup driver on modern Kubernetes setups. Matching containerd avoids a cgroup driver mismatch between container runtime and kubelet.4 — Install kubeadm, kubelet and kubectl
Add the Kubernetes apt repository and install the packages on all nodes:crictl/cri-tools to inspect CRI containers:
crictl is helpful for troubleshooting container runtime issues when Kubernetes API is unreachable.
5 — Ensure kubelet binds to the correct node IP (multi-interface environments)
In multi-interface VMs kubelet might pick the wrong IP. If your environment exposes aPRIMARY_IP environment variable per VM (pointing to the intended cluster interface), configure kubelet to use it:
On each node (controlplane, node01, node02):
PRIMARY_IP (example):
PRIMARY_IP, determine the correct interface with ip addr / ip route and replace ${PRIMARY_IP} with that IP.
6 — Initialize the control-plane node
Runkubeadm init on the control-plane node only. Provide the API server advertise address and the pod network CIDR that matches your CNI (Calico expects you to configure its ipPool accordingly). Example:
- Commands to configure kubectl for your user (copy
/etc/kubernetes/admin.conf) - The
kubeadm join ...command for worker nodes
NotReady until a CNI is installed):
Protect the
admin.conf and the kubeadm join token. Anyone with these can gain access to the cluster. If a token is lost, recreate it with sudo kubeadm token create --print-join-command.7 — Install the CNI plugin (Calico example)
Calico needs to know the pod CIDR. Download the Calico custom resources and set theipPool CIDR to match the POD_CIDR used during kubeadm init (10.244.0.0/16 in this example):
On the control-plane node:
8 — Join worker nodes
Whenkubeadm init completed it printed a kubeadm join command. If you lost it, recreate it on the control-plane node:
kubeadm join command with sudo on each worker node (node01, node02). Example (your token/hash will differ):
NotReady, wait for the CNI pods to be scheduled and become healthy.
9 — Quick test: deploy NGINX and expose it via NodePort
Create a Deployment and expose it via a NodePort (example uses node port30143):
Troubleshooting notes and exam tips
- Recreate a lost join command on the control-plane node:
- If nodes remain
NotReady, check:containerdis running and configured with systemd cgroups (SystemdCgroup = truein/etc/containerd/config.toml),- kubelet is bound to the correct
--node-ip, - the CNI is installed and its pod network CIDR matches the one passed to
kubeadm init.
- For certification exams: you will have the official docs available. Practice navigating:
This completes the kubeadm-based cluster installation and validation. You can substitute a different container runtime or CNI plugin: the kubeadm
init/join flow remains the same — only the runtime or network plugin installation steps differ.
Links and References
- Bootstrapping Clusters with kubeadm
- Creating a Cluster with kubeadm
- Installing kubeadm / kubelet / kubectl
- Calico Getting Started (On-Premises)