运维实战

Kubernetes 生产运维:高可用、升级、etcd 备份与灾难恢复演练

把高可用拓扑、逐小版本升级、etcd 快照恢复、工作负载备份、容量规划和灾备演练串成可执行生产流程。

TY
Tycho
技术博主
• 2026-09-23 • 19 分钟阅读 • 5 次浏览
Kubernetes 生产运维:高可用、升级、etcd 备份与灾难恢复演练

实验基线: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 中的业务数据,因此还需要存储快照或应用级备份。

灾备验收

  1. 定义 RPO/RTO 与负责人。
  2. 模拟单节点、单故障域和控制面故障。
  3. 从备份恢复到隔离集群。
  4. 验证 DNS、证书、Secret、PV、入口和业务一致性。
  5. 记录实际耗时与缺口,修订手册后再次演练。

高可用拓扑验收

  • API Server 至少两个实例,入口负载均衡器有独立健康检查。
  • etcd 使用 3 或 5 个低延迟成员,避免偶数成员。
  • 控制平面、工作节点和业务副本跨故障域。
  • 关键附加组件(CNI、CoreDNS、CSI、Ingress、监控)本身具备冗余。
  • 证书过期、磁盘容量、etcd 延迟和备份新鲜度都有告警。

升级执行清单

  1. 冻结非必要变更,记录当前版本和健康基线。
  2. 运行弃用 API 检查,升级第三方控制器。
  3. 保存 etcd 快照与资源清单,在隔离环境验证恢复。
  4. 升级 kubeadm,执行 kubeadm upgrade plan。
  5. 先升级一个控制平面并做 API/DNS/调度/业务检查。
  6. 逐台完成其余控制平面。
  7. 逐台 drain、升级 kubelet、重启、uncordon 工作节点。
  8. 观察至少一个业务高峰周期再结束变更。

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、持久卷挂载、监控采集和至少一条核心业务链路。任何门禁失败都停止后续节点升级。

恢复不是一条命令

  1. 隔离故障集群并保存日志、manifest 和损坏数据副本。
  2. 确认快照哈希、版本、revision 和来源集群。
  3. 在新目录执行 etcdutl snapshot restore。
  4. 按官方文档更新 etcd 静态 Pod 的数据目录/集群参数。
  5. 等待 API Server 恢复,检查 readyz 与系统组件。
  6. 恢复/核验 PV 业务数据、Secret、证书和入口。
  7. 业务只读验证通过后再受控恢复写流量。

季度演练故障集

  • 单工作节点丢失:验证重调度与存储重挂。
  • 单控制平面丢失:验证 API 入口和 etcd quorum。
  • 错误发布:验证自动门禁与回滚。
  • etcd 全量恢复:验证对象状态与证书。
  • 业务卷恢复:验证应用一致性与实际 RTO。
  • 区域不可用:验证 DNS/流量切换和数据 RPO。

可复现记录模板

每次实验记录:集群版本、容器运行时、CNI/CSI 版本、命名空间、使用的 YAML Git 提交、开始与结束时间。命令输出至少保留对象状态、事件、关键日志和回滚结果。文中的占位符必须替换成自己的值,生产执行前应由第二人复核。

故障处理原则

  1. 先缩小影响面,不删除现场。
  2. 按对象状态—事件—日志—依赖顺序收集证据。
  3. 提出可证伪假设,一次只改变一个变量。
  4. 验证恢复后清理临时权限、调试 Pod、端口转发和测试数据。

完成检查

  • 命令退出码为 0,目标对象状态与预期一致。
  • 保存执行前后 YAML、事件与关键日志,确认没有把测试命名空间以外的对象改动。
  • 故障演练完成后执行清理或回滚,再进行下一章。

官方资料

TY

Tycho

热爱分享技术知识,帮助开发者成长。

评论 (0)

评论功能当前已关闭
暂无评论,快来抢沙发吧!