Kubernetes cluster upgrades — both control plane and node versions — require careful planning to avoid disrupting running workloads. This guide covers a safe upgrade approach.
Why Cluster Upgrades Need Deliberate Planning
Kubernetes only supports a limited version skew (typically the two most recent minor versions) — falling too far behind means eventually facing a larger, riskier jump; regular, planned upgrades in smaller increments are safer than infrequent large version jumps.
Understanding the Upgrade Order
Control plane components must be upgraded before worker nodes — kubeadm and most managed Kubernetes setups enforce or strongly recommend this ordering, since newer worker nodes with an older control plane can cause compatibility issues.
Step 1 — Review the Release Notes
Before upgrading, review the target version's release notes for breaking changes, deprecated APIs, and specific upgrade considerations — particularly important for any API versions your manifests currently use that might be deprecated/removed.
Step 2 — Check for Deprecated API Usage
kubectl get --raw /metrics | grep apiserver_requested_deprecated_apis
Identify any resources in your cluster still using API versions that will be removed in the target version — address these before upgrading, since resources using removed APIs will fail after the upgrade.
Step 3 — Back Up Before Upgrading
See How to Back Up and Restore a Kubernetes Cluster with Velero — take a full backup before beginning any upgrade, providing a rollback path if something goes genuinely wrong during the process.
Step 4 — Upgrade the Control Plane First (kubeadm Example)
sudo apt update
sudo apt-cache madison kubeadm
sudo apt install kubeadm=1.29.0-1.1
sudo kubeadm upgrade plan
sudo kubeadm upgrade apply v1.29.0
See How to Install kubeadm and Set Up a Multi-Node Kubernetes Cluster for base setup context — kubeadm upgrade plan shows what will change before you commit to the actual upgrade.
Step 5 — Upgrade kubelet and kubectl on the Control Plane Node
sudo apt install kubelet=1.29.0-1.1 kubectl=1.29.0-1.1
sudo systemctl restart kubelet
Step 6 — Upgrade Worker Nodes One at a Time
kubectl drain NODE_NAME --ignore-daemonsets
sudo apt install kubeadm=1.29.0-1.1 kubelet=1.29.0-1.1
sudo kubeadm upgrade node
sudo systemctl restart kubelet
kubectl uncordon NODE_NAME
kubectl drain safely evicts pods from the node before upgrading, allowing them to be rescheduled elsewhere — essential for avoiding disruption; never upgrade a node with active workloads still running on it.
Ensuring Pod Disruption Budgets Are Configured
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: myapp-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: myapp
A PodDisruptionBudget ensures draining a node doesn't remove too many replicas of a critical application simultaneously — particularly important during rolling node upgrades where multiple nodes are drained sequentially.
Verifying Application Health After Each Node Upgrade
Don't proceed to the next node until confirming the previous node's workloads have rescheduled successfully and are healthy — a systematic, verified progression rather than rushing through all nodes without confirmation between steps.
Common Errors
Pods fail to reschedule during node drain — verify sufficient capacity exists on remaining nodes to accommodate evicted pods, and check for any restrictive PodDisruptionBudget or resource constraints preventing successful rescheduling.
Continue Reading
- How to Install kubeadm and Set Up a Multi-Node Kubernetes Cluster
- How to Back Up and Restore a Kubernetes Cluster with Velero
- How to Set Up Rolling Updates and Rollbacks in Kubernetes
Browse more articles in Kubernetes & Container Orchestration.