4. 故障域概念:可用区(AZ)、区域(Region)、节点故障域的定义与划分原则
在 Kubernetes 与 Helm 部署架构中,故障域(Failure Domain)是基础设施隔离的基本单位。正确划分故障域,能够确保控制平面与工作负载在物理或逻辑故障发生时,不会因单点失效而导致整个集群不可用。本节将系统定义三种核心故障域层级,并给出 Helm 部署中的划分原则。
4.1 故障域层级模型
Kubernetes 集群的故障域通常按物理与逻辑范围分为三个层级:节点(Node)、可用区(Availability Zone, AZ)、区域(Region)。下表对比了各层级的定义、故障范围与典型隔离粒度:
| 层级 | 定义 | 故障范围 | 隔离粒度 | Kubernetes 标签示例 |
|---|---|---|---|---|
| 节点(Node) | 单台物理机或虚拟机实例 | 硬件故障、OS 崩溃、内核 Panic | 单机 | kubernetes.io/hostname |
| 可用区(AZ) | 同一区域内独立的物理数据中心或机房 | 机架断电、网络汇聚层故障、制冷失效 | 机房级 | topology.kubernetes.io/zone |
| 区域(Region) | 地理上隔离的完整云服务区域 | 大规模自然灾害、区域网络中断 | 地理级 | topology.kubernetes.io/region |
关键认知:故障域层级越高,隔离范围越大,但跨域通信的延迟与成本也越高。Helm 部署时,应优先将控制平面组件跨 AZ 分布,而非跨 Region,以平衡可用性与性能。
4.2 故障域划分原则
在 Helm 部署架构中,故障域划分需遵循以下四项核心原则:
- 最小共享原则:同一故障域内的组件应共享尽可能少的物理资源(电源、网络、散热)。例如,同一 AZ 内的节点不应全部连接同一台 ToR 交换机。
- 反亲和原则:关键副本(如 etcd、kube-apiserver)必须调度到不同故障域。Helm 可通过
topologySpreadConstraints或podAntiAffinity实现。 - 控制平面隔离优先:控制平面组件(etcd、API Server、Controller Manager)应部署在独立的故障域集合中,与工作负载节点物理隔离,避免资源争抢与级联故障。
- DNS 依赖最小化:跨故障域的服务发现应避免强依赖中心化 DNS。Helm 部署时应启用
headless service或EndpointSlice,减少 DNS 查询成为故障扩散点。
4.3 故障域拓扑结构图
下图展示了标准的三层故障域拓扑,以及控制平面与工作负载在 AZ 间的分布策略:
4.4 节点故障域:物理机与虚拟化隔离
节点故障域是最小隔离单元。在裸金属或虚拟机环境中,节点故障域划分需关注以下维度:
- 硬件隔离:避免同一物理机上的多个 Pod 成为故障关联组。使用
kubernetes.io/hostname标签实现节点级反亲和。 - 网络隔离:节点应分属不同的 ToR 交换机或网络分段。Helm 部署时可通过
nodeSelector指定网络标签。 - 存储隔离:本地 SSD 或直通盘应仅挂载到单一节点,避免共享存储成为单点。
Helm 实践:在 values.yaml 中通过
topologySpreadConstraints 定义节点级分布策略:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app.kubernetes.io/component: control-plane
4.5 可用区(AZ)故障域:机房级冗余
可用区是同一 Region 内独立的物理数据中心,具备独立的电力、制冷和网络接入。AZ 故障域划分的核心原则:
- 至少 3 个 AZ:生产集群建议至少使用 3 个 AZ,确保 etcd 集群在任意 1 个 AZ 故障时仍能形成多数派(quorum)。
- 控制平面跨 AZ 分布:etcd 实例、API Server 实例应均匀分布在所有可用 AZ 中。
- 工作负载跨 AZ 分布:通过
topology.kubernetes.io/zone标签实现 Pod 跨 AZ 调度。 - DNS 本地化:CoreDNS 或 kube-dns 应在每个 AZ 内至少运行一个副本,避免跨 AZ DNS 查询增加延迟与故障面。
4.6 区域(Region)故障域:地理级容灾
区域故障域用于应对大规模灾难场景。跨 Region 部署通常用于容灾(Disaster Recovery)而非日常流量分担,因为跨 Region 延迟通常在 10ms~100ms 级别。划分原则:
| 场景 | 推荐策略 | Helm 配置要点 |
|---|---|---|
| 主备容灾 | 主 Region 承载全部流量,备 Region 冷备或温备 | Helm release 使用不同 kubeconfig,通过 CI/CD 切换 |
| 双活部署 | 两个 Region 同时承载流量,需全局负载均衡 | 使用 global.replicaCount 与 ingress.controller 多集群配置 |
| 控制平面隔离 | 每个 Region 拥有独立控制平面,不跨 Region 共享 etcd | Helm chart 中通过 .Values.global.region 区分配置 |
重要警告:切勿将 etcd 集群跨 Region 部署。跨 Region 网络延迟会导致 etcd 写入超时、心跳丢失,进而引发控制平面脑裂。etcd 集群必须限制在单个 Region 内。
4.7 故障域划分与 DNS 故障的关联
在 Helm 部署中,故障域划分直接影响 DNS 解析的可用性。以下是最常见的 DNS 故障场景与故障域划分的关系:
- 场景一:AZ 内 DNS 缓存失效 —— 如果 CoreDNS 仅部署在单一 AZ,该 AZ 故障将导致整个集群 DNS 解析中断。解决方案:每个 AZ 独立部署 CoreDNS 副本。
- 场景二:跨 AZ DNS 查询超时 —— 当 Pod 调度到 AZ-1,但 DNS 解析请求发送到 AZ-2 的 CoreDNS 时,跨 AZ 网络抖动可能导致查询失败。解决方案:使用
topologyKeys或nodeLocalDNS实现 DNS 本地优先。 - 场景三:Region 级 DNS 依赖 —— 如果集群依赖外部 Region 的 DNS 服务(如云厂商 Route53),Region 故障将导致服务发现全面瘫痪。解决方案:在集群内部署本地 DNS 缓存,并配置 fallback 策略。
下图展示了 DNS 故障域隔离的正确与错误部署对比:
4.8 控制平面隔离与故障域
控制平面隔离是故障域划分的最高优先级。etcd 集群作为 Kubernetes 的“大脑”,其故障域设计直接决定集群的可用性上限。以下是控制平面隔离的硬性要求:
| 组件 | 故障域要求 | 副本数 | Helm 配置示例 |
|---|---|---|---|
| etcd | 跨 3 个不同 AZ,每个 AZ 1 个实例 | 3 或 5 | etcd.replicaCount: 3etcd.antiAffinity: hard |
| kube-apiserver | 跨 2~3 个 AZ,与 etcd 同 AZ 优先 | 2 或 3 | apiserver.topologySpread: zone |
| kube-controller-manager | 跨 2 个 AZ,leader election 自动切换 | 2 | controllerManager.replicaCount: 2 |
| kube-scheduler | 跨 2 个 AZ,与 controller-manager 类似 | 2 | scheduler.replicaCount: 2 |
Helm 最佳实践:在 chart 的
values.yaml 中定义故障域配置模板,通过 .Values.global.failureDomain 统一管理:
global:
failureDomain:
region: us-east-1
zones:
- us-east-1a
- us-east-1b
- us-east-1c
controlPlane:
spread: zones
minReplicasPerZone: 1
dns:
localPerZone: true
replicaCountPerZone: 2
4.9 故障域划分的常见误区
- 误区一:AZ 数量越多越好 —— 超过 5 个 AZ 会增加 etcd 跨 AZ 同步延迟,通常 3 个 AZ 是最优平衡点。
- 误区二:节点故障域等同于 AZ 故障域 —— 节点故障仅影响单机,AZ 故障影响整个机房,两者的反亲和策略不同。
- 误区三:跨 Region 部署控制平面 —— 如 4.6 节所述,etcd 跨 Region 部署会导致严重的性能与一致性问题。
- 误区四:DNS 不需要故障域隔离 —— 许多故障案例表明,DNS 是集群中最容易被忽视的单点。务必为 CoreDNS 配置跨 AZ 部署与本地优先解析。