2. Kubernetes 基础回顾:Pod、Node、Namespace、Label 与 Selector 的核心概念
在深入 OPA Gatekeeper 的故障域划分策略之前,必须重新夯实 Kubernetes 最核心的五个抽象概念。这些概念不仅是集群调度的基础,更是后续编写约束规则、定义故障域标签、实现准入控制的直接操作对象。理解它们之间的层级关系与选择机制,是掌握 Gatekeeper 策略的前提。
2.1 核心对象层级关系
Kubernetes 集群的物理与逻辑结构可以抽象为以下三层:
- Node(节点):集群中的工作机器,可以是物理服务器或虚拟机。每个 Node 拥有独立的计算、存储和网络资源,是故障域的基本物理单元。
- Namespace(命名空间):虚拟集群划分,用于在同一物理集群内隔离资源组。不同 Namespace 中的资源名称可以重复,常用于多租户或环境隔离(如 dev、staging、prod)。
- Pod(容器组):Kubernetes 中最小的可部署计算单元,封装一个或多个容器。Pod 共享网络栈和存储卷,其调度位置直接决定了应用的实际故障域归属。
故障域视角: 在故障域划分场景中,Node 代表物理或虚拟故障边界(如机架、可用区),Namespace 代表逻辑故障边界(如业务线、环境),而 Pod 则是被约束的对象。Gatekeeper 的策略最终作用于 Pod 的创建请求,确保其被调度到符合故障域要求的 Node 上。
2.2 Pod:最小调度单元与故障域载体
Pod 是 Kubernetes 调度决策的直接对象。当用户通过 Deployment、StatefulSet 或直接创建 Pod 时,kube-scheduler 会根据一系列约束条件(如资源请求、亲和性规则、污点容忍)将 Pod 绑定到某个 Node 上。在故障域划分场景中,Pod 的以下属性至关重要:
| Pod 属性 | 故障域相关作用 | Gatekeeper 检查方式 |
|---|---|---|
spec.nodeName |
直接指定目标 Node(绕过调度器) | 禁止或限制直接指定,强制使用调度约束 |
spec.nodeSelector |
基于 Node Label 选择目标节点 | 验证 selector 是否包含故障域标签(如 topology.kubernetes.io/zone) |
spec.affinity.nodeAffinity |
更灵活的节点选择规则(required/preferred) | 检查 required 规则是否强制跨故障域分布 |
spec.topologySpreadConstraints |
跨拓扑域(如 zone、hostname)的 Pod 分布约束 | 验证是否配置了跨故障域的 maxSkew 限制 |
关键理解: Pod 本身不直接感知故障域,但它的调度属性决定了它最终落在哪个故障域中。Gatekeeper 的职责就是在 Pod 创建时,确保这些属性符合预定义的故障域策略。
2.3 Node:故障域的物理/逻辑边界
Node 是故障域划分的基石。每个 Node 通常带有描述其物理位置或逻辑分区的标签(Label),这些标签是 Gatekeeper 策略判断故障域归属的依据。常见的 Node 标签体系如下:
# 标准 Kubernetes 拓扑标签(推荐用于故障域划分)
topology.kubernetes.io/region: us-east-1 # 区域
topology.kubernetes.io/zone: us-east-1a # 可用区
# 自定义故障域标签(适用于机架、电源域等)
failure-domain.beta.kubernetes.io/region: us-east-1
failure-domain.beta.kubernetes.io/zone: us-east-1a
rack-id: rack-12 # 自定义机架标识
power-domain: pd-A # 自定义电源域
在 Gatekeeper 策略中,我们通常要求 Pod 的调度约束必须引用这些 Node 标签,从而确保 Pod 被分散到不同的故障域中。
2.4 Namespace:逻辑隔离与策略作用域
Namespace 在故障域划分中扮演两个角色:
- 策略作用域:Gatekeeper 的约束模板(ConstraintTemplate)和约束(Constraint)可以指定作用于哪些 Namespace。例如,只对
prodNamespace 中的 Pod 实施严格的跨可用区分布策略。 - 逻辑故障域:某些场景下,Namespace 本身代表一个逻辑故障域(如不同业务线),要求同一 Namespace 内的 Pod 必须调度到特定的 Node 集合上。
注意: Namespace 是逻辑概念,不直接对应物理故障。不要将 Namespace 隔离等同于物理故障域隔离。物理故障域必须通过 Node 标签和 Pod 调度约束来实现。
2.5 Label 与 Selector:策略匹配的核心机制
Label 是 Kubernetes 中用于标识和组织资源的键值对。Selector 则用于筛选具有特定 Label 的资源。在 Gatekeeper 的故障域策略中,Label 和 Selector 的配合使用贯穿始终:
- Node Label:标识 Node 所属的故障域(如
zone: az1)。 - Pod Label:标识 Pod 所属的应用或服务(如
app: frontend),用于在策略中区分不同应用。 - Namespace Label:标识 Namespace 的故障域要求(如
fault-domain-policy: strict),用于触发不同的 Gatekeeper 约束。
2.6 核心概念对比总结
| 概念 | 类型 | 故障域角色 | Gatekeeper 策略中的用途 |
|---|---|---|---|
| Pod | 工作负载 | 被调度的对象,故障域策略的最终执行单元 | 检查 Pod 的调度属性(nodeSelector、affinity、topologySpreadConstraints) |
| Node | 基础设施 | 物理/逻辑故障域的边界载体 | 通过 Node Label 定义故障域标识,作为 Pod 调度约束的匹配目标 |
| Namespace | 逻辑隔离 | 策略作用域与逻辑故障域 | 限定约束生效范围,或通过 Namespace Label 触发不同级别的策略 |
| Label | 元数据 | 标识资源所属的故障域、应用、环境 | 作为 Selector 的匹配依据,是策略规则中的核心匹配字段 |
| Selector | 匹配机制 | 将 Pod 与目标 Node/Namespace 关联 | 在 Gatekeeper 的 Rego 规则中,通过 input.review.object.spec.nodeSelector 等字段进行验证 |