k8s不支持跨多个版本升级!因此要1.18-1.19-1.20-1.21-1.22

升级难点

生产集群的升级,不能影响业务容器的运行,k8s组件较多,升级过程中,任何一个组件出现问题,都可能影响到业务,对于核心业务,如果批量重启,可能造成灾难,因此, 集群的升级需要,业务容器无感知,基于社区的升级方案主要有几个问题:

  • 版本的升级,不能跨大版本,只能从小版本逐步升级,升级繁琐
  • 升级过程中,出现问题,不能回滚
  • 升级会造成容器重建,影响业务的运行

难点分析

跨版本升级其中一个最大的问题是kubelet会重建业务容器,我们源码分析,为什么升级kubelet,会造成容器重建

Before you begin

  • Make sure you read the release notes carefully.
  • The cluster should use a static control plane and etcd pods or external etcd.
  • Make sure to back up any important components, such as app-level state stored in a database. kubeadm upgrade does not touch your workloads, only components internal to Kubernetes, but backups are always a best practice.
  • Swap must be disabled
  • 先查看 /etc/kubernetes/manifests/kube-apiserver.yaml,在里面找到 etcd 的地址和 apiserver 使用 etcd 的证书:
    • 外部的ectd要用 external 指定etcd地址: kubectl -n kube-system edit cm kubeadm-config
      •  etcd:
            external:
              endpoints: # 这里填写上面获取的 etcd 的地址
              - https://10.250.8.78:2379
              - https://10.250.8.79:2379
              - https://10.250.8.80:2379
              caFile: /etc/kubernetes/etcd-pki/ca.pem
              certFile: /etc/kubernetes/etcd-pki/client.pem
              keyFile: /etc/kubernetes/etcd-pki/client-key.pem
        ..
        默认的有可能是
         etcd:
            local:  #指内部etcd
                datadir.......

Additional information

  • Draining nodes before kubelet MINOR version upgrades is required. In the case of control plane nodes, they could be running CoreDNS Pods or other critical workloads.
  • All containers are restarted after upgrade, because the container spec hash value is changed

update apt 

# apt-get update && apt-get install -y apt-transport-https
# curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | apt-key add - 
# echo "deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main" >> /etc/apt/sources.list.d/kubernetes.list
# apt-get update

Determine which version to upgrade to

apt-cache madison kubeadm
# find the latest every version in the list
# it should look like 1.22.x-00, where x is the latest patch

升级控制平面节点

控制面节点上的升级过程应该每次处理一个节点。 首先选择一个要先行升级的控制面节点。该节点上必须拥有 /etc/kubernetes/admin.conf 文件。

执行 "kubeadm upgrade"

升级第一个控制面节点

  • 升级 kubeadm:
2、升级kubeadm
# apt-mark unhold kubeadm && apt-get update && apt-get install -y kubeadm=1.19.14-00 && apt-mark hold kubeadm
3、核实升级plan
# kubeadm upgrade plan
说明:
kubeadm upgrade 也会自动对 kubeadm 在节点上所管理的证书执行续约操作。 如果需要略过证书续约操作,可以使用标志 --certificate-renewal=false。
# kubeadm upgrade apply/node v1.19.14  --certificate-renewal=false
一旦该命令结束,你应该会看到:

[upgrade/successful] SUCCESS! Your cluster was upgraded to "v1.22.x". Enjoy!

[upgrade/kubelet] Now that your control plane is upgraded, please proceed with upgrading your kubelets if you haven't already done so.
手动升级你的 CNI 驱动插件。

你的容器网络接口(CNI)驱动应该提供了程序自身的升级说明。 参阅插件页面查找你的 CNI 驱动, 并查看是否需要其他升级步骤。

如果 CNI 驱动作为 DaemonSet 运行,则在其他控制平面节点上不需要此步骤。
对于其它控制面节点

与第一个控制面节点相同,但是使用:

sudo kubeadm upgrade node
而不是:

sudo kubeadm upgrade apply
此外,不需要执行 kubeadm upgrade plan 和更新 CNI 驱动插件的操作。
4、drain 控制节点
# kubectl drain master --ignore-daemonsets
5、升级kubelet 和 kubectl
# apt-mark unhold kubelet kubectl && apt-get update && apt-get install -y kubelet=1.19.14-00 kubectl=1.19.14-00 && apt-mark hold kubelet kubectl
6、升级后重启kubelet 节点
# systemctl daemon-reload
# systemctl restart kubelet
7、Uncordon 控制面板节点
# kubectl uncordon kmaster
8、查看节点状态
# kubectl get nodes 发现节点为Ready状态

 Upgrade worker nodes

1、升级kubeadm
# apt-mark unhold kubeadm && apt-get update && apt-get install -y kubeadm=1.19.14-00 && apt-mark hold kubeadm
2、检查kubeadm
# kubeadm version
3、更新本地kubelet 配置
# kubeadm upgrade node
4、drain node01
# kubectl drain knode01 --ignore-daemonsets
5、升级kubelet 和kubectl
# apt-mark unhold kubelet kubectl && apt-get update && apt-get install -y kubelet=1.19.14-00 kubectl=1.19.14-00 && apt-mark hold kubelet kubectl
6、重启kubelet 节点
# systemctl daemon-reload && systemctl restart kubelet
# systemctl restart kubelet
7、Uncordon worker节点
# kubectl uncordon node01
8、查看节点状态
# kubectl get node

从故障状态恢复

如果 kubeadm upgrade 失败并且没有回滚,例如由于执行期间节点意外关闭, 你可以再次运行 kubeadm upgrade。 此命令是幂等的,并最终确保实际状态是你声明的期望状态。 要从故障状态恢复,你还可以运行 kubeadm upgrade --force 而无需更改集群正在运行的版本。

在升级期间,kubeadm 向 /etc/kubernetes/tmp 目录下的如下备份文件夹写入数据:

  • kubeadm-backup-etcd-<date>-<time>
  • kubeadm-backup-manifests-<date>-<time>

kubeadm-backup-etcd 包含当前控制面节点本地 etcd 成员数据的备份。 如果 etcd 升级失败并且自动回滚也无法修复,则可以将此文件夹中的内容复制到 /var/lib/etcd 进行手工修复。如果使用的是外部的 etcd,则此备份文件夹为空。

kubeadm-backup-manifests 包含当前控制面节点的静态 Pod 清单文件的备份版本。 如果升级失败并且无法自动回滚,则此文件夹中的内容可以复制到 /etc/kubernetes/manifests 目录实现手工恢复。 如果由于某些原因,在升级前后某个组件的清单未发生变化,则 kubeadm 也不会为之 生成备份版本。

验证集群的状态
kubectl get nodes

重新配置 用户的配置文件
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

验证集群证书
kubeadm alpha certs check-expiration

参考:Upgrading kubeadm clusters | Kubernetes

https://kubernetes.io/zh/docs/setup/release/version-skew-policy/Kubernetes 版本及版本偏差支持策略 | Kubernetes

Logo

开源、云原生的融合云平台

更多推荐