3. 故障域隔离原理:故障域定义、物理/逻辑故障域、跨可用区/集群的隔离策略
3.1 故障域定义与核心概念
故障域(Fault Domain)是分布式系统中一组共享同一故障风险组件的资源集合。当该集合内的关键组件(如电源、网络交换机、物理服务器或可用区)发生故障时,集合内的所有资源将同时受到影响。故障域隔离的目标是通过将不同租户或工作负载分散到独立的故障域中,确保单一故障事件不会导致多个租户同时不可用。
关键原则: 故障域边界 = 故障影响范围边界。一个租户的故障不应跨越其所属的故障域边界影响到其他租户。
| 维度 | 定义 | 典型粒度 | 故障影响范围 |
|---|---|---|---|
| 物理故障域 | 基于硬件物理边界划分的故障隔离单元 | 机架、电源域、网络叶子交换机、数据中心 | 物理设备故障导致该域内所有计算/存储实例不可用 |
| 逻辑故障域 | 基于软件抽象层划分的逻辑隔离单元 | Kubernetes Namespace、虚拟网络、存储池、集群 | 软件配置错误或逻辑组件故障影响该逻辑域内资源 |
| 跨可用区故障域 | 跨数据中心可用区(AZ)的物理隔离 | 可用区(AZ)、Region | 单个AZ整体故障不影响其他AZ内的租户 |
| 跨集群故障域 | 跨Kubernetes集群或资源池的隔离 | 集群、联邦集群、资源池 | 单个集群控制面或数据面故障不影响其他集群 |
3.2 物理故障域 vs 逻辑故障域
物理故障域提供硬件级别的硬隔离,逻辑故障域提供软件层面的软隔离。在多租户场景中,两者需要组合使用才能实现完整的故障隔离效果。
最佳实践: 物理故障域决定“故障不会扩散到哪里”,逻辑故障域决定“租户被限制在哪里”。两者应形成正交映射关系:一个逻辑故障域(如Namespace)应尽量分布在多个物理故障域上,避免单点物理故障导致整个逻辑域不可用。
3.3 跨可用区(AZ)隔离策略
跨可用区隔离是云原生架构中最基础的故障域隔离手段。每个可用区由独立的电力、冷却和网络设施支撑,AZ之间通过低延迟光纤互联。多租户平台应将租户的工作负载均匀分布在多个AZ中,并确保每个租户至少跨越2个AZ。
注意: 跨AZ流量会产生额外的网络延迟和带宽成本。在OPA策略中,应通过标签约束强制要求关键租户的工作负载必须分布在至少2个AZ上,同时允许非关键租户仅在单AZ部署以降低成本。
3.4 跨集群隔离策略
当单个Kubernetes集群的规模或故障半径无法满足租户隔离要求时,需要引入跨集群隔离。每个集群拥有独立的控制面(API Server、etcd、Controller Manager),集群间的故障完全隔离。
| 隔离层级 | 故障半径 | 适用场景 | OPA策略示例 |
|---|---|---|---|
| 单集群内Namespace隔离 | Namespace内资源故障 | 开发/测试环境、低风险租户 | 禁止跨Namespace访问Service |
| 单集群内Node/Zone隔离 | 物理节点或可用区故障 | 生产环境、中等风险租户 | 强制PodAntiAffinity + topologySpreadConstraints |
| 跨集群隔离 | 整个集群控制面或数据面故障 | 金融、医疗等合规要求高的租户 | 禁止跨集群调度,每个租户独占集群 |
| 联邦集群隔离 | 跨Region/跨云故障 | 全球部署、灾难恢复 | 通过PlacementPolicy约束租户分布 |
3.5 OPA策略中的故障域约束实现
在OPA/Rego策略中,故障域隔离通过以下方式实现:
- 标签约束: 强制Pod必须带有
failure-domain.beta.kubernetes.io/zone标签,且值必须属于允许的AZ列表。 - 拓扑分布约束: 使用
topologySpreadConstraints确保同一租户的Pod在AZ间均匀分布。 - PodAntiAffinity: 强制同一租户的Pod不能调度到同一物理节点或同一可用区。
- 集群选择器: 通过
clusterSelector限制租户只能部署到指定的集群集合。
# OPA Rego 策略示例:强制跨AZ分布
package kubernetes.admission
violation[msg] {
input.request.kind.kind == "Pod"
input.request.operation == "CREATE"
# 获取租户标签
tenant := input.request.object.metadata.labels["tenant"]
# 检查是否指定了AZ标签
zone := input.request.object.spec.topologySpreadConstraints[_]
zone.maxSkew > 1
zone.whenUnsatisfiable == "DoNotSchedule"
zone.topologyKey == "topology.kubernetes.io/zone"
# 如果租户是critical级别,必须至少跨越2个AZ
tenant == "critical-tenant"
count({c | c := input.request.object.spec.topologySpreadConstraints[_];
c.topologyKey == "topology.kubernetes.io/zone"}) < 2
msg := sprintf("Critical tenant %v must have at least 2 zone topology spread constraints", [tenant])
}
关键指标: 故障域隔离覆盖率 = (已配置跨AZ/跨集群策略的租户数) / (总租户数) × 100%。目标值应 ≥ 95%。
3.6 故障域隔离的OPA指标采集点
在演练场景中,OPA需要采集以下与故障域隔离相关的指标:
| 指标名称 | 类型 | 采集方式 | 告警阈值 |
|---|---|---|---|
fault_domain_violations_total |
Counter | OPA决策日志中提取violation事件 | > 0 即告警 |
tenant_az_distribution_skew |
Gauge | 定期扫描Pod分布,计算AZ间Pod数量标准差 | > 0.3 触发警告 |
single_az_tenant_count |
Gauge | 统计仅部署在1个AZ上的租户数量 | > 0 触发警告 |
cross_cluster_tenant_ratio |
Gauge | 跨集群部署的租户数 / 总租户数 | < 0.8 触发警告 |
fault_domain_recovery_time |
Histogram | 从故障发生到Pod在另一故障域恢复的时间 | P99 > 120s 告警 |
演练建议: 在故障域隔离演练中,建议先模拟单个AZ故障(如断开AZ-1的网络),观察OPA是否检测到单AZ租户的Pod全部不可用,并触发
single_az_tenant_count 告警。然后验证跨AZ租户的Pod是否自动迁移到其他AZ。