2026年11月12日

2026年11月12日

Kubernetes 集群升级步骤:升级前检查、kubeadm 升级、节点轮换与托管服务

本文是日语原文的本地化版本。 阅读日语原文

Kubernetes 集群要按次要版本逐个升级,顺序是控制平面、附加组件、节点。步骤本身不长,但导致升级卡住的原因大多是事前检查不足,典型的有:使用了已被移除 API 的清单、无法腾空的节点上的 Pod、忘记做的 etcd 备份。本文介绍升级前要检查的事项、用 kubeadm 搭建的集群的升级步骤、逐台替换节点的方法,以及 EKS 等托管服务的流程。

Kubernetes 大致每年发布 3 个次要版本,每个版本的支持期约为 14 个月(截至 2026 年 10 月)。如果放置一年左右,就会接近支持到期,所以现实的做法是把它当作定期工作来计划。

升级前要检查的事项

1. 目标版本与升级顺序

控制平面不能跳过次要版本升级。想从 1.31 升到 1.33,就必须经过 1.32。补丁版本(例如 1.32.3 到 1.32.8)可以跳过。

同时,还要确认各组件之间的版本差(版本偏差,version skew)的规定。

  • kubelet 不能比 kube-apiserver 新。比 kube-apiserver 旧的一侧,允许在一定范围内存在差异(按目前的策略最多 3 个次要版本)。
  • kubectl 与 kube-apiserver 的差距要在前后 1 个次要版本以内。

正因为有这条规定,才形成了先升级控制平面、后升级节点的顺序。允许的差距范围过去变更过,所以请在目标版本对应的“Version Skew Policy”页面中确认。

2. 是否在使用将被移除的 API

次要版本升级后,原先已弃用的 API 版本有时会被移除。用已被移除的 API 版本编写的清单或 Helm chart,在升级后将无法 apply。

检查时,比较高效的做法是:先在官方的“Deprecated API Migration Guide”中查出目标版本要移除的 API,再用工具检查手头的清单。pluto、kubent(kube-no-trouble)这类工具,可以从清单、集群内的资源和 Helm 发布中找出对旧 API 的使用。

# 查看 kube-apiserver 记录的“对已弃用 API 的请求”
kubectl get --raw /metrics | grep apiserver_requested_deprecated_apis

这个指标中出现的内容,说明集群内确实有某个东西在调用旧的 API。调用方也可能不在清单仓库里,比如 CI/CD、Operator、监控工具等。

3. 节点能否腾空

更新节点时,要把该节点上的 Pod 迁移到别的节点(drain)。此时如果存在下面这样的 Pod,就会卡住,或者导致服务中断。

  • 只有 1 个副本的 Deployment:迁移期间服务会停止。
  • PodDisruptionBudget(PDB)过于严格:如果 minAvailable 与副本数相同,一个 Pod 都无法驱逐,drain 就无法推进。
  • 在节点本地磁盘(emptyDir)中保存数据的 Pod:驱逐后其中的内容会消失。

重要的应用请把副本数设为 2 个以上,并用 PDB 规定“可以同时停止的数量”。

4. etcd 备份

控制平面基本上无法降级。出问题时的最后手段是从 etcd 快照恢复,所以请在操作前立即做好快照。如果是用 kubeadm 搭建的集群,在控制平面节点上按下面的方式执行(证书路径为 kubeadm 的默认路径)。

sudo ETCDCTL_API=3 etcdctl \
  --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 \
  snapshot save /var/backups/etcd-$(date +%Y%m%d).db

快照请同时复制到另一台服务器上。此外,应用的数据(持久卷和数据库)也要另行备份。etcd 中只保存了 Kubernetes 资源的定义。

5. 先在测试环境中试一遍

如果有配置相同的测试集群,先在那里升级,确认应用的运行情况。附加组件(CNI、Ingress 控制器、cert-manager 等)是否支持新版本,也要分别通过各自的发行说明来确认。

用 kubeadm 搭建的集群的升级步骤

这里假设系统是 Ubuntu/Debian,软件包是从 pkgs.k8s.io 的仓库安装的。这个仓库按次要版本分开,所以要先把 URL 改写成目标版本的仓库,再进行更新。旧的 apt.kubernetes.io 仓库已经无法使用,所以请不要直接照搬旧文档里的命令。

控制平面(第 1 台)

# 改写仓库的版本之后
sudo apt-get update
sudo apt-mark unhold kubeadm
sudo apt-get install -y kubeadm='1.33.x-*'   # x 为可用的补丁版本号
sudo apt-mark hold kubeadm

kubeadm version
sudo kubeadm upgrade plan
sudo kubeadm upgrade apply v1.33.x

kubeadm upgrade plan 会显示当前版本可以升级到哪些版本,以及各组件会如何变化。如果这里出现错误或警告,请先解决,再进入 apply。apply 除了更新 kube-apiserver 等静态 Pod 之外,还会把 CoreDNS 和 kube-proxy 也替换成新版本。

在第 2 台及之后的控制平面上,请执行 sudo kubeadm upgrade node,而不是 apply。

各节点的 kubelet 和 kubectl

包括控制平面节点在内,按下面的流程逐台进行。

# 在操作终端上:驱逐 Pod,并将节点移出调度范围
kubectl drain <节点名> --ignore-daemonsets --delete-emptydir-data

# 在目标节点上:
#(工作节点在这里先更新 kubeadm,并执行 sudo kubeadm upgrade node)
sudo apt-mark unhold kubelet kubectl
sudo apt-get install -y kubelet='1.33.x-*' kubectl='1.33.x-*'
sudo apt-mark hold kubelet kubectl
sudo systemctl daemon-reload
sudo systemctl restart kubelet

# 在操作终端上:恢复为可调度
kubectl uncordon <节点名>
kubectl get nodes

加上 --delete-emptydir-data 后,emptyDir 中的内容会被删除。请事先确认是否有 Pod 的数据丢失后会造成问题,确认后再加上。如果 drain 一直无法结束,请用 kubectl get pdb -A 找出阻止驱逐的 PDB。1 台完成并恢复为 Ready、确认应用正常之后,再进入下一个节点。

替换节点的方式

除了更新现有节点,也可以添加新版本的节点,再依次对旧节点执行 drain 并删除。在云上的集群中,这种做法更为常见。操作系统和容器运行时也可以一并切换到新镜像,如果失败,可以删除新节点,回到旧节点。

如果想进一步稳妥,也可以整体另建一个新版本的集群,迁移应用后,再通过 DNS 或负载均衡器切换(蓝绿部署)。虽然费事,但即使控制平面出现问题,也能回到原来的集群。

使用托管服务的情况

在 EKS、GKE、AKS 上,控制平面的更新用一条命令或界面操作即可完成。不过,事前检查的思路,以及之后再升级节点的顺序,都是一样的。用 eksctl 管理 EKS 时,流程如下。

eksctl upgrade cluster --name wp-cluster --version 1.33 --approve
eksctl upgrade nodegroup --cluster wp-cluster --name ng-general --kubernetes-version 1.33

在控制平面之后,还要把 vpc-cni、coredns 等附加组件更新为支持新版本的版本。EKS 还有在升级前提示是否使用了已弃用 API 等情况的功能,可以在管理控制台或 CLI 中查看。GKE 可能会根据发布渠道自动更新,AKS 则用 az aks upgrade 更新。各服务的功能和默认行为可能会变化,所以每次操作时请确认官方文档。

升级后的检查

  • 用 kubectl get nodes 查看所有节点是否为 Ready,版本是否符合预期。
  • 用 kubectl get pods -A 查看是否有 CrashLoopBackOff 或 Pending 的 Pod。
  • 能否通过 Ingress 打开应用(如果是 WordPress,就是首页和后台)。
  • 监控和日志收集的代理是否仍在持续发送数据。

对出现问题的 Pod,用 kubectl describe pod 的 Events 和 kubectl logs --previous 查找原因。

总结

  • 次要版本要逐个升级,顺序为控制平面、附加组件、节点。kubelet 不能比 kube-apiserver 新。
  • 将被移除的 API 要事先通过指南和工具查找,并用 apiserver_requested_deprecated_apis 确认实际的调用方。
  • 重新检查 PDB 和副本数,避免 drain 时服务停止。
  • 操作前立即备份 etcd 快照和应用的数据。基本上无法降级。
  • 使用 kubeadm 时,先切换为 pkgs.k8s.io 按版本划分的仓库,再执行 kubeadm upgrade plan / apply。

关于 WordPress 有疑问?本站运营方位于日本,仅以日语回复。 联系我们(日语)

お気軽にご相談ください

お見積りへ お問い合わせへ
▲