3. 故障域概念与设计
3.1 故障域定义
故障域(Failure Domain)是平台工程中隔离故障影响范围的基本单位。在 Kubernetes 和 IDP 环境中,故障域通常分为三个层级:可用区(Zone)、集群(Cluster)和节点(Node)。每个层级对应不同的物理或逻辑隔离边界,决定了故障传播的半径。
| 故障域层级 | 定义 | 典型故障场景 | 隔离粒度 |
|---|---|---|---|
| 可用区(Zone) | 同一地域内独立的数据中心或电力/网络单元 | 区域电力中断、光纤断裂、AZ 级网络故障 | 物理数据中心级 |
| 集群(Cluster) | 一组控制面和数据面节点组成的 Kubernetes 集群 | API Server 过载、etcd 脑裂、集群证书过期 | 逻辑控制面级 |
| 节点(Node) | 单个物理机或虚拟机,运行 kubelet 和容器 | 磁盘故障、OOM、内核 Panic、硬件老化 | 单机级 |
关键原则:故障域层级越高,故障影响范围越大,恢复时间越长。IDP 设计应优先保证跨可用区冗余,其次才是集群内节点级反亲和。
3.2 IDP 中的故障域映射策略
平台工程 IDP 需要将抽象的工作负载(Helm Release、微服务、中间件)映射到底层故障域。映射策略决定了当某个故障域失效时,哪些工作负载会同时受损。
- Zone → Cluster 映射:每个可用区部署一个或多个 Kubernetes 集群,集群内的节点全部位于同一可用区。这种映射简单直接,但跨 AZ 流量需要集群间网络打通。
- Cluster → Node 映射:集群内的节点按可用区打上
topology.kubernetes.io/zone标签,通过 NodeAffinity 和 PodAntiAffinity 控制 Pod 分布。 - Helm Release → 故障域:在 Helm values 中声明
topologySpreadConstraints和affinity规则,将 Release 内的 Pod 分散到不同故障域。
实践建议:在 IDP 的 Helm Chart 模板中,将故障域配置抽象为全局变量
.Values.global.topology.failureDomain,避免在每个子 Chart 中重复定义。
3.3 反亲和性设计原则
反亲和性(Anti-Affinity)是故障域隔离的核心实现手段。在 Helm Chart 中通过 podAntiAffinity 和 topologySpreadConstraints 控制 Pod 分布,确保同一工作负载的多个副本不会落在同一故障域内。
3.3.1 反亲和性策略对比
| 策略类型 | Kubernetes 资源 | 作用范围 | 适用场景 |
|---|---|---|---|
| PodAntiAffinity | spec.affinity.podAntiAffinity |
节点级(hostname) | 严格禁止同节点部署两个相同副本 |
| TopologySpreadConstraints | spec.topologySpreadConstraints |
Zone / Region / 自定义拓扑 | 跨可用区均匀分布,容忍部分倾斜 |
| NodeAntiAffinity | spec.affinity.nodeAntiAffinity |
节点标签选择器 | 避免部署到特定硬件或网络属性的节点 |
3.3.2 Helm 模板中的反亲和配置示例
# values.yaml
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app.kubernetes.io/name
operator: In
values:
- {{ .Values.nameOverride | default .Chart.Name }}
topologyKey: kubernetes.io/hostname
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
labelSelector:
matchLabels:
app.kubernetes.io/name: {{ .Values.nameOverride | default .Chart.Name }}
避坑提示:
requiredDuringSchedulingIgnoredDuringExecution 是硬约束,当集群节点数少于副本数时会导致 Pod 无法调度。容量突增场景建议使用 preferredDuringSchedulingIgnoredDuringExecution 或配合 topologySpreadConstraints 的 ScheduleAnyway 模式。
3.3.3 反亲和性设计原则总结
- 分层隔离:先保证跨可用区(Zone)分布,再保证跨节点(Host)分布,最后考虑跨机架或跨交换机。
- 软硬结合:核心服务(etcd、API Server)使用硬反亲和;普通微服务使用软反亲和 + TopologySpreadConstraints。
- 容量感知:反亲和规则必须与集群容量规划联动,避免因约束过严导致资源碎片。
- Helm 参数化:将反亲和策略暴露为 values 参数,允许运维人员在突增时动态调整约束强度。
3.4 故障域与 Helm 水位预测的关联
在容量突增场景下,故障域设计直接影响 Helm 水位预测的准确性。如果反亲和约束过于严格,突增时 Pod 可能因找不到满足约束的节点而处于 Pending 状态,导致实际水位低于预期。因此,水位预测模型必须将故障域约束作为输入参数,计算有效可调度容量。
核心公式:有效可调度容量 = 集群总容量 − 故障域约束损耗 − 已有资源占用。其中故障域约束损耗 = Σ(每个故障域内因反亲和规则无法调度的资源量)。