3. OPA Gatekeeper 架构:Admission Webhook、ConstraintTemplate、Constraint、Rego 引擎交互流程
OPA Gatekeeper 是 Kubernetes 的 可审计、可执行的准入控制器。它通过将 OPA(Open Policy Agent)的 Rego 策略引擎封装为 Kubernetes 原生资源,实现了策略即代码(Policy as Code)。理解其核心组件的交互流程,是编写和调试 Deployment 升级前 Rego 策略的基础。
3.1 核心组件与职责
Gatekeeper 架构由四个关键组件构成,它们协同工作,将策略定义、编译、执行与审计串联起来。
| 组件 | Kubernetes 资源类型 | 核心职责 |
|---|---|---|
| Admission Webhook | ValidatingWebhookConfiguration | 拦截 API Server 的准入请求(CREATE/UPDATE),转发给 Gatekeeper 服务。 |
| ConstraintTemplate | CRD(Custom Resource Definition) | 定义 Rego 策略的“骨架”:参数 schema + Rego 代码模板。 |
| Constraint | CR(Custom Resource) | 实例化 ConstraintTemplate,传入具体参数(如:允许的镜像仓库列表)。 |
| Rego 引擎 | (OPA 内置) | 编译 Rego 策略,评估输入(AdmissionReview),输出决策(allow/deny)。 |
3.2 交互流程全景图
下图展示了从用户提交 Deployment 到 Gatekeeper 做出准入决策的完整交互链路。
3.3 分步交互详解
以下步骤详细描述了上图所示的交互过程:
- 用户提交资源:用户通过
kubectl apply提交一个 Deployment 或其他资源对象到 API Server。 - API Server 拦截:API Server 接收到请求后,根据注册的 ValidatingWebhookConfiguration 规则,将请求封装为
AdmissionReview对象,并发送给 Gatekeeper 服务。 - Webhook 路由:Gatekeeper 的 Webhook 端点接收请求,提取
AdmissionReview中的资源对象(如 Deployment 的 JSON 描述)。 - Constraint 匹配:Gatekeeper 根据资源对象的
apiVersion、kind、namespace等标签,查找所有已安装的 Constraint 实例,筛选出匹配当前资源的策略。 - Rego 引擎评估:对于每个匹配的 Constraint,Gatekeeper 调用 Rego 引擎。引擎从对应的 ConstraintTemplate 中获取 Rego 代码,并将 Constraint 的参数(如
allowedRegistries)注入到 Rego 的input和parameters对象中。 - 决策返回:Rego 引擎执行策略,输出
allow或deny结果,并附带可选的msg(拒绝原因)。Gatekeeper 将结果封装为AdmissionResponse返回给 API Server。 - 最终执行:API Server 根据响应决定是持久化资源(allow)还是拒绝请求(deny),并将结果返回给用户。
关键点: ConstraintTemplate 是 Rego 代码的“模板”,Constraint 是“实例”。同一个 ConstraintTemplate(如“检查镜像仓库”)可以被实例化为多个 Constraint(如“生产命名空间只允许 A 仓库”、“测试命名空间只允许 B 仓库”),实现策略复用。
3.4 策略生命周期与审计
除了实时准入控制,Gatekeeper 还支持 审计(Audit) 功能。审计过程不依赖 Webhook,而是定期扫描集群中已有的资源,检查它们是否违反已安装的 Constraint。
| 模式 | 触发方式 | 作用时机 | 输出 |
|---|---|---|---|
| 准入控制(Admission) | API Server 实时调用 Webhook | 资源创建/更新时 | 立即拒绝或允许 |
| 审计(Audit) | Gatekeeper 定时任务(默认 60s) | 资源已存在后 | 在 Constraint 的 status 中列出违规资源 |
注意: 审计模式不会自动删除或修改违规资源,它只提供可见性。对于 Deployment 升级前的策略验证,应依赖 准入控制 模式,确保升级请求在提交时就被拦截。
3.5 组件交互的 Rego 视角
从 Rego 引擎的角度看,每次评估的输入结构如下:
# 简化后的 Rego 输入结构
input = {
"review": {
"object": { # 被评估的资源对象(如 Deployment)
"apiVersion": "apps/v1",
"kind": "Deployment",
"metadata": {"name": "my-app", "namespace": "production"},
"spec": { ... }
},
"parameters": { # 从 Constraint 传入的参数
"allowedRegistries": ["gcr.io/my-company", "docker.io/verified"]
}
}
}
Rego 策略通过 input.review.object 访问资源详情,通过 input.review.parameters 获取策略参数。这种解耦设计使得策略代码(ConstraintTemplate)与策略配置(Constraint)完全分离,便于管理和版本控制。