Script to update a kubernetes cluster to the next patch or minor version.
#!/bin/bash
# if no parameter, show versions and syntax
if [ -z $1 ]; then
# show available versions
yum list --showduplicates kubeadm --disableexcludes=kubernetes
# show syntax
echo ""
echo "Syntax:"
echo "$0 <version>, e.g. $0 1.26.x-0"
exit 1
fi
# remember version
export TARGET_VERSION=$1
# configure kubectl to use admin config
export KUBECONFIG=/etc/kubernetes/admin.conf
# track first control plane node
export IS_FIRST=1
# loop through control plane nodes
#kubectl get nodes --no-headers | xargs -n 5 echo
NODES=`kubectl get nodes --no-headers | awk '{print $1}'`
for NODE in $NODES; do
# parse kubectl node output into parameters
NODE_HOSTNAME=`kubectl get node $NODE --no-headers | xargs -n 5 bash -c 'echo $0'`
NODE_TYPE=`kubectl get node $NODE --no-headers | xargs -n 5 bash -c 'echo $2'`
NODE_VERSION=`kubectl get node $NODE --no-headers | xargs -n 5 bash -c 'echo $4'`
# only work on control plane nodes in this loop
if [ $NODE_TYPE != "control-plane" ]; then
#echo ""
#echo "skipping worker node"
continue
fi
echo ""
echo "***"
echo "* Next: $NODE_HOSTNAME"
# upgrade kubeadm
echo "upgrade to: $TARGET_VERSION"
ssh root@$NODE_HOSTNAME yum install -y kubeadm-$TARGET_VERSION --disableexcludes=kubernetes
# verify the download works and has the expected version
#ssh root@$NODE_HOSTNAME kubeadm version
# verify the upgrade plan
#ssh root@$NODE_HOSTNAME kubeadm upgrade plan
# perform the update
if [ $IS_FIRST == "0" ]; then
ssh root@$NODE_HOSTNAME kubeadm upgrade node
else
# if this is the first control plane node its command is a little different
ssh root@$NODE_HOSTNAME kubeadm upgrade apply --yes v$TARGET_VERSION
# adjust tracking now that we've completed the first control plane node
export IS_FIRST=0
fi
# drain node & prepare for updating
kubectl drain $NODE_HOSTNAME --delete-emptydir-data --ignore-daemonsets
# update kubelet & kubectl
ssh root@$NODE_HOSTNAME yum install -y kubelet-$TARGET_VERSION kubectl-$TARGET_VERSION --disableexcludes=kubernetes
# restart kubelet
ssh root@$NODE_HOSTNAME systemctl daemon-reload
ssh root@$NODE_HOSTNAME systemctl restart kubelet
# uncordon the node
kubectl uncordon $NODE_HOSTNAME
done
# loop through worker nodes
NODES=`kubectl get nodes --no-headers | awk '{print $1}'`
for NODE in $NODES; do
# parse kubectl node output into parameters
NODE_HOSTNAME=`kubectl get node $NODE --no-headers | xargs -n 5 bash -c 'echo $0'`
NODE_TYPE=`kubectl get node $NODE --no-headers | xargs -n 5 bash -c 'echo $2'`
NODE_VERSION=`kubectl get node $NODE --no-headers | xargs -n 5 bash -c 'echo $4'`
# only work on control plane nodes in this loop
if [ $NODE_TYPE == "control-plane" ]; then
#echo ""
#echo "skipping control plane node"
continue
fi
echo ""
echo "***"
echo "* Next: $NODE_HOSTNAME"
# upgrade kubeadm
echo "upgrade to: $TARGET_VERSION"
ssh root@$NODE_HOSTNAME yum install -y kubeadm-$TARGET_VERSION --disableexcludes=kubernetes
# verify the download works and has the expected version
#ssh root@$NODE_HOSTNAME kubeadm version
# verify the upgrade plan
#ssh root@$NODE_HOSTNAME kubeadm upgrade plan
# perform the update
if [ $IS_FIRST == "0" ]; then
ssh root@$NODE_HOSTNAME kubeadm upgrade node
fi
# drain node & prepare for updating
kubectl drain $NODE_HOSTNAME --delete-emptydir-data --ignore-daemonsets
# update kubelet & kubectl
ssh root@$NODE_HOSTNAME yum install -y kubelet-$TARGET_VERSION kubectl-$TARGET_VERSION --disableexcludes=kubernetes
# restart kubelet
ssh root@$NODE_HOSTNAME systemctl daemon-reload
ssh root@$NODE_HOSTNAME systemctl restart kubelet
# uncordon the node
kubectl uncordon $NODE_HOSTNAME
done