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 的版本偏差有明确限制。升级顺序通常是:

  1. 先把当前次版本升级到最新补丁;
  2. 升级第一个控制面节点;
  3. 逐台升级其余控制面节点;
  4. 升级工作节点;
  5. 升级客户端和外围组件;
  6. 进入观察期后再考虑下一个次版本。

不得仅凭“旧 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 命令。

可采用的恢复路径包括:

  1. 单个节点失败:停止该节点继续升级,排查软件包、CNI、CRI 或 kubelet;
  2. 控制面组件未启动:使用 kubeadm 生成的静态清单备份恢复;
  3. etcd 升级或数据损坏:在隔离且确认仲裁关系后执行快照恢复;
  4. 插件不兼容:恢复插件清单或安装兼容版本;
  5. 业务不兼容:通过 GitOps 或发布平台回滚业务,不一定回滚集群;
  6. 全局不可恢复:按经过演练的集群重建与业务恢复流程执行。

恢复期间不要让旧、新控制面同时写入不同的 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 和下一版本计划;
  • [ ] 安全清理临时备份前已确认长期备份可恢复。

参考资料

Copyright © yan-jian.com 2023 - 2026 · Powered by GitBook更新时间: 2026-10-25 22:20:44

results matching ""

    No results matching ""