3. Gatekeeper 概述:OPA/Gatekeeper 架构、约束模板与约束概念、安装与部署

3.1 OPA 与 Gatekeeper 的定位

在云原生灾备准入策略评审中,Kubernetes 原生 RBAC 与 Admission Webhook 只能提供基础的“允许/拒绝”判断,无法表达复杂的策略逻辑。Open Policy Agent(OPA)与 Gatekeeper 的组合填补了这一空白:OPA 提供通用的策略引擎,Gatekeeper 将其封装为 Kubernetes 原生的准入控制器。

组件 角色 在灾备准入中的价值
OPA 通用策略引擎(Rego 语言) 定义灾备资源(如 Velero 备份、VolumeSnapshot)的合规规则
Gatekeeper Kubernetes 原生准入 Webhook + 策略控制器 将 OPA 策略注入集群,拦截并验证灾备资源的创建/更新请求
ConstraintTemplate 策略模板(CRD) 封装 Rego 逻辑,定义灾备策略的通用骨架
Constraint 策略实例(CR) 为特定命名空间或资源类型设定具体的灾备约束参数
关键理解:OPA 是策略引擎的“大脑”,Gatekeeper 是“手脚”,ConstraintTemplate 是“模具”,Constraint 是“成品”。在灾备场景中,这四层共同确保每一次备份策略变更都经过合规校验。

3.2 OPA/Gatekeeper 架构

Gatekeeper 以 Deployment 形式运行在集群中,监听 AdmissionReview 请求,并通过 OPA 引擎执行 Rego 策略。下图展示了请求从 API Server 到策略决策的完整路径:

Gatekeeper 准入控制架构(灾备场景) Kubernetes API Server Gatekeeper Webhook OPA 策略引擎 ConstraintTemplate Constraint kubectl / 客户端 创建/更新灾备资源 AdmissionReview Rego 查询 加载模板 读取参数 允许/拒绝 灾备资源示例 Velero Backup VolumeSnapshot CronJob 备份调度 StorageClass 策略
架构要点:Gatekeeper 作为动态准入 Webhook,在资源持久化之前拦截请求。OPA 引擎根据 ConstraintTemplate 中定义的 Rego 规则和 Constraint 中传入的参数,返回 true(允许)或 false(拒绝)。灾备场景下,这一机制可防止未授权的备份策略变更、不合规的存储类选择或缺少必要标签的备份任务。

3.3 约束模板(ConstraintTemplate)与约束(Constraint)

ConstraintTemplate 和 Constraint 是 Gatekeeper 策略体系的两大核心 CRD。理解它们的区别是编写灾备准入策略的基础。

维度 ConstraintTemplate Constraint
类型 Cluster-scoped CRD Cluster-scoped CR(实例)
职责 定义 Rego 策略逻辑与参数 schema 为模板提供具体参数值并作用于目标资源
灾备示例 检查备份资源是否包含 backup-retention 标签 要求 production 命名空间的备份保留期 ≥ 30 天
复用性 一个模板可被多个 Constraint 引用 每个 Constraint 绑定一个模板
更新影响 修改模板会影响所有引用它的 Constraint 修改 Constraint 只影响当前策略实例

以下是一个灾备场景的 ConstraintTemplate 示例,用于验证 Velero Backup 资源是否包含必需的标签:

apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
  name: k8srequiredbackuplabels
spec:
  crd:
    spec:
      names:
        kind: K8sRequiredBackupLabels
      validation:
        openAPIV3Schema:
          type: object
          properties:
            labels:
              type: array
              items:
                type: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8srequiredbackuplabels

        violation[{"msg": msg}] {
          input.review.object.kind == "Backup"
          input.review.object.apiVersion == "velero.io/v1"
          provided_labels := {label | input.review.object.metadata.labels[label]}
          required_labels := {label | label := input.parameters.labels[_]}
          missing_labels := required_labels - provided_labels
          count(missing_labels) > 0
          msg := sprintf("缺少必需的备份标签: %v", [missing_labels])
        }

对应的 Constraint 实例,为 production 命名空间设定具体标签要求:

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredBackupLabels
metadata:
  name: prod-backup-label-constraint
spec:
  match:
    kinds:
      - apiGroups: ["velero.io"]
        kinds: ["Backup"]
    namespaces: ["production"]
  parameters:
    labels:
      - "backup-retention"
      - "backup-schedule"
常见陷阱:ConstraintTemplate 中的 Rego 代码必须严格匹配目标资源的 GVK(Group/Version/Kind)。灾备资源(如 Velero Backup)的 apiVersion 可能随版本变化,务必在 Rego 中正确声明,否则策略会静默失效。

3.4 Gatekeeper 安装与部署

Gatekeeper 的部署方式主要有两种:Helm Chart 和静态 YAML。在生产环境中推荐使用 Helm,便于版本管理和参数定制。

3.4.1 使用 Helm 安装

# 添加 Gatekeeper Helm 仓库
helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts

# 更新仓库
helm repo update

# 安装 Gatekeeper(默认命名空间 gatekeeper-system)
helm install gatekeeper/gatekeeper \
  --name-template gatekeeper \
  --namespace gatekeeper-system \
  --create-namespace \
  --set replicas=2 \
  --set auditInterval=60 \
  --set logLevel=INFO

3.4.2 使用静态 YAML 安装

# 下载最新 release 的 YAML
kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/deploy/gatekeeper.yaml

3.4.3 验证安装

安装完成后,检查关键组件是否正常运行:

# 查看 Pod 状态
kubectl get pods -n gatekeeper-system

# 预期输出示例:
# NAME                                             READY   STATUS    RESTARTS   AGE
# gatekeeper-audit-5d8f9c6b7f-abc12                1/1     Running   0          2m
# gatekeeper-controller-manager-7f9c8d6e5-xyz34    1/1     Running   0          2m

# 查看 CRD 是否注册
kubectl get crd | grep gatekeeper

# 预期输出包含:
# constrainttemplates.templates.gatekeeper.sh
# constraints.constraints.gatekeeper.sh
# configs.config.gatekeeper.sh
组件 功能 灾备相关配置建议
gatekeeper-controller-manager 处理准入请求,执行 Rego 策略 生产环境至少 2 副本;灾备集群建议 3 副本
gatekeeper-audit 定期审计已有资源,标记违反策略的对象 设置 auditInterval=60(秒),及时发现存量违规
gatekeeper-webhook 注册 ValidatingWebhookConfiguration 灾备场景建议开启 failurePolicy=Fail,防止策略绕过
灾备部署建议:在灾备集群中部署 Gatekeeper 时,建议将 auditFromCache 设置为 true,减少对 API Server 的重复查询。同时,为 Gatekeeper 组件配置 PodDisruptionBudget,确保灾备切换期间策略引擎持续可用。

3.5 本章小结