<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged etcd</title>
<link>https://coderlegion.com/tag/etcd</link>
<description>Powered by Question2Answer</description>
<item>
<title>Upgrading Our Raspberry Pi Kubernetes Cluster: From v1.29 to v1.34 &amp; ETCD Backup Guide</title>
<link>https://coderlegion.com/13289/upgrading-our-raspberry-pi-kubernetes-cluster-from-v1-29-to-v1-34-etcd-backup-guide</link>
<description>&lt;hr&gt;
&lt;p&gt;title: Upgrading Our Raspberry Pi Kubernetes Cluster: From v1.29 to v1.34 &amp;amp; ETCD Backup Guide&lt;br&gt;
published: true&lt;br&gt;
date: 2025-10-16 14:35:59 UTC&lt;br&gt;
tags: raspberrypi,kubernetes,etcd,kubernetescluster&lt;/p&gt;
&lt;h3 id=&quot;canonical-url-https-medium-com-mahinshanazeer-upgrading-our-raspberry-pi-kubernetes-cluster-from-v1-29-to-v1-34-etcd-backup-guide-97a2074237b4&quot;&gt;canonical_url: &lt;a rel=&quot;nofollow&quot; href=&quot;https://medium.com/@mahinshanazeer/upgrading-our-raspberry-pi-kubernetes-cluster-from-v1-29-to-v1-34-etcd-backup-guide-97a2074237b4&quot;&gt;https://medium.com/@mahinshanazeer/upgrading-our-raspberry-pi-kubernetes-cluster-from-v1-29-to-v1-34-etcd-backup-guide-97a2074237b4&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1024/1*D0P7sopIzTaubncyFnNPag.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Keeping your cluster up-to-date is crucial for security, stability, and access to new features. In this blog, we’ll take a closer look at our home lab Kubernetes cluster running on Raspberry Pi devices. The setup includes 1 master node and 3 worker nodes, and it has been running smoothly for over four months without any major issues.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/702/1*RISM21an6y-TUght4dRieg.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;k8s home lab configuration — nodes&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;master2 — master node/ control plane&lt;br&gt;
master1 — worker node 3&lt;br&gt;
worker 1 — worker node 1&lt;br&gt;
worker 2 — worker node 2&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1024/1*AJBUK-y3Yy_dK1vLvcOLlw.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;k8s home lab configuration — system components&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;As part of regular maintenance and to stay up-to-date with the latest features and security patches, we decided to upgrade the cluster from Kubernetes v1.29 to v1.34. Alongside the upgrade, we’ll also walk through the process of backing up the ETCD datastore, which is crucial for fault tolerance and disaster recovery.&lt;/p&gt;
&lt;p&gt;Here’s what we’ll cover:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;⬆️ Step-by-step guide to upgrading Kubernetes components.&lt;/li&gt;
&lt;li&gt;️ Safely backing up ETCD in the master node.&lt;/li&gt;
&lt;li&gt;✅ Post-upgrade verification.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;a-backing-up-etcd&quot;&gt;A. Backing Up ETCD&lt;/h4&gt;
&lt;p&gt;Before diving into the upgrade process, it’s essential to create a backup of ETCD, the key-value store that holds all cluster state data. This step is crucial because if anything goes wrong during the upgrade — whether it’s a misconfiguration or a failed component — we need a reliable way to restore the cluster to its current stable state.&lt;/p&gt;
&lt;p&gt;Think of the ETCD backup as your safety net. It ensures that even in the worst-case scenario, you won’t lose your cluster’s configuration, workloads, or networking setup.&lt;/p&gt;
&lt;p&gt;Run the following command to confirm the ETCD pod name running on your control plane:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;kubectl get pods -n kube-system | grep etcd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1024/1*kCOudifkDT-Bb0uCn8rJ2A.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;k8s configuration — ETCD setup&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Suppose your control plane (master node) runs ETCD as a static pod (which is the default in kubeadm-based clusters, including Raspberry Pi setups). In that case, you can run etcdctl directly on the master node host — because the ETCD data directory and certificates are mounted locally at &lt;em&gt;/etc/kubernetes/pki/etcd/&lt;/em&gt; and &lt;em&gt;/var/lib/etcd/.&lt;/em&gt; In that case, you can use the following command to take the backup:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo ETCDCTL_API=3 etcdctl snapshot save /var/lib/etcd/backup.db \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If ETCD runs as a container (inside the pod) or you don’t have the etcdctl binary available on the host, then you’ll need to exec into the pod to run the backup from inside the container.&lt;/p&gt;
&lt;p&gt;In my setup, where &lt;strong&gt;etcd&lt;/strong&gt; runs as a container, I need to access the pod directly to execute the backup. There is no etcdctl binary available on the host.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;kubectl exec -n kube-system &amp;lt;node-label&amp;gt;-- \
  etcdctl snapshot save /var/lib/etcd/backup.db \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key

#edit the &amp;lt;node-label&amp;gt; with etcd node
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1024/1*xlWBIPqp8McKoOjKxkbKjg.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;Creating backup&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Now, verify the snapshot using the following command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;kubectl exec -n kube-system &amp;lt;node-label&amp;gt;-- \
  etcdctl snapshot status /var/lib/etcd/backup.db -w table
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/870/1*9GsdIbKWKprGPs_Seoc2kA.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;In the above screenshot, you can seee a deprecation warning. ETCD v3.6+ is deprecated &lt;em&gt;etcdctl snapshot status&lt;/em&gt; and recommends using &lt;em&gt;etcdutl snapshot status&lt;/em&gt;. However, in my kubeadm static pod setup, the &lt;em&gt;etcdutl&lt;/em&gt; binary is not included in the ETCD container. Only &lt;em&gt;etcdctl&lt;/em&gt; exists inside the pod. The warning is simply a deprecation notice, not a failure. You can safely continue using it &lt;em&gt;etcdctl snapshot status&lt;/em&gt; — it works perfectly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In my setup, I came across a deprecation warning while using etcdctl. To verify, I checked the current version of etcd using the following command.&lt;/p&gt;
&lt;p&gt;Since my cluster is kubeadm-managed, even though etcd v3.6+ recommends using etcdutl for snapshot management, etcdctl inside the etcd pod still works perfectly for backup and restore. etcdutl is a newer utility introduced in etcd v3.6+ as a replacement for certain snapshot operations, but in my case, continuing with etcdctl is fully sufficient.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;kubectl exec -n kube-system etcd-master2 -- etcdctl version
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1024/1*YP_D_wTZ1iGmGXza0cm2OQ.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;etcd version checking&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In some scenarios, the etcd backup file may reside only inside the etcd pod and not in a host-accessible directory.&lt;/p&gt;
&lt;p&gt;This can happen if the etcd container is minimal and lacks tools like tar to move files around, or if the host does not have etcdctl installed to create the snapshot directly. In such cases, you can use specific commands to move the backup file to a host-accessible directory.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;kubectl cp kube-system/etcd-master2:/tmp/backup.tar.gz ./backup.tar.gz
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In my setup, I created the etcd snapshot directly on the host in a host-accessible directory (for example, /var/lib/etcd/backup.db). Since the backup is already on the host, it can be copied or archived without using kubectl cp.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo cp /var/lib/etcd/backup.db ~/backup.db
sudo chown $USER:$USER ~/backup.db
ls -l ~/backup.db
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/855/1*0_RkF8kgG0E7bHsZgk3ywA.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;backup.db file status&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Additionally, it’s a good practice to create a copy of the backup on a remote server. This ensures an extra layer of safety and helps protect against data loss in case of hardware failure or accidental deletion.&lt;/p&gt;
&lt;h4 id=&quot;b-upgrading-the-cluster&quot;&gt;B. Upgrading the cluster&lt;/h4&gt;
&lt;p&gt;Since we have backed up etcd, we can safely proceed with the kubeadm upgrade for our Raspberry Pi Kubernetes cluster. Let’s go through a step-by-step process to upgrade the cluster from v1.29 → v1.34.&lt;/p&gt;
&lt;p&gt;Kubernetes officially supports upgrading one minor version at a time, which means that to move from 1.29 to 1.34, you need to perform incremental upgrades:&lt;/p&gt;
&lt;p&gt;Step 1: v1.29 → v1.30 &lt;br&gt;
Step 2: v1.30 → v1.31&lt;br&gt;
Step 3: v1.31 → v1.32&lt;br&gt;
Step 4: v1.32 → v1.33&lt;br&gt;
Step 5: v1.33 → v1.34&lt;/p&gt;
&lt;p&gt;Please refer to the following URL for k8s official documentation on skew policy:&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://v1-30.docs.kubernetes.io/releases/version-skew-policy/&quot;&gt;Version Skew Policy&lt;/a&gt;&lt;/p&gt;
&lt;h5 id=&quot;step-1-pre-checks-for-upgrading-the-cluster&quot;&gt;Step 1: Pre-Checks for upgrading the cluster&lt;/h5&gt;
&lt;p&gt;Before upgrading the cluster, it’s essential to ensure that the cluster is healthy and stable. This helps prevent issues during the upgrade and ensures a smooth transition between versions.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;kubectl version
kubectl get nodes
kubectl get cs
kubectl get pods -n kube-system
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1024/1*87FwxUqQ2TSc9YgpXHZPXw.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;Current status of the cluster&lt;/em&gt;&lt;/p&gt;
&lt;h5 id=&quot;step-2-upgrade-kubeadm-on-the-master-node&quot;&gt;Step 2: Upgrade kubeadm on the Master Node&lt;/h5&gt;
&lt;p&gt;You can also refer to the following documentation for more details regarding kubeadm upgrade:&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://v1-30.docs.kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/&quot;&gt;Upgrading kubeadm clusters&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;To upgrade to v1.30, ensure that the directory /etc/apt/keyrings exists. If it doesn’t, create it before running the curl command (see the note below). Afterwards, update the package repository to target v1.30.&lt;/p&gt;
&lt;p&gt;Each Kubernetes minor release repository (v1.29, v1.30, v1.31, etc.) may use a different GPG key. Using the key from an older version, such as v1.29, can cause package verification failures when installing packages from the v1.30 repository.&lt;/p&gt;
&lt;p&gt;To prevent such errors, always use the GPG key and repository provided specifically for the minor version you are upgrading to.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# If the directory `/etc/apt/keyrings` does not exist, it should be created before the curl command, read the note below.
# sudo mkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

# This overwrites any existing configuration in /etc/apt/sources.list.d/kubernetes.list
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Before upgradingkubeadmEnsure your package lists are up to date. Then, install the required version by using the following commands&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo apt-mark unhold kubelet kubeadm kubectl &amp;amp;&amp;amp; \
sudo apt-get update
sudo apt-get install -y kubeadm=1.30.14-1.1 kubelet=1.30.14-1.1 kubectl=1.30.14-1.1
sudo apt-mark hold kubelet kubeadm kubectl
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you want to upgrade to a specific Kubernetes version, you can use the following command to list all available minor versions in the corresponding repository:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt-cache madison kubeadm
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/978/1*RDcuF8IS82lXJ05pf4RgwQ.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;available packages in the repo&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;For comprehensive guidance on upgrading your Kubernetes cluster to version &lt;strong&gt;v1.30&lt;/strong&gt; , refer to the official Kubernetes documentation:&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/&quot;&gt;Installing kubeadm&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This resource provides detailed, step-by-step instructions tailored for clusters managed with &lt;strong&gt;kubeadm&lt;/strong&gt; , ensuring a smooth and efficient upgrade process.&lt;/p&gt;
&lt;p&gt;Once the upgrade is complete, verify the &lt;strong&gt;kubeadm&lt;/strong&gt; version using the following command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;kubeadm version
kubectl version --client
kubelet --version
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1024/1*z4cxNAMceG76DxwAJF3s6g.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;current kubeadm version&lt;/em&gt;&lt;/p&gt;
&lt;h5 id=&quot;step-3-plan-the-upgrade&quot;&gt;Step 3: Plan the Upgrade&lt;/h5&gt;
&lt;p&gt;After upgrading kubeadm, it’s important to check the upgrade path and verify the versions of all cluster components. This ensures that all parts of your Kubernetes cluster are compatible and running the expected versions.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo kubeadm upgrade plan
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It will display:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;current cluster version&lt;/strong&gt; and control plane version.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;available target versions&lt;/strong&gt; you can upgrade to.&lt;/li&gt;
&lt;li&gt;The versions of &lt;strong&gt;kubelet&lt;/strong&gt; and &lt;strong&gt;kubectl&lt;/strong&gt; on your nodes.&lt;/li&gt;
&lt;li&gt;Any &lt;strong&gt;required steps or notes&lt;/strong&gt; for a smooth upgrade.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1024/1*15KMi7LmDU8VNoAp1yaaSw.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;kubeadm upgrade plan output — 1&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1024/1*iYYt88VaUFyo_7Se5QW1kQ.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;kubeadm upgrade plan output — 2&lt;/em&gt;&lt;/p&gt;
&lt;h5 id=&quot;step-4-upgrade-the-control-plane&quot;&gt;Step 4: Upgrade the Control Plane&lt;/h5&gt;
&lt;p&gt;Once the upgrade plan is reviewed and all changes are understood, you can proceed with upgrading the cluster. Use the kubeadm upgrade apply command, which is provided in the output of kubeadm upgrade plan.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo kubeadm upgrade apply v1.30.14
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The upgrade process may take some time, depending on the size and complexity of your cluster. Once it completes successfully, you should see a message similar to the following:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1024/1*uTURS7u-pxMBDoiHaUpdMg.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;upgraded to “v1.30.14”&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Now, verify the control plane using the following commands:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#rebooting the master node or restarting the kubelete is highly recommended
sudo systemctl daemon-reload
sudo systemctl restart kubelet
kubectl get nodes
kubectl get pods -n kube-system
&lt;/code&gt;&lt;/pre&gt;
&lt;h5 id=&quot;step-5-upgrade-worker-nodes&quot;&gt;Step 5: Upgrade Worker Nodes&lt;/h5&gt;
&lt;p&gt;Now repeat the same steps from ‘Step 2: Upgrade kubeadm on the Master Node’ again in master1, worker1 and worker2 nodes (worker nodes). Workers do not control the cluster state; running upgrade plan there doesn’t provide meaningful information. First drain the worker node from the control plane, so that all the resources will be taken out of the node&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh to controlplane (master2)
-------------------------------
#step 1:
kubectl drain &amp;lt;worker-node&amp;gt; --ignore-daemonsets --delete-emptydir-data

***
kubectl drain worker1 --ignore-daemonsets --delete-emptydir-data
***
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1024/1*K82WBCjXW1xi6br5ep5r3A.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;draining resources from worker node (master1)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Now you can repeat the steps we followed for control plane for upgrading the version:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh to master1 node
-------------------------------
#step 1:
sudo rm -rf /etc/apt/sources.list.d/kubernetes.list

#step 2:
# If the directory `/etc/apt/keyrings` does not exist, it should be created before the curl command, read the note below.
# sudo mkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
#step 3:
# This overwrites any existing configuration in /etc/apt/sources.list.d/kubernetes.list
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

#step 4:
sudo apt-mark unhold kubelet kubeadm kubectl &amp;amp;&amp;amp; \
sudo apt-get update
sudo apt-get install -y kubeadm=1.30.14-1.1 kubelet=1.30.14-1.1 kubectl=1.30.14-1.1
sudo apt-mark hold kubelet kubeadm kubectl

#step 5:
kubeadm version

#step 6:
#rebooting the master node or restarting the kubelete is highly recommended
sudo systemctl daemon-reload
sudo systemctl restart kubelet
kubectl get nodes
kubectl get pods -n kube-system

#step 7:
kubeadm upgrade node

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/1024/1*X1wudh5rErmUwuoFw4yLFg.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;upgrading worker node — host ‘master2’ is a worker node here. (master2 — master node/ control planemaster1 — worker node 3worker 1 — worker node 1worker 2 — worker node 2)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Also verify the nodes from control plane:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/852/1*BtfZU1oK2v7Mp4rqYZ7SzA.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;upgrade completed&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Now we can following commmand to make the node available for schedule;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;kubectl uncordon master1
#run this command in the control plane.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/671/1*9rBFG6wuuuSvW5donzFW1Q.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;Marking node as schedulable&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;kubectl uncordon command is used to &lt;strong&gt;mark a node as schedulable again&lt;/strong&gt; after it has been drained.&lt;/p&gt;
&lt;p&gt;Similarly we can do the upgrades in other 2 worker nodes, I will mention the commands below:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;worker1:&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh to controlplane (master2)
-------------------------------
#step 1:
kubectl drain &amp;lt;worker-node&amp;gt; --ignore-daemonsets --delete-emptydir-data

***
kubectl drain worker1 --ignore-daemonsets --delete-emptydir-data
***

ssh to worker1 node

#step 1:
sudo rm -rf /etc/apt/sources.list.d/kubernetes.list

#step 2:
# If the directory `/etc/apt/keyrings` does not exist, it should be created before the curl command, read the note below.
# sudo mkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
#step 3:
# This overwrites any existing configuration in /etc/apt/sources.list.d/kubernetes.list
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

#step 4:
sudo apt-mark unhold kubelet kubeadm kubectl &amp;amp;&amp;amp; \
sudo apt-get update
sudo apt-get install -y kubeadm=1.30.14-1.1 kubelet=1.30.14-1.1 kubectl=1.30.14-1.1
sudo apt-mark hold kubelet kubeadm kubectl

#step 5:
kubeadm version

#step 6:
#rebooting the master node or restarting the kubelete is highly recommended
sudo systemctl daemon-reload
sudo systemctl restart kubelet

#step 7:
sudo kubeadm upgrade node

ssh to controlplane (master2)
-------------------------------
#step 1:
kubectl uncordon worker1
kubectl get nodes
kubectl get pods -n kube-system
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;worker2:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh to controlplane (master2)
-------------------------------
#step 1:
kubectl drain &amp;lt;worker-node&amp;gt; --ignore-daemonsets --delete-emptydir-data

***
kubectl drain worker2 --ignore-daemonsets --delete-emptydir-data
***

ssh to worker2 node
-------------------------------
#step 1:
sudo rm -rf /etc/apt/sources.list.d/kubernetes.list

#step 2:
# If the directory `/etc/apt/keyrings` does not exist, it should be created before the curl command, read the note below.
# sudo mkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
#step 3:
# This overwrites any existing configuration in /etc/apt/sources.list.d/kubernetes.list
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

#step 4:
sudo apt-mark unhold kubelet kubeadm kubectl &amp;amp;&amp;amp; \
sudo apt-get update
sudo apt-get install -y kubeadm=1.30.14-1.1 kubelet=1.30.14-1.1 kubectl=1.30.14-1.1
sudo apt-mark hold kubelet kubeadm kubectl

#step 5:
kubeadm version

#step 6:
#rebooting the master node or restarting the kubelete is highly recommended
sudo systemctl daemon-reload
sudo systemctl restart kubelet
kubectl get nodes
kubectl get pods -n kube-system

#step 7:
sudo kubeadm upgrade node

ssh to controlplane (master2)
-------------------------------
#step 1:
kubectl uncordon worker2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All nodes have now been successfully upgraded to &lt;strong&gt;v1.30.14&lt;/strong&gt; , as shown in the following screenshot.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://cdn-images-1.medium.com/max/617/1*cX2D2v7kwsgAx5dpAu_CAA.png&quot; alt=&quot;&quot;&gt;&lt;br&gt;
&lt;em&gt;kubernetes version v1.30.14&lt;/em&gt;&lt;/p&gt;
&lt;h5 id=&quot;step-5-upgrading-to-1-34&quot;&gt;Step 5: Upgrading to 1.34&lt;/h5&gt;
&lt;p&gt;Following the same process, we’ll now proceed to upgrade the cluster from &lt;strong&gt;v1.30.14&lt;/strong&gt; to &lt;strong&gt;v1.31&lt;/strong&gt;. Then we will proceed with with&lt;/p&gt;
&lt;p&gt;Step 1: v1.29.15 → v1.30.14–1.1&lt;br&gt;
Step 2: v1.30.14–1.1 → v1.31.13–1.1&lt;br&gt;
Step 3: v1.31.13–1.1 → v1.32.9&lt;br&gt;
Step 4: v1.32.9 → v1.33.5&lt;br&gt;
Step 5: v1.33.5 → v1.34.1&lt;/p&gt;
&lt;p&gt;In control-plane (master2) use the following steps to upgrade to version 1.31:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh to controlplane (master2)

#step 1:
sudo rm -rf /etc/apt/sources.list.d/kubernetes.list

# If the directory `/etc/apt/keyrings` does not exist, it should be created before the curl command, read the note below.
# sudo mkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg

# This overwrites any existing configuration in /etc/apt/sources.list.d/kubernetes.list
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list

#step 2:
sudo apt update
apt-cache madison kubeadm

#step 3:
sudo apt-mark unhold kubelet kubeadm kubectl &amp;amp;&amp;amp; \
sudo apt-get update
sudo apt-get install -y kubeadm kubelet kubectl #will take the latest version
sudo apt-mark hold kubelet kubeadm kubectl

#step 4:
kubeadm version
kubectl version --client
kubelet --version

#step 5:
sudo kubeadm upgrade plan

#step 6:
sudo kubeadm upgrade apply &amp;lt;version&amp;gt;
#I used the following command
sudo kubeadm upgrade apply v1.31.13

#step 7:
#rebooting the master node or restarting the kubelete is highly recommended
sudo systemctl daemon-reload
sudo systemctl restart kubelet
kubectl get nodes
kubectl get pods -n kube-system
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now lets setup the worker nodes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh to controlplane (master2)
-------------------------------
#step 1:
kubectl drain &amp;lt;worker-node&amp;gt; --ignore-daemonsets --delete-emptydir-data

ssh to &amp;lt;worker-node&amp;gt; node
-------------------------------
#step 1:
sudo rm -rf /etc/apt/sources.list.d/kubernetes.list

#step 2:
# If the directory `/etc/apt/keyrings` does not exist, it should be created before the curl command, read the note below.
# sudo mkdir -p -m 755 /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-key
&lt;/code&gt;&lt;/pre&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/13289/upgrading-our-raspberry-pi-kubernetes-cluster-from-v1-29-to-v1-34-etcd-backup-guide</guid>
<pubDate>Sat, 21 Mar 2026 13:53:24 +0000</pubDate>
</item>
</channel>
</rss>