Upgrading my Kubernetes cluster
Part of the responsibility of being a DevOps engineer comes with keeping software, other dependencies, and platforms/systems up-to-date. One of these is Kubernetes. Staying up-to-date with the latest version of Kubernetes is very important. In addition to bug fixes and new features, there is also the occasional security fix/update. Security is crucial in a platform as large as Kubernetes.
Kubernetes versions change very often (about every 4 months), so it’s important to keep your cluster up-to-date. Before getting started, you want to read, or at least skim the release notes for each version since your current version. I know it’s kind of a hassle, but it’s important to know what’s being updated. The following are some things you’ll find in updates:
- Security fixes/updates
- Bug fixes
- New features
- Breaking changes or other upgrade notes that you must be aware of prior to upgrading
Upgrade process (control plane node)
For my cluster, I used the instructions from this link (but the current documentation can be found here. I basically followed these instructions. But I will lay out all the steps I made in this post.
You can see what version your cluster is currently running by executing the command kubectl get nodes
.
My upgrade process is as follows:
- Upgrade current MINOR version: 1.30.2 –> 1.30.10
- Upgrade from 1.30.10 –> 1.31.6
Since my CNI addon has not been tested with version 1.32.x of Kubernetes, we’ll stop here and stay on 1.31.x for now.
Update the package repository
First, we’ve got to download and install the newest public signing key for the Kubernetes package repository1.
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.32/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
Find which version of package to upgrade to
# Find the latest 1.30 version in the list.
# It should look like 1.30.x-*, where x is the latest patch.
sudo apt update
sudo apt-cache madison kubeadm
Upgrade control plane node
Upgrade kubeadm:
sudo apt-mark unhold kubeadm && \ sudo apt-get update && sudo apt-get install -y kubeadm='1.30.10-1.1' && \ sudo apt-mark hold kubeadm
Verify the expected version was installed:
kubeadm version
Verify the upgrade plan:
sudo kubeadm upgrade plan
Choose the version to upgrade to and run the upgrade:
sudo kubeadm upgrade apply v1.30.10
Manually upgrade my CNI provider plugin.
I’m using Canal (Calico for policy and Flannel for networking). I will therefore follow their instructions for upgrading Canal2.
- Fetch the K8s manifest:
curl https://raw.githubusercontent.com/projectcalico/calico/v3.29.2/manifests/canal.yaml -o upgrade.yaml
- Initiate a rolling update:
kubectl apply --server-side --force-conflicts -f upgrade.yaml
- We can watch as this update occurs.
watch kubectl get pods -n kube-system
- Fetch the K8s manifest:
Drain the node
kubectl drain k8s-master --ignore-daemonsets
Upgrade kubelet and kubectl
Upgrade the kubelet and kubectl:
sudo apt-mark unhold kubelet kubectl && \ sudo apt-get update && sudo apt-get install -y kubelet='1.30.10-1.1' kubectl='1.30.10-1.1' && \ sudo apt-mark hold kubelet kubectl
Restart the kubelet:
sudo systemctl daemon-reload sudo systemctl restart kubelet
Uncordon the node
Bring the node back online by marking it schedulable:
kubectl uncordon k8s-master
Upgrade process (worker nodes)
We’ll essentially repeat the same steps, but for the worker nodes this time.
Update the package repository
First, we’ve got to download and install the newest public signing key for the Kubernetes package repository.
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.32/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
Upgrade worker nodes
Upgrade kubeadm:
sudo apt-mark unhold kubeadm && \ sudo apt-get update && sudo apt-get install -y kubeadm='1.30.10-1.1' && \ sudo apt-mark hold kubeadm
Upgrade the node by calling “kubeadm upgrade”:
sudo kubeadm upgrade node
Drain the node
# execute this command on a control plane node
kubectl drain k8s-node1 --ignore-daemonsets
Upgrade kubelet and kubectl
Upgrade the kubelet and kubectl:
sudo apt-mark unhold kubelet kubectl && \ sudo apt-get update && sudo apt-get install -y kubelet='1.30.10-1.1' kubectl='1.30.10-1.1' && \ sudo apt-mark hold kubelet kubectl
Restart the kubelet:
sudo systemctl daemon-reload sudo systemctl restart kubelet
Uncordon the node
Bring the node back online by marking it schedulable:
# execute this command on a control plane node
kubectl uncordon k8s-node1
Next steps
We’ll repeat this process for the remaining node(s). In my case, k8s-node2
.
Next is to upgrade from version 1.30.10 to version 1.31.6. We’ll follow the same steps as we previously did, but first we’ll run this extra step on each node.
Update the package repository
We’ve got to add the apt repository so the packages can be upgraded. Kubernetes has individual repositories for each minor release of Kubernetes, rather than a single repository for all versions1. This needs to be run on each node, both the control plane and the two worker nodes.
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' | sudo tee -a /etc/apt/sources.list.d/kubernetes.list