Introduction
Troubleshooting a Kubernetes cluster deployed with kubeadm requires a systematic approach that connects observed symptoms to verified fixes. This guide walks through the architecture of kubeadm-based clusters, the common failure modes, and the exact commands you need to diagnose and resolve issues safely. By the end, you will have a repeatable workflow that limits blast radius, protects sensitive data, and verifies every change before declaring success.
Kubeadm is the official tool for bootstrapping Kubernetes clusters, but it does not manage the cluster lifecycle after initialization. That means operators must understand how kubeadm pieces together the control plane and worker nodes, and how to inspect those components when things go wrong. We cover version inventories, configuration paths, diagnostic techniques, failure modes, and an operations checklist, all with concrete examples.
Version and Environment Inventory
Before touching anything, you must know exactly what you are running. Start by collecting the Kubernetes version, kubeadm version, container runtime, and node status. These read-only commands set the foundation for every later decision.
# Kubernetes server version
kubectl version --short
# kubeadm version
kubeadm version
# Container runtime (example with containerd)
ctr version
# Node status and details
kubectl get nodes -o wide
Expected output should show a consistent version across nodes, for example v1.29.1. If you see a mismatch between kubectl version client and server, note it; minor differences are often acceptable, but major version gaps can cause API incompatibilities. For production clusters, pin versions and plan upgrades carefully.
Capture the deployment topology: is this a single control plane, stacked etcd, or external etcd? Use kubectl get pods -n kube-system to list system pods and see which are running on which nodes. This inventory step is read-only and safe to run at any time. Never use real credentials in commands; replace them with placeholders in any shared documentation.
Safe Configuration Path
Configuration changes are where most outages begin. Kubeadm stores cluster configuration in a ConfigMap and uses a configuration file for initialization and upgrades. When you need to modify a component, follow a path that minimizes risk: observe, back up, change one item, verify, and have a rollback plan.
Identifying Configuration Sources
Kubeadm writes cluster configuration to kubeadm-config in the kube-system namespace. View it with:
kubectl get configmap kubeadm-config -n kube-system -o yaml
This shows the ClusterConfiguration and ClusterStatus. Before changing anything, export it to a file for backup:
kubectl get configmap kubeadm-config -n kube-system -o jsonpath='{.data.ClusterConfiguration}' > cluster-config-backup.yaml
Applying a Scoped Configuration Change
Suppose you need to increase the API server's request timeout. Edit the ConfigMap directly using kubectl edit, but be aware that changes to the ConfigMap do not automatically restart control plane components. Kubeadm-managed static pods only pick up changes after they are restarted. The safe approach is to move the static pod manifest temporarily, let the kubelet restart the component, and verify.
Example: Modify the API server manifest.
# Backup the manifest
cp /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/kube-apiserver.yaml.bak
# Edit the manifest to add --request-timeout=60s
vi /etc/kubernetes/manifests/kube-apiserver.yaml
# The kubelet detects the change and restarts the API server automatically
Then verify the API server is healthy:
kubectl get pods -n kube-system | grep kube-apiserver
kubectl get --raw='/readyz?verbose'
The second command should return ok for all checks if the API server is ready. If the new setting causes a failure, restore the backup manifest and the kubelet will revert to the previous configuration.
Verification and Diagnostics
When a cluster is misbehaving, you need a methodical way to narrow down the cause. This section covers the key diagnostic commands and how to interpret their output.
Control Plane Health
Check the health of the control plane components (etcd, API server, controller manager, scheduler) using the kubectl get pods -n kube-system command. Since these run as static pods, their names end with the node name. For a single control plane node, expect all four to be Running.
If a pod is CrashLoopBackOff, inspect its logs:
kubectl logs -n kube-system kube-apiserver-<node-name> --tail=50
Look for common errors such as misconfigured certificates, unreachable etcd, or invalid flags. The API server will not start if it cannot reach etcd, so always verify etcd health first.
Kubelet and Container Runtime Issues
The kubelet is the node agent that starts static pods and communicates with the API server. Check its status:
systemctl status kubelet
journalctl -u kubelet -n 50 --no-pager
If the kubelet cannot start, it may be due to a missing container runtime endpoint. Verify the runtime socket is correct in /var/lib/kubelet/config.yaml and that the runtime is running.
For containerd:
systemctl status containerd
ctr images list
If the runtime is healthy but kubelet still fails, check the kubelet configuration for correct paths and authentication.
Network Diagnostics
Pod networking issues often surface as services not being reachable or pods unable to communicate. Common CNI plugins include Calico, Flannel, and Cilium. Check the CNI pods:
kubectl get pods -n kube-system | grep -E 'calico|flannel|cilium'
If a CNI pod is not running, inspect its logs. Also verify that the node has the required CNI binaries in /opt/cni/bin and configuration in /etc/cni/net.d/.
Use kubectl describe pod to see events that might indicate network setup failures.
Failure Modes and Recovery
Kubeadm clusters can fail in predictable ways. This section covers some of the most common failure modes and how to recover from them with minimal downtime.
Failed kubeadm init
A kubeadm init can fail for various reasons: missing prerequisites, firewall blocks, or existing cluster leftovers. If init fails, run kubeadm reset to clean up before retrying. This command removes all Kubernetes-related files and restores the node to a pre-init state.
kubeadm reset
After reset, check that required ports are open and system requirements are met. Then re-run init with the same configuration file, if used.
Certificate Expiry
Kubernetes certificates have a one-year validity by default. If they expire, the API server will fail to start. Check certificate expiry:
kubeadm certs check-expiration
If certificates are expired, renew them:
kubeadm certs renew all
Then restart the control plane components (or reboot the node) to pick up the new certificates. To prevent future expiration, set up a renewal cron job or use kubeadm certs renew before expiry.
etcd Data Corruption
etcd is the backing store for all cluster state. Corruption can cause the API server to lose data or fail completely. Always have an etcd backup:
# Snapshot etcd
ETCDCTL_API=3 etcdctl snapshot save /backup/etcd-snapshot.db \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
To restore from a snapshot, stop etcd, restore the data, and restart. This process is complex and should be practiced in a non-production environment first.
Node NotReady
A node may show NotReady for many reasons: kubelet down, network partition, or resource exhaustion. First, check the kubelet status on that node:
systemctl status kubelet
If kubelet is running, describe the node to see conditions:
kubectl describe node <node-name>
Look for MemoryPressure, DiskPressure, or NetworkUnavailable conditions. Address the underlying issue (free disk space, fix network, etc.) and the node should return to Ready.
Common Pitfalls and How to Avoid Them
Even experienced operators fall into traps. Here are some frequent mistakes and how to steer clear of them.
- Ignoring version skew: Kubernetes components have a supported version skew policy. Running a newer kubectl against an older API server can cause errors. Always align client and server versions within the supported range. Check the official Kubernetes version skew policy before upgrades.
- Editing etcd directly: Directly manipulating etcd data without proper backup can corrupt the cluster. Always use
kubeadmor Kubernetes API for changes, and maintain etcd snapshots.
- Disabling swap after installation: Kubelet requires swap to be off. If swap is enabled after cluster creation, kubelet will fail. Ensure swap is permanently disabled in
/etc/fstaband that the system is rebooted if necessary.
- Overlooking certificate renewal: As mentioned, certificates expire annually. Set reminders and automate renewal using
kubeadm certs renewin a cron job on the control plane.
- Using the wrong container runtime socket: Kubeadm defaults may not match your runtime configuration. Always verify the socket path in the kubelet config and runtime installation.
Operations Checklist
Use this checklist for routine maintenance and troubleshooting. For each item, assign a single owner (for example, Priya Shah, Engineering Lead) and set a review frequency (weekly, monthly, or before each release).
| Check | Command | Expected Result | Owner | Frequency |
|---|---|---|---|---|
| Cluster nodes healthy | kubectl get nodes | All nodes Ready | Priya Shah | Weekly |
| Control plane pods running | kubectl get pods -n kube-system | All critical pods Running | Alex Chen | Weekly |
| Certificate expiry | kubeadm certs check-expiration | No cert expiring within 30 days | Priya Shah | Monthly |
| etcd backup | etcdctl snapshot save | Snapshot file created | Jordan Lee | Daily |
| Kubelet status on nodes | systemctl status kubelet | Active (running) | Alex Chen | Monthly |
| CNI plugin health | kubectl get pods -n kube-system (filter CNI) | All CNI pods Running | Jordan Lee | Weekly |
| Disk usage on nodes | df -h | Usage below 80% | Priya Shah | Monthly |
| Log rotation | ls -l /var/log/containers | No oversized logs | Alex Chen | Monthly |
Conclusion
Troubleshooting kubeadm architecture is a skill built on careful observation, version awareness, and controlled changes. Every command in this guide is read-only or reversible when possible, and includes verification steps to confirm the cluster is healthy again. Start with the least invasive diagnostic, record current state, and only change one component at a time. Document your recovery steps and test them regularly in a staging environment.
For deeper dives, consult the official Kubernetes documentation on kubeadm and the troubleshooting guides for specific components like etcd and CNI plugins. With the practices outlined here, you can handle most cluster issues and keep your Kubernetes environment resilient.
Next step: pick one low-risk verification from the checklist, run it on your cluster, and compare the result with the expected output. Then review your backup and recovery procedures for etcd and certificates.