4. OPA Gatekeeper 入门:OPA 与 Rego 语言基础、Gatekeeper 架构、安装与部署、核心概念
OPA Gatekeeper 是 Kubernetes 生态中最成熟的策略引擎之一,它允许集群管理员以声明式的方式定义、审计和强制执行准入控制策略。本节将系统介绍 OPA 策略语言 Rego、Gatekeeper 的架构设计、部署方法以及核心资源模型。
4.1 OPA 与 Rego 语言基础
OPA(Open Policy Agent)是一个通用的策略引擎,它将策略决策与业务逻辑解耦。Rego 是 OPA 专用的声明式查询语言,灵感来源于 Datalog,专为在复杂嵌套数据(如 Kubernetes 资源清单)上编写策略而设计。
4.1.1 Rego 核心语法
| 概念 | 语法示例 | 说明 |
|---|---|---|
| 规则 | allow { input.spec.replicas > 1 } |
当条件为真时,规则为真 |
| 默认值 | default allow = false |
显式拒绝,防止未定义行为 |
| 迭代 | some i; input.containers[i].image |
遍历数组元素 |
| 模式匹配 | input.kind == "Pod" |
精确匹配资源类型 |
| 否定 | not input.metadata.namespace == "kube-system" |
排除特定命名空间 |
4.1.2 策略决策模型
OPA 的策略决策遵循“输入-规则-输出”模型:
- input:Kubernetes AdmissionReview 请求的完整 JSON 表示,包含资源对象、用户信息、操作类型等。
- data:OPA 缓存的外部数据,如命名空间标签、节点信息、外部配置。
- 规则:Rego 文件中的策略逻辑,通常包含
violation或deny规则。 - 输出:Gatekeeper 期望的响应格式,如
{"msg": "镜像必须来自受信任仓库"}。
💡 关键原则:Rego 策略默认是“允许所有”,必须显式编写拒绝规则。Gatekeeper 通过检查
violation 规则是否有输出值来决定是否拒绝请求。
4.2 Gatekeeper 架构
Gatekeeper 由三个核心组件构成,它们协同工作以实现策略的声明式管理和强制执行。
4.2.1 组件职责
| 组件 | 职责 | 部署形态 |
|---|---|---|
| Webhook | 拦截 API Server 的准入请求,转发给 OPA 引擎 | Deployment + Service |
| OPA Engine | 加载 ConstraintTemplate 中的 Rego 策略,执行评估 | 与 Webhook 同 Pod |
| ConstraintTemplate | 定义可复用的策略模板(Rego 代码 + Schema) | CRD |
| Constraint | 实例化模板,绑定具体参数和作用范围 | CRD 实例 |
4.3 安装与部署
Gatekeeper 推荐通过 Helm Chart 或直接应用官方 YAML 清单进行部署。以下为生产环境推荐步骤:
4.3.1 使用 Helm 安装
# 添加 Gatekeeper Helm 仓库
helm repo add gatekeeper https://open-policy-agent.github.io/gatekeeper/charts
# 安装 Gatekeeper 到 gatekeeper-system 命名空间
helm install gatekeeper/gatekeeper \
--name-template=gatekeeper \
--namespace gatekeeper-system \
--create-namespace \
--set replicas=2 \
--set auditInterval=60 \
--set logLevel=INFO
4.3.2 验证部署
# 检查 Pod 状态
kubectl get pods -n gatekeeper-system
# 检查 CRD 是否注册
kubectl get crd | grep gatekeeper
# 检查 Webhook 配置
kubectl get validatingwebhookconfigurations | grep gatekeeper
✅ 生产建议:部署时至少设置 2 个副本以保证高可用;开启
audit 功能以定期扫描集群中已存在的违规资源;使用 --set logLevel=DEBUG 进行故障排查。
4.4 核心概念:ConstraintTemplate 与 Constraint
Gatekeeper 的策略模型围绕两个核心 CRD 构建:ConstraintTemplate 定义“做什么”,Constraint 定义“对谁做”和“参数是什么”。
4.4.1 ConstraintTemplate
ConstraintTemplate 是一个集群范围的 CRD,它封装了一段 Rego 策略代码和一个可选的参数 Schema。以下是一个禁止使用 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
endswith(tag, ":latest")
msg := sprintf("容器镜像 %v 使用了禁止的 :latest 标签", [container.image])
}
4.4.2 Constraint
Constraint 是 ConstraintTemplate 的实例化对象,它指定了策略参数和匹配范围。以下实例禁止在 production 命名空间中使用 latest 标签:
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sDisallowedTags
metadata:
name: block-latest-in-prod
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
namespaces:
- "production"
parameters:
tags:
- "latest"
4.4.3 策略生命周期
4.4.4 关键字段说明
| 资源 | 关键字段 | 作用 |
|---|---|---|
| ConstraintTemplate | spec.crd.spec.names.kind |
定义 Constraint 的 Kind 名称 |
spec.targets[].rego |
嵌入 Rego 策略代码 | |
spec.crd.spec.validation |
定义参数 Schema(OpenAPI v3) | |
| Constraint | spec.match |
匹配资源类型、命名空间、标签等 |
spec.parameters |
传递给 Rego 策略的具体参数 | |
status |
审计结果和违规资源列表 |
⚠️ 常见陷阱:
- ConstraintTemplate 中的
kind名称必须与 Constraint 的kind完全一致(大小写敏感)。 - Rego 包名(
package)建议与 ConstraintTemplate 名称保持一致,避免混淆。 - Constraint 的
match字段支持kinds、namespaces、labelSelector、namespaceSelector等多种匹配方式,组合使用时为 AND 逻辑。