4. 故障域模型:单AZ故障、跨AZ冗余、机架级故障、物理区域隔离

在Kubernetes集群中,故障域(Failure Domain)是划分资源隔离边界的基础单元。OPA策略需要精确验证集群是否按照预期的故障域模型进行调度与约束。本节将四种核心故障域模型进行结构化拆解,并给出对应的OPA策略测试边界条件。

4.1 故障域模型对比总览

故障域模型 隔离粒度 典型标签键 OPA关注点
单AZ故障 可用区(Availability Zone) topology.kubernetes.io/zone Pod是否全部集中在同一AZ
跨AZ冗余 可用区(跨多个AZ) topology.kubernetes.io/zone 工作负载副本是否分布在≥2个AZ
机架级故障 物理机架(Rack) topology.kubernetes.io/rack 同一机架是否承载过多关键Pod
物理区域隔离 数据中心/物理站点 topology.kubernetes.io/region 跨站点流量与数据合规边界
策略测试要点: 每种故障域模型在OPA中对应不同的input路径与data查询模式。测试用例必须覆盖“违反约束”与“合规通过”两种状态,并验证边界值(如AZ数量=1、副本数=2等)。

4.2 单AZ故障模型与OPA验证

单AZ故障模型假设整个可用区不可用。OPA策略应确保关键工作负载不将所有副本部署在同一个AZ内。测试边界条件包括:

  • 边界1: 当集群只有一个AZ标签的节点时,策略应允许调度(无法跨AZ)。
  • 边界2: 当副本数=1且节点分布在多个AZ时,策略应允许(单副本无法跨AZ)。
  • 边界3: 当副本数≥2且所有Pod的zone标签相同时,策略应拒绝。
# OPA策略片段:拒绝所有Pod在同一AZ
deny[msg] {
    pods := input.review.object.spec.template.spec.containers
    zones := {zone | some i; zone := input.review.object.spec.template.spec.nodeSelector["topology.kubernetes.io/zone"]}
    count(zones) == 1
    msg := sprintf("所有Pod集中在同一AZ: %v", [zones])
}
测试建议: 使用mock数据构造一个包含3个节点、2个AZ的集群,分别测试Pod分布在1个AZ和2个AZ的场景。断言deny规则在跨AZ时不应触发。

4.3 跨AZ冗余模型与OPA验证

跨AZ冗余要求工作负载的副本必须分布在至少两个不同的可用区。这是生产环境中最常见的故障域策略。OPA测试需要覆盖以下边界:

  • 边界1: 副本数=2且分布在2个不同AZ → 合规。
  • 边界2: 副本数=3且分布在2个不同AZ → 合规(允许部分AZ承载多个副本)。
  • 边界3: 副本数=2且分布在1个AZ → 违规。
  • 边界4: 副本数=1且分布在1个AZ → 策略应允许(单副本无法跨AZ)。
常见陷阱: 跨AZ冗余策略容易忽略“单副本”场景。如果策略强制要求副本数≥2且跨AZ,则单副本Deployment会被拒绝,导致开发环境无法部署。建议在策略中加入count(replicas) < 2豁免条件。
# OPA策略片段:跨AZ冗余检查(含单副本豁免)
deny[msg] {
    replicas := input.review.object.spec.replicas
    replicas >= 2
    zones := {zone | some i; input.review.object.spec.template.spec.nodeSelector["topology.kubernetes.io/zone"]}
    count(zones) < 2
    msg := sprintf("副本数=%d,但仅分布在%d个AZ,需要至少2个AZ", [replicas, count(zones)])
}

4.4 机架级故障模型与OPA验证

机架级故障模型关注物理机架的单点失效风险。在超大规模集群中,同一机架的网络交换机或电源故障可能导致大量Pod同时离线。OPA策略应限制同一机架上关键工作负载的Pod数量。

测试场景 机架标签分布 预期结果
单机架承载3个Pod rack-01: 3个Pod 违规(超过阈值2)
双机架各承载2个Pod rack-01: 2个, rack-02: 2个 合规
单机架承载2个Pod rack-01: 2个 合规(等于阈值)
单机架承载1个Pod rack-01: 1个 合规
# OPA策略片段:机架级Pod数量限制(阈值=2)
deny[msg] {
    rack_pods := {rack: count(pods) |
        some pod in input.review.object.spec.template.spec.containers
        rack := pod.nodeSelector["topology.kubernetes.io/rack"]
        pods := [pod]
    }
    some rack, count
    rack_pods[rack] == count
    count > 2
    msg := sprintf("机架 %v 承载 %d 个Pod,超过阈值2", [rack, count])
}
边界条件: 当集群中所有节点都属于同一个机架时(如小型开发集群),策略应允许调度,否则无法部署任何工作负载。建议在策略中增加count(distinct_racks) < 2豁免。

4.5 物理区域隔离模型与OPA验证

物理区域隔离通常用于跨数据中心或跨地域部署场景。OPA策略需要验证工作负载是否被限制在指定的物理区域内,同时禁止跨区域的数据访问。测试边界包括:

  • 边界1: Pod的region标签必须匹配命名空间注解中声明的允许区域。
  • 边界2: 跨区域Service的externalName引用必须被拒绝。
  • 边界3: 允许区域列表为空时,策略应拒绝所有Pod(安全默认)。
  • 边界4: 允许区域列表包含通配符*时,策略应允许所有区域。
# OPA策略片段:物理区域隔离检查
deny[msg] {
    allowed_regions := data.namespaces[input.review.object.metadata.namespace].allowed_regions
    pod_region := input.review.object.spec.template.spec.nodeSelector["topology.kubernetes.io/region"]
    not allowed_regions[pod_region]
    msg := sprintf("Pod区域 %v 不在命名空间允许区域 %v 中", [pod_region, allowed_regions])
}
测试数据构造: 创建两个命名空间prod-cn(允许区域: cn-east, cn-west)和prod-eu(允许区域: eu-west)。分别测试Pod部署在允许区域和禁止区域时的策略响应。

4.6 故障域模型综合SVG架构图

下图展示了四种故障域模型在Kubernetes集群中的层级关系与OPA策略作用点:

故障域模型层级与OPA策略作用点 物理区域隔离(Region) 标签: topology.kubernetes.io/region OPA: 验证Pod region ∈ 命名空间允许区域列表 可用区(AZ) 标签: topology.kubernetes.io/zone OPA: 单AZ故障检查 + 跨AZ冗余验证(副本数≥2时需≥2个AZ) 机架(Rack) 标签: topology.kubernetes.io/rack OPA: 限制同一机架关键Pod数量(阈值可配置,默认2) 节点(Node) 标签: kubernetes.io/hostname OPA: 节点级亲和性/反亲和性策略(与故障域模型联动) 策略测试边界 单AZ/跨AZ/机架阈值/区域白名单

4.7 故障域模型OPA测试用例设计

针对上述四种模型,设计以下OPA测试用例矩阵,确保边界条件全覆盖:

测试ID 故障域模型 输入条件 期望结果
FD-001 单AZ故障 副本数=3,所有Pod zone=cn-east-1 拒绝
FD-002 单AZ故障 副本数=1,Pod zone=cn-east-1 允许(单副本豁免)
FD-003 跨AZ冗余 副本数=2,zone分布: cn-east-1, cn-east-2 允许
FD-004 跨AZ冗余 副本数=2,zone分布: cn-east-1, cn-east-1 拒绝
FD-005 机架级故障 rack-01承载3个Pod,阈值=2 拒绝
FD-006 机架级故障 rack-01承载2个Pod,阈值=2 允许
FD-007 物理区域隔离 命名空间允许区域: [cn-east],Pod region=cn-west 拒绝
FD-008 物理区域隔离 命名空间允许区域: [*],Pod region=eu-west 允许
边界条件提醒: 测试用例FD-002和FD-006是容易被忽略的边界场景。单副本Pod无法跨AZ,单机架集群无法跨机架。OPA策略必须包含count(replicas) < 2或count(distinct_racks) < 2的豁免逻辑,否则会导致小规模集群无法部署任何工作负载。

4.8 故障域模型OPA测试执行流程

以下SVG图展示了从策略定义到测试执行的完整流程:

故障域模型OPA测试执行流程 1. 定义故障域策略 rego文件 + 规则 2. 构造测试数据 mock节点/Pod/命名空间 3. 执行OPA测试 opa test -v 4. 验证 通过/失败 失败 → 调整策略/数据 测试用例清单(覆盖四种故障域模型) • FD-001 ~ FD-002: 单AZ故障模型(含单副本豁免) • FD-003 ~ FD-004: 跨AZ冗余模型(副本数≥2时跨AZ) • FD-005 ~ FD-006: 机架级故障模型(阈值边界测试) • FD-007 ~ FD-008: 物理区域隔离模型(白名单与通配符)
测试执行建议: 使用opa test --coverage命令生成测试覆盖率报告,确保每条策略规则都被至少一个正向用例和一个反向用例覆盖。对于故障域模型,特别关注count()聚合函数和some迭代的边界条件。