4. OPA/Gatekeeper入门:安装Gatekeeper、创建第一个ConstraintTemplate、创建第一个Constraint

在Kubernetes集群中实施策略即代码(Policy as Code),OPA/Gatekeeper是目前最成熟、社区最广泛采用的方案。本章将带你从零开始:安装Gatekeeper、理解核心概念、编写第一个ConstraintTemplate和Constraint,为后续构建资源配额模型打下基础。

4.1 OPA/Gatekeeper核心概念

Gatekeeper是Kubernetes的准入控制器(Admission Controller),它基于OPA(Open Policy Agent)引擎,允许用户通过声明式配置定义策略,在资源创建或更新时进行校验和拦截。其核心组件包括:

组件 角色 说明
OPA引擎 策略决策引擎 执行Rego策略语言编写的规则,返回allow/deny决策
Gatekeeper Webhook K8s准入控制器 拦截API请求,调用OPA引擎进行策略校验
ConstraintTemplate 策略模板 定义策略逻辑(Rego代码)和参数schema,是策略的“类”
Constraint 策略实例 引用ConstraintTemplate并传入具体参数,是策略的“对象”
关键理解:ConstraintTemplate ≈ 策略的“蓝图”,Constraint ≈ 策略的“具体执行规则”。一个Template可以被多个Constraint复用,每个Constraint可以配置不同的参数(如不同的资源配额阈值)。

4.2 安装Gatekeeper

推荐使用Helm Chart进行安装,版本兼容性请参考官方文档。以下为安装步骤:

  1. 添加Helm仓库
    helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts
    helm repo update
  2. 安装Gatekeeper
    helm install gatekeeper/gatekeeper --name-template=gatekeeper \
      --namespace gatekeeper-system --create-namespace
  3. 验证安装
    kubectl get pods -n gatekeeper-system
    # 预期输出:gatekeeper-audit-xxx、gatekeeper-controller-manager-xxx 等Pod处于Running状态
安装后关键检查项:
  • 确认gatekeeper-system命名空间下所有Pod运行正常
  • 确认ValidatingWebhookConfiguration已创建:kubectl get validatingwebhookconfiguration
  • 确认ConstraintTemplate CRD已注册:kubectl get crd | grep constraint

4.3 创建第一个ConstraintTemplate

ConstraintTemplate使用Rego语言编写策略逻辑,并定义可配置的参数。以下示例创建一个“禁止使用latest镜像标签”的策略模板:

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

        violation[{"msg": msg}] {
          container := input.review.object.spec.containers[_]
          tag := container.image
          # 检查镜像标签是否在禁止列表中
          disallowed_tags := object.get(input.parameters, "tags", [])
          any_tag_in_list(tag, disallowed_tags)
          msg := sprintf("镜像 %v 使用了禁止的标签: %v", [container.image, disallowed_tags])
        }

        any_tag_in_list(tag, tags) {
          t := tags[_]
          contains(tag, t)
        }
Rego编写要点:
  • violation[{"msg": msg}] 是策略入口,当条件满足时产生违规消息
  • input.review 是准入请求的完整对象
  • input.parameters 是Constraint中传入的参数
  • Rego是声明式语言,_ 表示通配符,[_] 遍历数组

4.4 创建第一个Constraint

Constraint引用上面创建的Template,并传入具体参数:

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sDisallowedTags
metadata:
  name: disallow-latest-tag
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]
    namespaces:
      - "production"
  parameters:
    tags:
      - "latest"
      - "dev"

上述Constraint的含义:

  • match:定义策略生效范围——仅对production命名空间下的Pod资源生效
  • parameters:传入禁止的标签列表,包含latest和dev

4.5 策略生效流程与验证

下图展示了Gatekeeper从安装到策略拦截的完整工作流:

Gatekeeper策略生效流程 用户/kubectl API Server Gatekeeper Webhook OPA引擎 ConstraintTemplate Constraint 创建Pod 准入请求 allow/deny 准入响应 流程说明: 1. 用户创建Pod 2. API Server触发准入 3. Gatekeeper调用OPA 4. OPA匹配Constraint

4.6 测试策略效果

创建上述Constraint后,尝试在production命名空间下创建一个使用latest标签的Pod:

kubectl create ns production
kubectl run test-pod --image=nginx:latest -n production
# 预期输出:Error from server (Forbidden): admission webhook "validation.gatekeeper.sh" denied the request:
# 镜像 nginx:latest 使用了禁止的标签: ["latest","dev"]

使用合规的镜像标签则可以通过:

kubectl run test-pod --image=nginx:1.25 -n production
# 预期输出:pod/test-pod created
验证清单:
  • ✅ Gatekeeper安装成功,Pod运行正常
  • ✅ ConstraintTemplate已注册(kubectl get constrainttemplates)
  • ✅ Constraint已创建(kubectl get constraints)
  • ✅ 违规请求被正确拦截,合规请求通过
  • ✅ 审计日志可查(kubectl logs -n gatekeeper-system -l gatekeeper.sh/operation=audit)

4.7 本章小结