3. 故障域概念

故障域(Failure Domain)是集群架构中用于隔离故障影响范围的一组物理或逻辑边界。在 Kubernetes 集群中,合理划分故障域能够确保单一组件的失效不会扩散至整个集群,是保障服务高可用性的基础设计原则。

3.1 故障域定义

故障域定义了一组共享同一故障风险因素的资源集合。当该域内的某个关键组件(如电源、网络交换机、机架PDU)发生故障时,域内所有资源都会受到影响。故障域的核心特征包括:

  • 共享风险:域内资源依赖相同的底层基础设施。
  • 故障隔离:域间故障不应相互传播。
  • 层级嵌套:大故障域可包含多个小故障域。
  • 资源分布:高可用架构要求副本跨故障域部署。
关键原则:Kubernetes 调度器通过 topology.kubernetes.io/zone 和 topology.kubernetes.io/region 标签识别故障域,Pod 反亲和性规则利用这些标签实现跨域分布。

3.2 常见故障域类型

故障域层级 典型范围 共享风险组件 MTBF 影响 Kubernetes 标签
可用区(AZ) 独立数据中心或机房 市电、骨干网络、冷却系统 数年一次 topology.kubernetes.io/zone
机架(Rack) 42U 标准机柜 ToR 交换机、PDU、KVM 数月一次 topology.kubernetes.io/rack(自定义)
主机(Host) 单台物理服务器 电源模块、磁盘、网卡 数周一次 kubernetes.io/hostname
实践建议:在公有云环境中,可用区是最高优先级的故障域;在自建机房中,机架级故障域往往比可用区更频繁发生,建议优先配置机架反亲和。

3.3 故障域对集群稳定性的影响

故障域划分直接影响集群的可用性指标和容灾能力。以下从三个维度分析其影响:

3.3.1 可用性量化影响

假设每个故障域的独立可用性为 A_domain,副本数为 N,跨域部署后的集群可用性计算公式为:

# 跨域部署(N 个副本分布在 N 个不同故障域)
A_cluster = 1 - (1 - A_domain)^N

# 同域部署(N 个副本集中在同一个故障域)
A_cluster = A_domain

以可用区为例,假设单 AZ 可用性为 99.9%(年故障约 8.76 小时),跨 3 个 AZ 部署 3 副本:

A_cluster = 1 - (1 - 0.999)^3 = 1 - 0.001^3 = 0.999999999
年故障时间 ≈ 0.0315 秒

可见,跨故障域部署可将可用性从 99.9% 提升至 99.9999999%。

3.3.2 故障扩散抑制

未合理划分故障域时,单一故障可能引发级联效应:

  • 控制面故障:etcd 副本全部位于同一机架,机架断电导致集群完全不可用。
  • 数据面故障:所有业务 Pod 集中在同一可用区,该 AZ 网络故障导致服务全部中断。
  • 资源争抢:故障域内节点同时触发 OOM,导致剩余节点过载。

3.3.3 容量规划约束

故障域划分对容量突增场景有直接影响:

场景 同域部署 跨域部署
突发流量 2x 单域资源不足,触发 Pending 多域分摊,可弹性扩容
单域故障 服务完全不可用 剩余域承载流量,容量降级 33%
Helm 水位预测 按单域峰值预测,浪费资源 按多域均值预测,利用率更高
常见误区:部分团队仅配置了 Pod 反亲和,但未在节点层面打故障域标签,导致调度器无法识别真实故障边界。务必确保 kubelet 启动时正确注入 --node-labels 参数。

3.4 故障域拓扑结构

下图展示了从可用区到主机的三层故障域层级关系,以及故障传播路径:

故障域层级拓扑与故障传播路径 可用区 A(AZ-A) 共享风险:市电、骨干网络、冷却系统 标签:topology.kubernetes.io/zone=az-a 机架 R1 共享风险:ToR 交换机、PDU 标签:rack=r1 机架 R2 共享风险:ToR 交换机、PDU 标签:rack=r2 Host-1 kubernetes.io/hostname Host-2 kubernetes.io/hostname Host-3 kubernetes.io/hostname Host-4 kubernetes.io/hostname 故障传播路径 故障隔离设计要点 Pod 副本应分布在不同的可用区 → 不同机架 → 不同主机,形成逐层隔离

3.5 故障域配置实践

在 Kubernetes 集群中配置故障域标签的标准步骤:

  1. 节点打标:在 kubelet 启动参数或节点创建时注入标签。
  2. 验证标签:使用 kubectl get nodes --show-labels 确认。
  3. 配置反亲和:在 Deployment/StatefulSet 中设置 PodAntiAffinity。
  4. 测试故障:模拟单域故障,验证 Pod 是否重新调度到其他域。
# 节点打标示例(kubelet 启动参数)
--node-labels="topology.kubernetes.io/zone=az-a,topology.kubernetes.io/rack=r1"

# Pod 反亲和配置示例
apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - my-app
            topologyKey: topology.kubernetes.io/zone
容量规划提示:在 Helm Chart 中,可通过 .Values.topologySpreadConstraints 参数动态设置故障域分布策略,结合 HPA 和 VPA 实现跨域自动扩缩容。