APT Package Management for Kubernetes Upgrades¶
Reference: https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/
Why Package Pinning Exists¶
In a production cluster, you never want apt upgrade or an automated update system to accidentally pull a new Kubernetes version. A surprise kubelet upgrade can kill running workloads — the kubelet restarts and takes all containers on that node with it.
apt-mark hold <package> pins a package to its current version. It's excluded from all upgrades — even apt upgrade or unattended-upgrades — until you explicitly unhold it.
This means you can safely run apt upgrade on the system (for OS security patches) without accidentally touching Kubernetes packages.
The Hold / Unhold Pattern¶
Every single Kubernetes package upgrade follows this exact pattern:
1. apt-mark unhold <package> ← remove the pin so you can install a different version
2. apt-get install -y <package>=<exact version>
3. apt-mark hold <package> ← re-pin it so future upgrades can't touch it
Why re-pin after installing? If you forget to re-hold, the next time someone runs apt upgrade the package gets bumped to whatever the latest version is. That's exactly the accident you were trying to prevent.
apt-mark Commands¶
apt-mark hold kubeadm # pin — exclude from upgrades
apt-mark unhold kubeadm # unpin — allow version change
apt-mark showhold # list all currently held packages
Verify a package is held:
If it returns kubeadm, it's pinned. If it returns nothing, it's not pinned.
Finding What Versions Are Available — apt-cache madison¶
What apt-cache madison does: Queries the local APT package cache and lists all available versions of a package from all configured repositories, in descending order (newest first).
Output:
kubeadm | 1.34.5-1.1 | https://pkgs.k8s.io/...
kubeadm | 1.34.4-1.1 | https://pkgs.k8s.io/...
kubeadm | 1.34.3-1.1 | https://pkgs.k8s.io/...
If you're on 1.34.3, the next version up is 1.34.4. That is the version you install. Not 1.34.5.
If apt-cache madison returns nothing or only shows your current version:
apt-get update refreshes the package index from the configured repositories. Without this, APT only knows about versions it already saw — it won't know about packages released since the last update. Always run apt-get update before checking versions.
Version Format — What Is -1.1?¶
When you see 1.34.4-1.1 in the apt output:
1.34.4= the Kubernetes version-1.1= the Debian/Ubuntu package revision (the packaging build number, not a Kubernetes thing)
When you install, you include the full string:
The quotes and exact string matter. apt-get install kubeadm=1.34.4 without the -1.1 suffix will fail or install the wrong thing.
Full Upgrade Command — With Every Flag Explained¶
apt-mark unhold kubeadm && \
apt-get update && \
apt-get install -y kubeadm='1.34.4-1.1' && \
apt-mark hold kubeadm
| Part | What it does |
|---|---|
apt-mark unhold kubeadm |
Remove the version pin so apt can install a different version |
&& |
Only proceed to the next command if the previous one succeeded. If unhold fails, nothing else runs. |
apt-get update |
Refresh the package index from repositories. Without this, apt might not know the new version exists |
apt-get install -y kubeadm='1.34.4-1.1' |
Install exactly this version. -y = auto-yes to all prompts (non-interactive, needed in scripts) |
apt-mark hold kubeadm |
Re-pin it so future apt upgrades don't touch it |
Why chain with && instead of ;?
- && = run next command only if previous succeeded (exit code 0)
- ; = run next command regardless of whether previous failed
If apt-get update fails (no network, repo down), you don't want to install a package with a stale index. && stops the chain immediately on failure.
apt-get vs apt¶
apt-get install -y kubeadm='1.34.4-1.1' # scripting — stable, predictable output
apt install kubeadm='1.34.4-1.1' # interactive use — same thing with a progress bar
In scripts and exam answers, use apt-get. It has stable, parseable output designed for scripting. apt is the human-friendly frontend — the output format can change between versions.
Verify the Install¶
Always run this after installing. Never skip it. If the install silently failed (package already at that version, or apt error that was swallowed), kubeadm upgrade apply with the old binary does nothing — and you won't know why. Verify first.