实验基线:Kubernetes v1.37.0、kubectl v1.37.0。先在测试环境执行,记录变更前状态与回滚点;生产集群不得直接照抄节点地址、网段、存储类或资源额度。
高可用不是多放几台机器
控制平面至少跨故障域部署,API Server 前放健康检查正确的负载均衡器;etcd 使用奇数成员并关注磁盘延迟。业务工作负载还要配置多副本、拓扑分布、PDB 与反亲和性。控制面高可用不能替代应用高可用。
升级前门禁
- 阅读目标小版本发布说明与弃用 API。
- 确认 kubeadm 只跨一个次版本,例如 1.36.x 到 1.37.x,不跳版本。
- 先做 etcd 快照和关键资源导出,并实际验证可读取。
- 确认 CNI、CSI、Ingress、监控和准入组件兼容。
- 准备回滚边界、维护窗口和停止条件。
kubeadm upgrade plan
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data
# 升级该节点 kubelet/kubectl 并重启 kubelet
kubectl uncordon <node>
kubectl get nodes
kubectl get pods -A先升级一个控制平面,再逐台升级其余控制平面和工作节点。每台节点之间执行系统与业务冒烟测试。
etcd 快照与恢复
ETCDCTL_API=3 etcdctl snapshot save snapshot.db \
--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
etcdutl snapshot status snapshot.db --write-out=table恢复必须在隔离环境按目标版本文档演练,校验资源、工作负载数据与业务读写。etcd 只包含集群状态,不包含 PV 中的业务数据,因此还需要存储快照或应用级备份。
灾备验收
- 定义 RPO/RTO 与负责人。
- 模拟单节点、单故障域和控制面故障。
- 从备份恢复到隔离集群。
- 验证 DNS、证书、Secret、PV、入口和业务一致性。
- 记录实际耗时与缺口,修订手册后再次演练。
高可用拓扑验收
- API Server 至少两个实例,入口负载均衡器有独立健康检查。
- etcd 使用 3 或 5 个低延迟成员,避免偶数成员。
- 控制平面、工作节点和业务副本跨故障域。
- 关键附加组件(CNI、CoreDNS、CSI、Ingress、监控)本身具备冗余。
- 证书过期、磁盘容量、etcd 延迟和备份新鲜度都有告警。
升级执行清单
- 冻结非必要变更,记录当前版本和健康基线。
- 运行弃用 API 检查,升级第三方控制器。
- 保存 etcd 快照与资源清单,在隔离环境验证恢复。
- 升级 kubeadm,执行
kubeadm upgrade plan。 - 先升级一个控制平面并做 API/DNS/调度/业务检查。
- 逐台完成其余控制平面。
- 逐台 drain、升级 kubelet、重启、uncordon 工作节点。
- 观察至少一个业务高峰周期再结束变更。
kubelet 可以在受支持的版本偏差范围内短暂落后,但升级计划仍应尽快收敛,不能把版本偏差当长期状态。
etcd 快照前后校验
ETCDCTL_API=3 etcdctl endpoint health --cluster \
--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
sha256sum snapshot.db > snapshot.db.sha256
etcdutl snapshot status snapshot.db --write-out=table快照和证书材料必须加密存储、限制访问并异地保留。恢复时按目标 Kubernetes/etcd 版本文档操作到隔离目录,修改静态 Pod manifest 指向恢复后的数据目录,再逐项验证。
灾难恢复演练脚本
| 阶段 | 验收 |
|---|---|
| 宣布事件 | 角色、时间线、停止条件明确 |
| 隔离恢复 | 不连接生产写流量 |
| 恢复控制面 | readyz、节点、系统 Pod 正常 |
| 恢复数据 | PV/数据库备份一致且可读写 |
| 业务验证 | 认证、DNS、入口、核心交易通过 |
| 复盘 | 实际 RPO/RTO、缺口和负责人记录 |
容量与性能基线
按节点可分配资源而不是物理总量规划;为系统 Pod、DaemonSet、滚动升级 surge 和节点故障保留余量。etcd 优先低延迟持久盘,API Server 关注请求限流,CoreDNS 关注缓存与副本。每季度至少做一次恢复演练,并在 Kubernetes、CSI 或备份组件升级后重新验证。
逐节点升级的命令骨架
# 第一个控制平面:先升级 kubeadm
sudo apt-mark unhold kubeadm
sudo apt-get update && sudo apt-get install -y kubeadm='1.37.x-*'
sudo apt-mark hold kubeadm
sudo kubeadm upgrade plan
sudo kubeadm upgrade apply v1.37.x
# 每个节点:排空后升级 kubelet/kubectl
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data
sudo apt-mark unhold kubelet kubectl
sudo apt-get install -y kubelet='1.37.x-*' kubectl='1.37.x-*'
sudo apt-mark hold kubelet kubectl
sudo systemctl daemon-reload && sudo systemctl restart kubelet
kubectl uncordon <node>1.37.x-*必须替换为仓库中实际版本,并按官方目标补丁版本文档执行。--delete-emptydir-data会删除 emptyDir 数据,排空前要确认应用能承受。
每台节点后的门禁
kubectl get nodes
kubectl get pods -A -o wide
kubectl get --raw='/readyz?verbose'
kubectl get events -A --sort-by=.metadata.creationTimestamp | tail -n 50此外验证 CoreDNS、Service、Ingress、持久卷挂载、监控采集和至少一条核心业务链路。任何门禁失败都停止后续节点升级。
恢复不是一条命令
- 隔离故障集群并保存日志、manifest 和损坏数据副本。
- 确认快照哈希、版本、revision 和来源集群。
- 在新目录执行 etcdutl snapshot restore。
- 按官方文档更新 etcd 静态 Pod 的数据目录/集群参数。
- 等待 API Server 恢复,检查 readyz 与系统组件。
- 恢复/核验 PV 业务数据、Secret、证书和入口。
- 业务只读验证通过后再受控恢复写流量。
季度演练故障集
- 单工作节点丢失:验证重调度与存储重挂。
- 单控制平面丢失:验证 API 入口和 etcd quorum。
- 错误发布:验证自动门禁与回滚。
- etcd 全量恢复:验证对象状态与证书。
- 业务卷恢复:验证应用一致性与实际 RTO。
- 区域不可用:验证 DNS/流量切换和数据 RPO。
可复现记录模板
每次实验记录:集群版本、容器运行时、CNI/CSI 版本、命名空间、使用的 YAML Git 提交、开始与结束时间。命令输出至少保留对象状态、事件、关键日志和回滚结果。文中的占位符必须替换成自己的值,生产执行前应由第二人复核。
故障处理原则
- 先缩小影响面,不删除现场。
- 按对象状态—事件—日志—依赖顺序收集证据。
- 提出可证伪假设,一次只改变一个变量。
- 验证恢复后清理临时权限、调试 Pod、端口转发和测试数据。
完成检查
- 命令退出码为 0,目标对象状态与预期一致。
- 保存执行前后 YAML、事件与关键日志,确认没有把测试命名空间以外的对象改动。
- 故障演练完成后执行清理或回滚,再进行下一章。