9.2 KiB
Upgrading clusters
-
It's recommended to run consistent versions across a cluster
(mostly to have feature parity and latest security updates)
-
It's not mandatory
(otherwise, cluster upgrades would be a nightmare!)
-
Components can be upgraded one at a time without problems
Checking what we're running
- It's easy to check the version for the API server
.lab[
-
Log into node
oldversion1 -
Check the version of kubectl and of the API server:
kubectl version
]
-
In a HA setup with multiple API servers, they can have different versions
-
Running the command above multiple times can return different values
Node versions
- It's also easy to check the version of kubelet
.lab[
- Check node versions (includes kubelet, kernel, container engine):
kubectl get nodes -o wide
]
-
Different nodes can run different kubelet versions
-
Different nodes can run different kernel versions
-
Different nodes can run different container engines
Control plane versions
- If the control plane is self-hosted (running in pods), we can check it
.lab[
- Show image versions for all pods in
kube-systemnamespace:kubectl --namespace=kube-system get pods -o json \ | jq -r ' .items[] | [.spec.nodeName, .metadata.name] + (.spec.containers[].image | split(":")) | @tsv ' \ | column -t
]
What version are we running anyway?
-
When I say, "I'm running Kubernetes 1.18", is that the version of:
-
kubectl
-
API server
-
kubelet
-
controller manager
-
something else?
-
Other versions that are important
-
etcd
-
kube-dns or CoreDNS
-
CNI plugin(s)
-
Network controller, network policy controller
-
Container engine
-
Linux kernel
General guidelines
-
To update a component, use whatever was used to install it
-
If it's a distro package, update that distro package
-
If it's a container or pod, update that container or pod
-
If you used configuration management, update with that
Know where your binaries come from
-
Sometimes, we need to upgrade quickly
(when a vulnerability is announced and patched)
-
If we are using an installer, we should:
-
make sure it's using upstream packages
-
or make sure that whatever packages it uses are current
-
make sure we can tell it to pin specific component versions
-
Important questions
-
Should we upgrade the control plane before or after the kubelets?
-
Within the control plane, should we upgrade the API server first or last?
-
How often should we upgrade?
-
How long are versions maintained?
-
All the answers are in the documentation about version skew policy!
-
Let's review the key elements together ...
Kubernetes uses semantic versioning
-
Kubernetes versions look like MAJOR.MINOR.PATCH; e.g. in 1.18.20:
- MAJOR = 1
- MINOR = 18
- PATCH = 20
-
It's always possible to mix and match different PATCH releases
(e.g. 1.18.20 and 1.18.15 are compatible)
-
It is recommended to run the latest PATCH release
(but it's mandatory only when there is a security advisory)
Version skew
-
API server must be more recent than its clients (kubelet and control plane)
-
... Which means it must always be upgraded first
-
All components support a difference of one¹ MINOR version
-
This allows live upgrades (since we can mix e.g. 1.18 and 1.19)
-
It also means that going from 1.18 to 1.20 requires going through 1.19
.footnote[¹Except kubelet, which can be up to two MINOR behind API server, and kubectl, which can be one MINOR ahead or behind API server.]
Release cycle
-
There is a new PATCH relese whenever necessary
(every few weeks, or "ASAP" when there is a security vulnerability)
-
There is a new MINOR release every 3 months (approximately)
-
At any given time, three MINOR releases are maintained
-
... Which means that MINOR releases are maintained approximately 9 months
-
We should expect to upgrade at least every 3 months (on average)
In practice
-
We are going to update a few cluster components
-
We will change the kubelet version on one node
-
We will change the version of the API server
-
We will work with cluster
oldversion(nodesoldversion1,oldversion2,oldversion3)
Updating the API server
-
This cluster has been deployed with kubeadm
-
The control plane runs in static pods
-
These pods are started automatically by kubelet
(even when kubelet can't contact the API server)
-
They are defined in YAML files in
/etc/kubernetes/manifests(this path is set by a kubelet command-line flag)
-
kubelet automatically updates the pods when the files are changed
Changing the API server version
- We will edit the YAML file to use a different image version
.lab[
-
Log into node
oldversion1 -
Check API server version:
kubectl version -
Edit the API server pod manifest:
sudo vim /etc/kubernetes/manifests/kube-apiserver.yaml -
Look for the
image:line, and update it to e.g.v1.19.0
]
Checking what we've done
- The API server will be briefly unavailable while kubelet restarts it
.lab[
- Check the API server version:
kubectl version
]
Was that a good idea?
--
No!
--
-
Remember the guideline we gave earlier:
To update a component, use whatever was used to install it.
-
This control plane was deployed with kubeadm
-
We should use kubeadm to upgrade it!
Updating the whole control plane
-
Let's make it right, and use kubeadm to upgrade the entire control plane
(note: this is possible only because the cluster was installed with kubeadm)
.lab[
- Check what will be upgraded:
sudo kubeadm upgrade plan
]
Note 1: kubeadm thinks that our cluster is running 1.19.0.
It is confused by our manual upgrade of the API server!
Note 2: kubeadm itself is still version 1.18.20..
It doesn't know how to upgrade do 1.19.X.
Upgrading kubeadm
- First things first: we need to upgrade kubeadm
.lab[
-
Upgrade kubeadm:
sudo apt install kubeadm -
Check what kubeadm tells us:
sudo kubeadm upgrade plan
]
Problem: kubeadm doesn't know know how to handle upgrades from version 1.18.
This is because we installed version 1.22 (or even later).
We need to install kubeadm version 1.19.X.
Downgrading kubeadm
- We need to go back to version 1.19.X.
.lab[
-
View available versions for package
kubeadm:apt show kubeadm -a | grep ^Version | grep 1.19 -
Downgrade kubeadm:
sudo apt install kubeadm=1.19.8-00 -
Check what kubeadm tells us:
sudo kubeadm upgrade plan
]
kubeadm should now agree to upgrade to 1.19.8.
Upgrading the cluster with kubeadm
-
Ideally, we should revert our
image:change(so that kubeadm executes the right migration steps)
-
Or we can try the upgrade anyway
.lab[
- Perform the upgrade:
sudo kubeadm upgrade apply v1.19.8
]
Updating kubelet
-
These nodes have been installed using the official Kubernetes packages
-
We can therefore use
aptorapt-get
.lab[
-
Log into node
oldversion3 -
View available versions for package
kubelet:apt show kubelet -a | grep ^Version -
Upgrade kubelet:
sudo apt install kubelet=1.19.8-00
]
Checking what we've done
.lab[
-
Log into node
oldversion1 -
Check node versions:
kubectl get nodes -o wide -
Create a deployment and scale it to make sure that the node still works
]
Was that a good idea?
--
Almost!
--
-
Yes, kubelet was installed with distribution packages
-
However, kubeadm took care of configuring kubelet
(when doing
kubeadm join ...) -
We were supposed to run a special command before upgrading kubelet!
-
That command should be executed on each node
-
It will download the kubelet configuration generated by kubeadm
Upgrading kubelet the right way
-
We need to upgrade kubeadm, upgrade kubelet config, then upgrade kubelet
(after upgrading the control plane)
.lab[
- Download the configuration on each node, and upgrade kubelet:
for N in 1 2 3; do ssh oldversion$N " sudo apt install kubeadm=1.19.8-00 && sudo kubeadm upgrade node && sudo apt install kubelet=1.19.8-00" done
]
Checking what we've done
- All our nodes should now be updated to version 1.19.8
.lab[
- Check nodes versions:
kubectl get nodes -o wide
]
class: extra-details
Skipping versions
-
This example worked because we went from 1.18 to 1.19
-
If you are upgrading from e.g. 1.16, you will have to go through 1.17 first
-
This means upgrading kubeadm to 1.17.X, then using it to upgrade the cluster
-
Then upgrading kubeadm to 1.18.X, etc.
-
Make sure to read the release notes before upgrading!
???
:EN:- Best practices for cluster upgrades :EN:- Example: upgrading a kubeadm cluster
:FR:- Bonnes pratiques pour la mise à jour des clusters :FR:- Exemple : mettre à jour un cluster kubeadm