3. 故障域定义与划分原则

在 CrashLoop 场景下,故障域(Failure Domain)是资源模型恢复方案的基础抽象单元。一个故障域定义为一组共享同一失效风险组件的资源集合——当该组件失效时,域内所有资源同时不可用。正确的故障域划分决定了恢复策略的粒度、并行度与安全边界。

3.1 故障域核心概念

故障域的本质是失效相关性的边界。在 Kubernetes 集群中,故障域通常按物理或逻辑层级组织:

层级 失效范围 典型故障源 CrashLoop 影响
Pod 单个容器实例 应用崩溃、OOM、配置错误 CrashLoopBackOff 直接表现
Node 节点上所有 Pod 内核 Panic、磁盘故障、网络中断 批量 CrashLoop 或 NotReady
可用区 区域内所有节点 机房断电、光缆中断、制冷失效 大规模级联 CrashLoop
集群 整个控制面 + 数据面 etcd 损坏、API Server 过载、证书过期 全局恢复困难
关键原则:故障域划分必须满足 MECE(Mutually Exclusive, Collectively Exhaustive)——域间互斥、域内穷举。一个资源只能属于一个故障域,且所有资源必须被某个故障域覆盖。

3.2 按节点划分故障域

节点级故障域是最常用的划分粒度。每个 Kubernetes Node 作为一个独立故障域,域内包含该节点上运行的所有 Pod 和 DaemonSet 实例。

  • 划分依据:节点名称、节点 IP、节点标签(如 kubernetes.io/hostname)。
  • 隔离边界:节点内核、kubelet 进程、本地存储、节点网络接口。
  • CrashLoop 场景:当节点磁盘 I/O 饱和或内存泄漏时,该节点上所有 Pod 可能同时进入 CrashLoopBackOff 状态。
  • 恢复策略:节点级驱逐 + Pod 反亲和调度,避免同一工作负载的多个副本落在同一节点。
# 节点故障域标签示例
kubectl label node worker-01 failure-domain.beta.kubernetes.io/node=worker-01
kubectl label node worker-02 failure-domain.beta.kubernetes.io/node=worker-02

3.3 按可用区划分故障域

可用区(Availability Zone, AZ)是云原生架构中最重要的故障域层级。一个可用区通常对应一个独立的物理数据中心或电力域,多个可用区组成一个区域(Region)。

属性 节点级 可用区级 集群级
失效半径 单台物理机 整个数据中心 控制面 + 所有节点
恢复时间目标 分钟级 小时级 小时~天级
CrashLoop 扩散 局部 区域级 全局
资源模型策略 PodAntiAffinity TopologySpreadConstraints 多集群联邦
最佳实践:在云环境中,始终使用 topology.kubernetes.io/zone 标签标记可用区。Pod 的 topologySpreadConstraints 应配置为 maxSkew=1,确保每个可用区最多承载一个副本的偏差。

3.4 按集群划分故障域

集群级故障域用于跨集群容灾场景。当单个集群的控制面(etcd、API Server、Controller Manager)整体失效时,整个集群内的所有工作负载都处于风险中。

  • 划分依据:集群名称、集群 ID、集群所属 Region。
  • 隔离边界:etcd 集群、API Server 端点、集群 CA 证书、网络策略。
  • CrashLoop 场景:etcd 磁盘空间满导致写入失败 → 所有 Pod 状态更新停滞 → 新 Pod 无法调度 → 已有 Pod 因健康检查失败进入 CrashLoop。
  • 恢复策略:多集群服务网格(如 Istio)或 Cluster API 的跨集群 workload 迁移。

3.5 故障隔离边界

故障隔离边界定义了故障域之间的失效传播阻断点。在 CrashLoop 场景下,隔离边界必须满足以下条件:

  1. 资源不共享:不同故障域之间不能共享同一物理资源(如同一块磁盘、同一根网线)。
  2. 控制面独立:每个故障域应有独立的控制面组件或至少独立的 API Server 端点。
  3. 状态不耦合:一个故障域内的 CrashLoop 不应导致另一个故障域的配置变更或状态回滚。
  4. 恢复不阻塞:一个故障域的恢复操作不应等待另一个故障域的资源释放。
常见误区:仅靠 PodAntiAffinity 无法实现真正的故障隔离。如果两个 Pod 被调度到不同节点但共享同一块 NAS 存储,存储故障会导致两个 Pod 同时 CrashLoop。故障域划分必须覆盖计算、存储、网络三个维度。

3.6 故障域划分的层次结构

下图展示了从 Pod 到集群的四层故障域模型,以及 CrashLoop 在不同层级间的传播路径与隔离边界:

故障域层次结构与 CrashLoop 传播路径 集群故障域 (Cluster Failure Domain) 控制面失效 → 全局 CrashLoop · 恢复策略:多集群联邦 隔离边界:etcd 集群 / API Server 端点 / 集群 CA 可用区故障域 (AZ Failure Domain) 机房级失效 → 区域 CrashLoop · 恢复策略:TopologySpreadConstraints 隔离边界:独立电力 / 网络 / 制冷基础设施 节点故障域 (Node Failure Domain) 单机失效 → 局部 CrashLoop · 恢复策略:PodAntiAffinity + 驱逐 隔离边界:节点内核 / kubelet / 本地存储 / 网络接口 Pod 故障域 (Pod Failure Domain) 容器崩溃 → CrashLoopBackOff · 恢复策略:重启策略 + 健康检查 隔离边界:容器 cgroup / 网络命名空间 / 临时存储 传播方向 上层失效 向下传播 CrashLoop

3.7 故障域划分的实践清单

在 CrashLoop 场景下实施故障域划分时,建议按以下步骤操作:

  1. 盘点基础设施拓扑:收集节点分布、可用区映射、存储后端、网络设备列表。
  2. 标记故障域标签:为每个节点和可用区添加标准 Kubernetes 标签(topology.kubernetes.io/zone、failure-domain.beta.kubernetes.io/region)。
  3. 配置拓扑分布约束:为关键工作负载设置 topologySpreadConstraints,指定按 zone 或 hostname 分布。
  4. 验证隔离边界:通过混沌工程注入节点级、可用区级故障,确认 CrashLoop 不会跨域传播。
  5. 建立恢复优先级:按故障域层级定义恢复顺序——先恢复 Pod 级,再恢复节点级,最后处理可用区级和集群级。
核心结论:故障域划分不是一次性的静态操作,而是随着集群拓扑变化持续演进的动态过程。每次节点扩缩容、可用区变更或集群升级后,都应重新验证故障域划分的正确性。