Upgrading a Kubernetes v1.28 Cluster using kubeadm
Tags: kubernetes, cloudnative, opensource, beginners
Published: 2023-08-28 13:37:26

> In this article, we will look how we can upgrade a three node Kubernetes v1.28 cluster using kubeadm

## Prerequisites

* We need a working Kubernetes cluster created using kubeadm
    
* If you haven’t created the cluster, please check my previous article below
This will guide you to create a Kubernetes v1.28.0 cluster
[Building a Kubernetes v1.28 Cluster using kubeadm](https://iamunnip.hashnode.dev/building-a-kubernetes-v128-cluster-using-kubeadm)
    

## Upgrade Process

### Control Plane

Verify the version of our cluster

```bash
# control-plane

kubectl get nodes
NAME            STATUS   ROLES           AGE    VERSION
control-plane   Ready    control-plane   3m6s   v1.28.0
node-1          Ready    <none>          43s    v1.28.0
node-2          Ready    <none>          37s    v1.28.0
```

Update the package index and find the latest kubeadm patch available in the repository

```bash
# control-plane

sudo apt update

sudo apt-cache madison kubeadm
```

Unhold the kubeadm package for upgrading

```bash
# control-plane

sudo apt-mark unhold kubeadm
```

Upgrade the kubeadm package to version v1.28.1 and hold the package from automatic upgrading

```bash
# control-plane

sudo apt install -y kubeadm=1.28.1-1.1

sudo apt-mark hold kubeadm
```

Check the upgraded kubeadm version and verify the upgrade plan

```bash
# control-plane

sudo kubeadm version

sudo kubeadm upgrade plan
```

Once our plan is verified, we can upgrade the control-plane by executing the below command

```bash
# control-plane

sudo kubeadm upgrade apply v1.28.1
```

Prepare the control-plane for maintenance by marking it unschedulable and evicting the workloads

```bash
# control-plane

kubectl drain control-plane --ignore-daemonsets
```

Unhold the kubelet and kubectl packages for an upgrade

```bash
# control-plane

sudo apt-mark unhold kubelet kubectl
```

Upgrade kubelet and kubectl packages to version v1.28.1 and hold the packages from automatic upgrading

```bash
# control-plane

sudo apt install kubelet=1.28.1-1.1 kubectl=1.28.1-1.1

sudo apt-mark hold kubelet kubectl
```

Restart the kubelet service on control-plane

```bash
# control-plane

sudo systemctl daemon-reload

sudo systemctl restart kubelet
```

Uncordon the control-plane for marking it as schedulable

```bash
# control-plane

kubectl uncordon control-plane
```

Verify the nodes, now we can see control-plane is upgraded to v1.28.1

```bash
# control-plane

kubectl get nodes
NAME            STATUS   ROLES           AGE     VERSION
control-plane   Ready    control-plane   9m17s   v1.28.1
node-1          Ready    <none>          6m54s   v1.28.0
node-2          Ready    <none>          6m48s   v1.28.0
```

### Nodes

Update the package index on node-1 and node-2 and unhold the kubeadm package for upgrading

```bash
# node-1 and node-2

sudo apt update

sudo apt-mark unhold kubeadm
```

Upgrade the kubeadm package to version v1.28.1 on node-1 and node-2 and hold the package from automatic upgrading

```bash
# node-1 and node-2

sudo apt install kubeadm=1.28.1-1.1

sudo apt-mark hold kubeadm
```

Upgrade the cluster configuration on node-1 and node-2 using the below command

```bash
# node-1 and node-2

sudo kubeadm upgrade node
```

Prepare node-1 and node-2 for maintenance by marking them as unschedulable and evicting the workloads  
Execute the below drain command on control-plane

```bash
# control-plane

kubectl drain node-1 --ignore-daemonsets --force

kubectl drain node-2 --ignore-daemonsets --force
```

Unhold the kubelet and kubectl packages for an upgrade

```bash
# node-1 and node-2

sudo apt-mark unhold kubelet kubectl
```

Upgrade kubelet and kubectl packages to version v1.28.1 and hold the packages from automatic upgrading

```bash
# node-1 and node-2

sudo apt install kubelet=1.28.1-1.1 kubectl=1.28.1-1.1

sudo apt-mark hold kubelet kubectl
```

Restart the kubelet service on node-1 and node-2

```bash
# node-1 and node-2

sudo systemctl daemon-reload

sudo systemctl restart kubelet
```

Uncordon node-1 and node-2 for marking it as schedulable  
Execute the below uncordon command on the control-plane

```bash
# control-plane

kubectl uncordon node-1

kubectl uncordon node-2
```

Now our cluster is fully upgraded to v1.28.1  
Verify the same by executing the below command on the control-plane

```bash
# control-plane

kubectl get nodes
NAME            STATUS   ROLES           AGE   VERSION
control-plane   Ready    control-plane   14m   v1.28.1
node-1          Ready    <none>          11m   v1.28.1
node-2          Ready    <none>          11m   v1.28.1
```

## Reference

[https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/](https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/)