Skip to main content
In this lesson we demonstrate upgrading a kubeadm-managed Kubernetes cluster from v1.28 → v1.29, following the official kubeadm upgrade guide: https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/.
A screenshot of the Kubernetes website documentation page describing how to upgrade kubeadm clusters, with a left navigation sidebar and links to specific version upgrade guides. The page shows headings and a short numbered upgrade workflow.
This walkthrough covers the core tasks and commands you will run during a minor-version upgrade. The process is consistent across minor upgrades (e.g., any 1.28 → 1.29 path), but always consult the kubeadm upgrade docs for version-specific notes.

Pre-upgrade checks

  1. Confirm cluster node health and current Kubernetes versions:
Example output:
  1. Verify the OS/distribution on each node (some package steps differ by OS):
This demo uses Ubuntu 20.04.6 (Debian-family), so Debian/Ubuntu instructions are shown below. If you run a different distribution, follow the distro-specific repository setup in the kubeadm docs.
A screenshot of the Kubernetes documentation website showing a page titled "Changing the package repository." The page includes a highlighted note about deprecated legacy package repositories and a left-hand navigation menu.

Package repository update (pkgs.k8s.io)

The old Google-hosted repos (apt.kubernetes.io / yum.kubernetes.io) are deprecated. Kubernetes packages are now published at pkgs.k8s.io and you must point your package manager to the target minor-series repo (for example v1.29) and import the Release key before installing kubeadm, kubelet, and kubectl.
Kubernetes packages are now hosted at pkgs.k8s.io. Update your package repository entries and import the Release.key for the target minor series before upgrading kubeadm, kubelet, and kubectl.
On Debian/Ubuntu, perform these steps on every node (control-plane and workers). Replace v1.29 with your target minor series if different.
Query available kubeadm versions to pick the exact patch release (choose the latest patch in the minor series, e.g., 1.29.3):
Example output:
Save the exact package version string (e.g., 1.29.3-1.1) — you will use it when installing kubeadm, kubelet, and kubectl.

Upgrade sequence (high-level)

Follow one node at a time to preserve control-plane availability and workload continuity.

Upgrade kubeadm on a control-plane node

On a control-plane node, unhold kubeadm, install the exact kubeadm package, and hold it again:
Verify the installed kubeadm version:
Plan the upgrade to see recommended actions and components that require manual updates (note: kubelet is always manual):
The plan output shows:
  • current cluster version (e.g., v1.28.0),
  • local kubeadm version (e.g., v1.29.3),
  • available target version(s),
  • components to upgrade manually after kubeadm (kubelet, etc.).

Apply the control-plane upgrade

From the same control-plane node:
What kubeadm upgrade apply does:
  • backs up cluster control-plane config,
  • updates control-plane static pods (kube-apiserver, kube-controller-manager, kube-scheduler),
  • applies required addon changes (CoreDNS, kube-proxy, etc.) if applicable.
After kubeadm upgrade apply completes, the control plane components are upgraded but the kubelet is not. Nodes will still report their old version until you upgrade the kubelet and restart it on each node.

Upgrade kubelet on the control-plane node

Before upgrading kubelet on a node, drain it so workloads are safely evicted (run from a machine with kubectl configured):
On the drained control-plane node, unhold, install the exact kubelet and kubectl packages, then hold, reload systemd, and restart kubelet:
Check node version and scheduling state:
If the node was drained, it will show SchedulingDisabled. Re-enable scheduling:
Repeat the control-plane kubelet upgrade for each control-plane node one at a time. As an alternate documented step, after updating packages on a control-plane node you may run:
to perform node-specific upgrade tasks.
A screenshot of the Kubernetes website blog showing a post titled "What you need to know about the new package repositories?" with the site header and a left sidebar listing 2023 posts. The article text discusses migrating from Google-hosted package repositories and their deprecation timeline.

Upgrade worker nodes

Perform worker upgrades one node at a time to minimize disruption.
  1. On the worker node, update the package repo entry and install the chosen kubeadm version:
  1. From a control-plane node (or any node with cluster-admin kubectl), run the node-level upgrade and then drain the worker:
  1. On the worker node, upgrade kubelet (and optionally kubectl), then restart kubelet:
  1. Uncordon the worker node to resume scheduling:
Confirm the node reports the updated version:
Example final state after both control-plane and worker upgrades:
Repeat the worker-node steps for each worker until the entire cluster is upgraded.

Final notes and best practices

  • kubeadm upgrades control-plane static pods and in-cluster components, but the kubelet must be upgraded separately on every node.
  • Always pick the latest patch release within your target minor series (for example, choose the latest 1.29.x) and install that exact package string when using apt.
  • Upgrade nodes one at a time to keep the control plane and workloads highly available.
  • If using a CNI provider or other cluster add-ons, consult their documentation for any version-specific upgrade steps.
  • Test the upgrade in a staging environment before applying to production.
This completes the demo lesson for upgrading a kubeadm Kubernetes cluster from v1.28 to v1.29.

Watch Video

Practice Lab