4. 故障域模型:节点故障域、可用区故障域、区域故障域定义与标签
在云原生架构中,故障域(Failure Domain)是资源隔离与容灾调度的基本单元。Helm 应用交付的故障域隔离演练,首先需要建立清晰的故障域模型,并通过标准化的标签体系将模型映射到 Kubernetes 集群资源上。本章定义三层故障域模型:节点故障域、可用区故障域和区域故障域,并给出对应的标签规范。
4.1 三层故障域模型定义
故障域模型采用自底向上的三层结构,每一层对应不同的故障范围和隔离粒度:
| 层级 | 故障域名称 | 故障范围 | 典型故障场景 | 隔离粒度 |
|---|---|---|---|---|
| L1 | 节点故障域 | 单台物理机/虚拟机 | 硬件故障、内核崩溃、网络中断 | Pod 实例 |
| L2 | 可用区故障域 | 数据中心内独立机房/机架组 | 机架断电、交换机故障、制冷失效 | Deployment / StatefulSet |
| L3 | 区域故障域 | 跨数据中心/地理区域 | 自然灾害、骨干网中断、电力全停 | Service / Ingress / 全局负载均衡 |
设计原则:上层故障域包含下层故障域。一个区域包含多个可用区,一个可用区包含多个节点。Helm 应用在部署时,应确保同一服务的多个副本分布在不同的故障域层级上,避免单点故障导致服务完全不可用。
4.2 节点故障域(Node Failure Domain)
节点故障域是最小粒度的故障隔离单元,对应 Kubernetes 集群中的单个 Node。节点故障域的标签用于标识节点所属的物理位置和硬件属性,帮助调度器将 Pod 分散到不同节点上。
4.2.1 节点故障域标签规范
# 节点故障域标准标签(Kubernetes 节点标签)
topology.kubernetes.io/node-name: <node-name>
node.kubernetes.io/instance-type: <instance-type>
node.kubernetes.io/hostname: <hostname>
failure-domain.beta.kubernetes.io/node: <node-id>
4.2.2 节点故障域应用场景
- Pod 反亲和性:通过
podAntiAffinity将同一应用的多个副本调度到不同节点。 - 节点级故障模拟:演练时通过
kubectl cordon或kubectl drain模拟节点故障。 - 节点标签选择:使用
nodeSelector或nodeAffinity将特定工作负载绑定到指定节点。
4.3 可用区故障域(Availability Zone Failure Domain)
可用区故障域是中等粒度的故障隔离单元,通常对应数据中心内的独立机房、机架组或电力分区。同一可用区内的节点共享网络、电力和制冷基础设施,因此可用区故障会导致该区内所有节点不可用。
4.3.1 可用区故障域标签规范
# 可用区故障域标准标签
topology.kubernetes.io/zone: <zone-name>
failure-domain.beta.kubernetes.io/zone: <zone-name>
topology.kubernetes.io/region: <region-name> # 同时关联区域
4.3.2 可用区故障域应用场景
- 跨可用区部署:Helm values 中配置
topologySpreadConstraints实现 Pod 在可用区间的均匀分布。 - 可用区级故障演练:通过网络策略或节点池隔离模拟整个可用区离线。
- 存储卷绑定:确保 PVC 和 Pod 调度在同一可用区,避免跨区 IO 延迟。
4.4 区域故障域(Region Failure Domain)
区域故障域是最大粒度的故障隔离单元,对应地理区域或数据中心集群。区域故障通常由自然灾害、骨干网中断或大规模电力故障引起,影响范围覆盖整个区域内的所有可用区和节点。
4.4.1 区域故障域标签规范
# 区域故障域标准标签
topology.kubernetes.io/region: <region-name>
failure-domain.beta.kubernetes.io/region: <region-name>
topology.kubernetes.io/zone: <zone-name> # 子标签,关联可用区
4.4.2 区域故障域应用场景
- 多区域容灾:Helm 应用通过 Global Ingress 或 DNS 负载均衡实现跨区域流量切换。
- 区域级故障演练:模拟整个区域不可用,验证全局容灾策略和流量调度能力。
- 数据合规与就近接入:根据用户地理位置将流量路由到最近区域,降低延迟。
4.5 故障域模型关系图
下图展示三层故障域模型的层级关系与标签映射:
4.6 故障域标签在 Helm 中的应用
在 Helm Chart 的 values.yaml 中,通过配置拓扑分布约束(Topology Spread Constraints)和 Pod 反亲和性,将故障域模型转化为实际的调度策略:
# Helm values.yaml 示例:跨故障域部署配置
global:
topology:
region: "cn-east-1"
zones:
- "cn-east-1a"
- "cn-east-1b"
- "cn-east-1c"
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app: "{{ .Values.global.appName }}"
topologyKey: "topology.kubernetes.io/node" # 节点级分散
topologySpreadConstraints:
- maxSkew: 1
topologyKey: "topology.kubernetes.io/zone" # 可用区级均匀分布
whenUnsatisfiable: DoNotSchedule
- maxSkew: 2
topologyKey: "topology.kubernetes.io/region" # 区域级容灾
whenUnsatisfiable: ScheduleAnyway
关键配置解读:
topologyKey: "topology.kubernetes.io/node":确保同一应用的 Pod 分布在不同的节点上,应对节点故障。topologyKey: "topology.kubernetes.io/zone":确保 Pod 在可用区间均匀分布,应对可用区故障。topologyKey: "topology.kubernetes.io/region":确保 Pod 分布在多个区域,应对区域级灾难。maxSkew控制分布偏差,值越小分布越均匀。
4.7 故障域标签验证与演练准备
在开始故障域隔离演练前,需要验证集群节点的标签是否正确配置:
# 查看所有节点的故障域标签
kubectl get nodes -o custom-columns=\
NODE:.metadata.name,\
REGION:.metadata.labels.topology\.kubernetes\.io/region,\
ZONE:.metadata.labels.topology\.kubernetes\.io/zone,\
HOSTNAME:.metadata.labels.kubernetes\.io/hostname
# 检查特定可用区的节点
kubectl get nodes -l topology.kubernetes.io/zone=cn-east-1a
# 验证节点故障域标签完整性
kubectl describe node node-1 | grep -A5 "Labels"
常见问题:
- 节点缺少
topology.kubernetes.io/zone或topology.kubernetes.io/region标签,导致拓扑分布约束无法生效。 - 同一可用区内节点标签不一致,造成调度器误判故障域边界。
- 跨区域部署时,区域标签拼写错误(如大小写不一致),导致 Pod 无法正确分布。
4.8 故障域模型与演练场景映射
下表将三层故障域模型与演练场景进行映射,帮助设计针对性的故障注入测试:
| 故障域层级 | 演练场景 | 故障注入方式 | 预期验证目标 |
|---|---|---|---|
| 节点故障域 | 单节点宕机 | kubectl cordon && kubectl drain |
Pod 自动迁移到其他节点,服务不中断 |
| 可用区故障域 | 整可用区离线 | 网络策略隔离 / 节点池缩容 | 流量切换到其他可用区,RTO < 30s |
| 区域故障域 | 区域级网络中断 | Global Ingress 路由规则变更 | DNS 切换至备用区域,RPO < 5min |
通过本章定义的故障域模型和标签体系,Helm 应用交付能够实现精细化的故障隔离调度,为后续的故障注入演练和看板监控提供标准化的数据基础。