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进行安装,版本兼容性请参考官方文档。以下为安装步骤:
- 添加Helm仓库
helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts helm repo update - 安装Gatekeeper
helm install gatekeeper/gatekeeper --name-template=gatekeeper \ --namespace gatekeeper-system --create-namespace - 验证安装
kubectl get pods -n gatekeeper-system # 预期输出:gatekeeper-audit-xxx、gatekeeper-controller-manager-xxx 等Pod处于Running状态
安装后关键检查项:
- 确认
gatekeeper-system命名空间下所有Pod运行正常 - 确认
ValidatingWebhookConfiguration已创建:kubectl get validatingwebhookconfiguration - 确认
ConstraintTemplateCRD已注册: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从安装到策略拦截的完整工作流:
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)