1. 故障域基础概念

1.1 什么是故障域(Failure Domain)

故障域是系统中一组共享单一故障点的资源集合。当该故障点失效时,集合内的所有资源都会受到影响。在分布式系统和 Kubernetes 集群中,故障域是进行高可用设计、资源隔离和容灾规划的基本单元。

核心定义:故障域 = 共享同一故障边界的资源组。边界内的任意组件失效,将导致整个域内的服务或数据不可用。

常见的故障域层级包括:

  • 物理机级别:同一台服务器上的所有进程共享电源、网卡、磁盘。
  • 机架级别:同一机架内的服务器共享 PDU(电源分配单元)和 ToR(Top of Rack)交换机。
  • 数据中心级别:同一数据中心共享建筑供电、制冷、网络骨干。
  • 地域级别:同一地理区域可能受自然灾害(地震、洪水)影响。

1.2 可用区(Availability Zone)与地域(Region)的关系

在云原生环境中,地域(Region)和可用区(Availability Zone,AZ)是故障域划分的标准模型。两者之间的关系可以用下表清晰说明:

维度 地域(Region) 可用区(AZ)
定义 独立的地理区域,包含多个可用区 地域内独立的物理位置,拥有独立的电力、冷却和网络
故障隔离范围 跨地域故障极少发生(自然灾害级别) 单 AZ 故障不影响其他 AZ
网络延迟 跨地域延迟较高(10-100ms+) 同地域内 AZ 间延迟极低(1-2ms)
典型用途 数据主权、全球部署、异地容灾 高可用架构、负载均衡、故障转移
K8s 映射 多集群联邦(Multi-Cluster Federation) 节点标签 + Pod 拓扑分布约束

下图展示了 Region 与 AZ 的层级关系以及故障域的隔离边界:

地域(Region)与可用区(AZ)故障域层级 地域(Region)— 故障域边界:地理区域 可用区 A 独立电力 / 冷却 / 网络 K8s Node 组 K8s Node 组 K8s Node 组 可用区 B 独立电力 / 冷却 / 网络 K8s Node 组 K8s Node 组 K8s Node 组 可用区 C 独立电力 / 冷却 / 网络 K8s Node 组 K8s Node 组 K8s Node 组 故障域隔离:单 AZ 故障不影响其他 AZ;跨 Region 故障极少发生

1.3 故障域在 K8s 中的重要性

Kubernetes 作为容器编排平台,其核心价值之一就是通过故障域感知实现工作负载的高可用。如果集群不感知故障域,Pod 可能全部调度到同一个可用区或同一台物理机,一旦该故障域失效,整个应用将完全不可用。

常见误区:很多团队认为只要部署了多个 Pod 副本就实现了高可用。但如果所有副本都落在同一个故障域(例如同一个机架或同一个 AZ),那么该故障域的任何问题都会导致全部副本同时失效。故障域划分是真正高可用的前提。

故障域在 K8s 中的具体作用体现在以下方面:

K8s 能力 故障域关联 实际效果
Pod 拓扑分布约束
topologySpreadConstraints
按节点、可用区、地域等拓扑键均匀分布 Pod 避免单点故障导致全部 Pod 不可用
Pod 反亲和性
podAntiAffinity
强制同一应用的 Pod 分布在不同故障域 确保故障域隔离,提升可用性
节点亲和性
nodeAffinity
将关键工作负载调度到特定故障域的节点 满足合规、延迟或硬件要求
PV/PVC 本地卷调度 Pod 必须调度到数据所在的故障域节点 避免跨 AZ 访问导致性能下降
集群自动扩缩容
Cluster Autoscaler
按故障域维度触发节点组扩缩 保证各 AZ 资源均衡,避免单 AZ 过载

下图展示了在 K8s 集群中,通过拓扑分布约束将 3 个 Pod 副本均匀分布到 3 个不同可用区的调度策略:

K8s 跨可用区 Pod 分布(拓扑分布约束) 应用副本集 replicas: 3 K8s 调度器 可用区 A Pod-1 (Running) Node-1 可用区 B Pod-2 (Running) Node-2 可用区 C Pod-3 (Running) Node-3 拓扑分布约束:topologySpreadConstraints 确保 3 个 Pod 副本分别调度到 3 个不同可用区 任意一个可用区故障,仅影响 1/3 的 Pod,其余 2 个 Pod 继续提供服务

1.4 故障域划分的最佳实践

SRE 建议:在规划 K8s 集群时,至少使用 3 个可用区部署控制平面和数据平面。对于关键生产应用,确保每个工作负载的 Pod 副本数 ≥ 3,且通过拓扑分布约束强制跨 AZ 分布。

故障域划分的落地步骤:

  1. 识别故障边界:梳理物理机、机架、交换机、PDU、数据中心、云服务商 AZ/Region 等层级。
  2. 标记节点拓扑:通过节点标签(topology.kubernetes.io/zone、topology.kubernetes.io/region)将故障域信息注入 K8s。
  3. 配置调度策略:使用 topologySpreadConstraints 和 podAntiAffinity 约束 Pod 分布。
  4. 验证与监控:定期检查 Pod 分布是否均衡,监控各故障域的资源水位和健康状态。

以下是一个典型的拓扑分布约束配置示例:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  template:
    spec:
      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: topology.kubernetes.io/zone
          whenUnsatisfiable: DoNotSchedule
          labelSelector:
            matchLabels:
              app: web-app
      containers:
        - name: nginx
          image: nginx:1.25
关键参数说明:
maxSkew: 1 — 任意两个可用区之间的 Pod 数量差异不超过 1。
topologyKey: topology.kubernetes.io/zone — 按可用区拓扑键进行分布。
whenUnsatisfiable: DoNotSchedule — 无法满足约束时不调度,避免破坏故障域隔离。