Kubernetes 生产集群升级、弃用 API 治理与回滚演练
Kubernetes 升级不是简单地替换几个二进制文件。真正困难的是确认控制面、kubelet、CNI、CSI、Ingress、Admission Webhook、监控组件和业务清单能够同时跨过版本边界,并且在出现异常时仍然保留可验证的退路。
本文以 kubeadm 管理的高可用集群为主线,给出一套可以重复执行的升级方法。托管 Kubernetes 的具体命令不同,但风险识别、分批验证和回滚边界同样适用。
重要原则:不要跳过 Kubernetes 次版本升级;不要把 etcd 快照等同于完整业务备份;不要在没有演练和维护窗口的情况下直接升级生产集群。
一、先定义升级成功标准
在讨论命令以前,先确定本次升级的目标和退出条件。
至少记录以下内容:
| 项目 | 需要回答的问题 |
|---|---|
| 当前版本 | 控制面、kubelet、kubectl、kubeadm 分别是什么版本 |
| 目标版本 | 目标次版本和补丁版本是什么,是否仍在官方支持期 |
| 可用性目标 | 升级期间允许多少节点不可用,核心业务是否允许重调度 |
| 数据保护 | etcd、数据库、对象存储、PV 分别如何备份和恢复 |
| 回滚边界 | 哪一步以前可以回滚二进制,哪一步以后需要恢复集群或数据 |
| 验证窗口 | 每批升级后观察多久,哪些指标必须恢复到基线 |
升级成功不应只看 kubectl get nodes 是否为 Ready,还要验证入口流量、服务发现、存储挂载、DNS、证书、控制器队列、告警和关键业务事务。
二、建立版本与依赖清单
1. 采集集群版本
kubectl version
kubectl get nodes -o wide
kubeadm version
kubectl get --raw='/readyz?verbose'
kubectl get --raw='/livez?verbose'
同时记录:
- 容器运行时及版本:
containerd --version、crictl version; - CNI 类型与版本,如 Calico、Cilium;
- CSI 驱动与 external-provisioner、snapshotter 版本;
- CoreDNS、kube-proxy、Ingress Controller;
- Metrics Server、Prometheus Operator、日志采集器;
- Admission Webhook、Operator 和自研控制器;
- Helm Chart、CRD 与 API 组版本。
2. 核对版本偏差
Kubernetes 对 kube-apiserver、kubelet、kube-controller-manager、kube-scheduler 和 kubectl 的版本偏差有明确限制。升级顺序通常是:
- 先把当前次版本升级到最新补丁;
- 升级第一个控制面节点;
- 逐台升级其余控制面节点;
- 升级工作节点;
- 升级客户端和外围组件;
- 进入观察期后再考虑下一个次版本。
不得仅凭“旧 kubelet 还能连接新 API Server”就长期保留混合版本。
三、治理弃用 API
API 被弃用不代表马上不可用,但在目标版本停止提供后,旧清单、控制器或 Webhook 会直接失败。
1. 从对象清单检查
将 Git 仓库、Helm 渲染结果和集群对象统一扫描:
helm template example ./chart > rendered.yaml
kubectl api-resources --verbs=list -o name
kubectl get --raw /metrics | grep apiserver_requested_deprecated_apis
可配合 Pluto、kubent 等工具做静态扫描,但最终仍应以目标版本的官方弃用指南和 API Discovery 结果为准。
2. 从审计日志检查真实调用方
仅扫描现有对象不够。某些 CI 脚本、旧 Operator 或外部系统可能仍在调用旧 API。应在升级前至少观察一个完整业务周期,按以下字段汇总审计日志:
user.username;userAgent;objectRef.apiGroup;objectRef.apiVersion;objectRef.resource;- 响应码和请求次数。
识别调用方后,先升级客户端,再迁移对象版本。不要只把 YAML 中的 apiVersion 文本替换掉,字段语义、默认值和控制器行为也可能改变。
3. 检查 Webhook 兼容性
kubectl get validatingwebhookconfigurations,mutatingwebhookconfigurations -o yaml
重点检查:
admissionReviewVersions是否包含目标版本支持值;matchPolicy是否合理;- Webhook 服务证书是否有效;
failurePolicy会不会在升级期间阻塞所有资源写入;- 自研 Webhook 是否能忽略未知字段。
四、升级前健康检查与备份
1. 控制面基线
kubectl get --raw='/readyz?verbose'
kubectl get --raw='/metrics' > apiserver-metrics-before.txt
kubectl get events -A --sort-by=.lastTimestamp > events-before.txt
kubectl get pods -A -o wide > pods-before.txt
kubectl get nodes -o yaml > nodes-before.yaml
升级前不应存在未解释的控制面错误、持续 CrashLoopBackOff、磁盘压力、证书临期或 etcd 告警。
2. etcd 快照
使用与集群匹配的 etcdctl,显式提供端点和证书:
ETCDCTL_API=3 etcdctl \
--endpoints=https://127.0.0.1:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt \
--key=/etc/kubernetes/pki/etcd/healthcheck-client.key \
snapshot save /secure-backup/etcd-before-upgrade.db
ETCDCTL_API=3 etcdctl snapshot status \
/secure-backup/etcd-before-upgrade.db --write-out=table
快照必须复制到集群外,并验证可以在隔离环境恢复。只保存文件但从未恢复演练,不能算有效备份。
3. 业务数据与声明式配置
etcd 快照不一定包含外部数据库和存储后端中的数据。还需要:
- 数据库一致性备份;
- 关键 PV 的快照或应用级备份;
- GitOps 仓库和 Helm values;
- kubeadm 配置、证书目录、静态 Pod 清单;
- CNI、CSI 和负载均衡器配置;
- 当前软件包及镜像清单。
五、先在演练环境走完整流程
演练环境至少应包含:
- 与生产相同的当前版本和目标版本;
- 相同类型的 CNI、CSI、Ingress 和 Admission Webhook;
- 一组有状态和无状态样例业务;
- PDB、反亲和、Local PV、CronJob 等易受升级影响的对象;
- 失败注入,例如镜像不可拉取、节点无法重启、CNI 未就绪。
演练要记录每一步耗时、观察指标和恢复动作,并把命令整理为经过评审的 Runbook。
六、执行 kubeadm 升级
以下命令只展示流程,实际版本号应来自升级计划和软件仓库。
1. 第一个控制面节点
sudo kubeadm upgrade plan
sudo kubeadm upgrade apply v1.xx.y
sudo systemctl daemon-reload
sudo systemctl restart kubelet
sudo systemctl status kubelet --no-pager
执行前确认目标镜像可访问,必要时提前预拉取。升级完成后检查静态 Pod、etcd 成员、证书和 API Server 健康状态。
2. 其余控制面节点
逐台执行,任何时刻都要保证多数 etcd 成员和足够的 API Server 实例可用:
sudo kubeadm upgrade node
sudo systemctl restart kubelet
不要同时重启全部控制面节点。
3. 工作节点
kubectl cordon worker-01
kubectl drain worker-01 \
--ignore-daemonsets \
--delete-emptydir-data \
--timeout=20m
升级 kubeadm、kubelet、kubectl 和运行时后:
sudo kubeadm upgrade node
sudo systemctl restart kubelet
kubectl uncordon worker-01
每批节点数量应由业务副本、PDB、剩余容量和故障域决定。节点恢复 Ready 不等于可以立即开始下一批,还应确认业务 Pod 已稳定、错误率和延迟回到基线。
七、CNI、CSI与核心插件
Kubernetes 不会替你处理全部插件兼容性。
CNI
检查:
- 目标 Kubernetes 版本支持矩阵;
- CRD 是否需要先升级;
- kube-proxy 替代模式或 eBPF 数据面兼容性;
- NetworkPolicy 行为;
- MTU、隧道和路由状态。
CSI
检查 external-provisioner、attacher、resizer、snapshotter 和 node-driver-registrar。升级后至少完成一次卷创建、挂载、扩容、快照和恢复测试。
CoreDNS
kubectl -n kube-system get deploy coredns -o yaml
kubectl run dns-test --rm -it --restart=Never \
--image=busybox:1.36 -- nslookup kubernetes.default.svc.cluster.local
同时检查自定义 Corefile 插件是否仍兼容。
八、分阶段验收
控制面
/readyz与/livez全部通过;- API Server 5xx、请求延迟和限流恢复正常;
- controller-manager、scheduler 无持续错误;
- etcd 无 leader 频繁切换、空间超限和高延迟。
节点
- Node Ready,版本与运行时符合计划;
- kubelet 日志无证书、CRI、CNI、CSI 错误;
- 不存在 DiskPressure、MemoryPressure、PIDPressure;
- DaemonSet 全部恢复。
业务
- 内外部 DNS、Service、Ingress 正常;
- 新建 Pod、Job、PVC 能成功;
- 滚动发布、HPA、CronJob 正常;
- 关键事务和异步任务无积压;
- 监控、日志、追踪没有数据断层。
九、理解回滚边界
Kubernetes 升级后的“回滚”通常不是执行一条 downgrade 命令。
可采用的恢复路径包括:
- 单个节点失败:停止该节点继续升级,排查软件包、CNI、CRI 或 kubelet;
- 控制面组件未启动:使用 kubeadm 生成的静态清单备份恢复;
- etcd 升级或数据损坏:在隔离且确认仲裁关系后执行快照恢复;
- 插件不兼容:恢复插件清单或安装兼容版本;
- 业务不兼容:通过 GitOps 或发布平台回滚业务,不一定回滚集群;
- 全局不可恢复:按经过演练的集群重建与业务恢复流程执行。
恢复期间不要让旧、新控制面同时写入不同的 etcd 数据目录,也不要在未确认成员关系时随意复制 /var/lib/etcd。
十、常见故障场景
节点 drain 一直阻塞
检查 PDB、孤立 Pod、Local Storage、长时间终止和 StatefulSet 副本。不要习惯性加 --force 绕过保护,应先确认该 Pod 是否有替代实例和数据保护。
API Server升级后Webhook超时
检查 Webhook Service、Endpoints、证书、网络策略和 failurePolicy。必要时按预案临时缩小匹配范围,而不是直接删除全部准入控制。
CoreDNS正常但业务解析失败
同时检查 Pod 的 /etc/resolv.conf、NodeLocal DNSCache、上游 DNS、网络策略和 conntrack,不要只重启 CoreDNS。
新节点Ready但Pod无法创建
依次检查 kubelet、CRI、CNI、镜像仓库和 CSI。Ready 主要反映 kubelet心跳,并不能证明每个扩展组件可用。
十一、生产升级检查清单
升级前
- [ ] 已阅读目标版本发行说明与弃用指南;
- [ ] 已确认版本偏差、插件兼容矩阵和镜像来源;
- [ ] 已扫描静态清单和真实弃用 API 调用;
- [ ] 已验证 etcd、数据库和 PV 备份;
- [ ] 已完成同版本路径演练;
- [ ] 已定义暂停、继续和恢复条件;
- [ ] 已预留节点容量并核对 PDB。
升级中
- [ ] 控制面逐台升级;
- [ ] 工作节点按批次 cordon、drain、升级、验证、uncordon;
- [ ] 每批完成后观察控制面和业务指标;
- [ ] 没有用强制参数掩盖未理解的问题。
升级后
- [ ] 控制面、节点、CNI、CSI、DNS、Ingress 全部验证;
- [ ] 完成新建、发布、扩容、挂载和快照测试;
- [ ] 连续观察至少一个业务高峰;
- [ ] 更新资产清单、Runbook 和下一版本计划;
- [ ] 安全清理临时备份前已确认长期备份可恢复。
参考资料
- Kubernetes:Upgrading kubeadm clusters
https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-upgrade/ - Kubernetes:Version Skew Policy
https://kubernetes.io/releases/version-skew-policy/ - Kubernetes:Deprecated API Migration Guide
https://kubernetes.io/docs/reference/using-api/deprecation-guide/ - Kubernetes:Operating etcd clusters
https://kubernetes.io/docs/tasks/administer-cluster/configure-upgrade-etcd/