Complete step-by-step upgrade procedure with commands
Critical first step - backup cluster state
export ETCDCTL_API=3 export ETCDCTL_ENDPOINTS=https://127.0.0.1:2379 export ETCDCTL_CACERT=/etc/kubernetes/pki/etcd/ca.crt export ETCDCTL_CERT=/etc/kubernetes/pki/etcd/server.crt export ETCDCTL_KEY=/etc/kubernetes/pki/etcd/server.key
sudo etcdctl snapshot save /backup/etcd-snapshot-$(date +%Y%m%d-%H%M%S).db
sudo etcdctl snapshot status /backup/etcd-snapshot-*.db
kubectl version --short kubectl get nodes -o wide kubectl get pods -A kubectl get --raw /metrics | grep apiserver_requested_deprecated_apis
Upgrade control plane components first
sudo apt-mark unhold kubeadm sudo apt-get update sudo apt-get install -y kubeadm=1.32.0-00 sudo apt-mark hold kubeadm kubeadm version
sudo yum install -y kubeadm-1.32.0-0 --disableexcludes=kubernetes kubeadm version
kubectl drain <control-plane-node> --ignore-daemonsets --delete-emptydir-data
sudo kubeadm upgrade plan
sudo kubeadm upgrade apply v1.32.0
sudo kubeadm upgrade node
sudo apt-mark unhold kubelet kubectl sudo apt-get update sudo apt-get install -y kubelet=1.32.0-00 kubectl=1.32.0-00 sudo apt-mark hold kubelet kubectl
sudo yum install -y kubelet-1.32.0-0 kubectl-1.32.0-0 --disableexcludes=kubernetes
sudo systemctl daemon-reload sudo systemctl restart kubelet kubectl uncordon <control-plane-node> kubectl get nodes
Upgrade each worker node sequentially
kubectl cordon <worker-node-name> kubectl drain <worker-node-name> --ignore-daemonsets --delete-emptydir-data
sudo apt-mark unhold kubeadm sudo apt-get update sudo apt-get install -y kubeadm=1.32.0-00 sudo apt-mark hold kubeadm
sudo yum install -y kubeadm-1.32.0-0 --disableexcludes=kubernetes
sudo kubeadm upgrade node
sudo apt-mark unhold kubelet kubectl sudo apt-get update sudo apt-get install -y kubelet=1.32.0-00 kubectl=1.32.0-00 sudo apt-mark hold kubelet kubectl
sudo yum install -y kubelet-1.32.0-0 kubectl-1.32.0-0 --disableexcludes=kubernetes
sudo systemctl daemon-reload sudo systemctl restart kubelet
kubectl uncordon <worker-node-name> kubectl get nodes -o wide
Verify cluster health and functionality
kubectl version --short kubectl get nodes -o wide
kubectl get pods -n kube-system kubectl get pods -A
kubectl run nginx-test --image=nginx:latest --port=80 kubectl expose pod nginx-test --port=80 --type=NodePort kubectl get svc nginx-test # Test access, then cleanup: kubectl delete pod nginx-test kubectl delete svc nginx-test
kubectl get events -A --sort-by='.lastTimestamp' | tail -20 kubectl get --raw /metrics | grep apiserver_requested_deprecated_apis