4. 集群级故障诊断与恢复

当 OpenShift 集群出现“大面积不可用”时,问题往往不在业务负载,而在控制平面本身。控制平面由 API Server、etcd、控制器管理器和调度器组成,其中 API Server 是所有交互的唯一入口,etcd 是唯一可信状态源。本节围绕四类典型集群级故障展开:API Server 不可用、etcd 集群脑裂、证书过期、控制平面节点宕机,重点讲清“如何定位”和“如何恢复”。

核心判断原则:先区分“API Server 进程问题”与“etcd 数据问题”。API Server 不可用通常表现为客户端无法连接;etcd 脑裂则表现为部分节点可读、部分节点写入失败或数据不一致。两者的恢复路径完全不同,误判会导致数据丢失。

一、API Server 不可用

API Server 不可用的典型现象是 oc 命令返回 Unable to connect to the server: dial tcp ... connection refused 或超时。此时不要急于重启,先判断是单节点故障还是全部节点故障。

定位步骤:首先通过 SSH 登录控制平面节点,检查 API Server 静态 Pod 状态。OpenShift 中 API Server 以静态 Pod 形式运行,kubelet 直接管理,不依赖 API Server 自身。执行:

crictl ps | grep kube-apiserver
crictl logs <apiserver-container-id> --tail 100

若容器不存在或反复重启,查看 kubelet 日志:journalctl -u kubelet -n 200。常见原因包括:静态 Pod 清单文件被误删、证书文件缺失、etcd 连接失败、端口 6443 被占用。

恢复方式:若为单节点 API Server 故障,其他控制平面节点的 API Server 仍可服务,集群整体可用,只需修复该节点。若所有节点 API Server 均不可用,需从 etcd 恢复或修复证书。对于静态 Pod 清单丢失,可从其他控制平面节点复制 /etc/kubernetes/manifests/kube-apiserver-pod.yaml 并重启 kubelet。

二、etcd 集群脑裂

etcd 脑裂指集群中多数派分裂,导致部分节点无法达成共识。典型现象:etcdctl endpoint health 显示部分节点不健康,etcdctl endpoint status 显示各节点 RAFT TERM 或 RAFT INDEX 差异巨大,写入操作超时或返回 etcdserver: request timed out。

定位时,先确认 etcd 成员列表和健康状态:

etcdctl --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/static-pod-resources/etcd-certs/ca.crt \
  --cert=/etc/kubernetes/static-pod-resources/etcd-certs/peer.crt \
  --key=/etc/kubernetes/static-pod-resources/etcd-certs/peer.key \
  member list -w table
etcdctl endpoint status -w table

若某节点 RAFT TERM 明显落后,说明它已脱离集群。恢复原则:永远不要直接删除落后节点的数据目录,应先将其从集群中移除,再以新成员身份重新加入。操作如下:

etcdctl member remove <member-id>
# 在故障节点清理数据目录
rm -rf /var/lib/etcd/*
# 重新加入集群(使用集群现有成员作为 initial-cluster)
etcdctl member add <name> --peer-urls=https://<ip>:2380

若多数派已丢失,只能从快照恢复。恢复前必须停止所有 etcd 实例,使用 etcdctl snapshot restore 从最近快照重建数据目录,再逐个启动。恢复后需验证 etcdctl endpoint health 全部为 healthy。

三、证书过期

OpenShift 证书分为两类:集群证书(由 openshift-cluster-operator 管理)和 etcd/API Server 静态证书。证书过期通常表现为 API Server 无法启动、oc 报 x509: certificate has expired,或 etcd 节点间通信失败。

定位:检查证书有效期。对于 API Server:

openssl x509 -in /etc/kubernetes/static-pod-resources/kube-apiserver-certs/secrets/.../tls.crt -noout -dates

恢复:OpenShift 提供 oc adm certificate approve 和 oc adm ca rotate 命令。对于静态证书,需使用 cluster-kube-apiserver-operator 重新生成。若 API Server 已无法启动,需手动替换证书文件并重启 kubelet。etcd 证书过期时,需同时更新 peer 和 server 证书,并确保所有节点时间同步。

四、控制平面节点宕机

单节点宕机时,若集群有 3 个控制平面节点,剩余 2 个仍可维持多数派,集群可用。此时应尽快修复或替换节点。若宕机节点是 etcd 成员,需先将其从 etcd 集群移除,避免影响 quorum。

定位:通过 oc get nodes 查看节点状态为 NotReady,oc get pods -n openshift-etcd 查看 etcd Pod 状态。若节点彻底不可恢复,需执行节点替换流程:从集群中删除节点,清理 etcd 成员,重新安装节点并加入集群。

控制平面故障诊断与恢复决策路径 集群不可用 / oc 命令失败 API Server 是否可连接? (curl -k https://<api>:6443/healthz) 否 API Server 故障 检查静态 Pod / 证书 crictl ps | grep apiserver journalctl -u kubelet 修复清单/证书后重启 是 API Server 正常 检查 etcd 健康状态 etcd 多数派是否健康? (endpoint health) 否 etcd 脑裂 / 多数派丢失 移除落后成员或快照恢复 member remove <id> rm -rf /var/lib/etcd/* member add 重新加入 是 检查证书有效期 openssl x509 -dates 过期则轮换证书 控制平面节点宕机处理 单节点宕机:剩余节点维持 quorum,修复或替换节点;若为 etcd 成员,先 member remove 再重建 多节点宕机:优先恢复 etcd 多数派,再恢复 API Server

五、恢复后的验证与预防

无论哪种故障,恢复后必须执行以下验证:oc get nodes 全部 Ready;oc get clusteroperators 全部 Available=True;etcdctl endpoint health 全部健康;oc get pods -n openshift-etcd 所有 etcd Pod 运行正常。此外,检查 oc get events -A --sort-by=.lastTimestamp 确认无持续报错。

预防措施包括:定期备份 etcd 快照(etcdctl snapshot save),监控证书到期时间(建议提前 30 天告警),保持控制平面节点时间同步(NTP),以及避免在 etcd 节点上运行高负载业务 Pod。对于生产集群,建议至少 3 个控制平面节点,并配置 etcd 独立磁盘。

etcd 快照恢复是最后手段,恢复后集群状态会回退到快照时间点,期间所有变更丢失。因此,优先尝试修复单个成员而非整体恢复。