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 的层级关系以及故障域的隔离边界:
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 个不同可用区的调度策略:
1.4 故障域划分的最佳实践
SRE 建议:在规划 K8s 集群时,至少使用 3 个可用区部署控制平面和数据平面。对于关键生产应用,确保每个工作负载的 Pod 副本数 ≥ 3,且通过拓扑分布约束强制跨 AZ 分布。
故障域划分的落地步骤:
- 识别故障边界:梳理物理机、机架、交换机、PDU、数据中心、云服务商 AZ/Region 等层级。
- 标记节点拓扑:通过节点标签(
topology.kubernetes.io/zone、topology.kubernetes.io/region)将故障域信息注入 K8s。 - 配置调度策略:使用
topologySpreadConstraints和podAntiAffinity约束 Pod 分布。 - 验证与监控:定期检查 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 — 无法满足约束时不调度,避免破坏故障域隔离。