2. OPA Gatekeeper 架构深度解析:Admission Webhook、Rego 引擎、数据缓存层的工作原理
OPA Gatekeeper 是 Kubernetes 生态中最成熟的策略引擎之一,其核心架构围绕 Admission Webhook、Rego 引擎 和 数据缓存层 三大组件构建。理解这三者的协作关系,是优化规则缓存、降低 API 延迟的前提。
2.1 整体架构与请求生命周期
Gatekeeper 以 可变更 Webhook (MutatingWebhook) 和 验证 Webhook (ValidatingWebhook) 的形式注册到 API Server。当资源创建、更新或删除时,API Server 会并行调用 Gatekeeper 的 Webhook 端点,触发策略评估。
2.2 Admission Webhook:策略入口
Admission Webhook 是 Gatekeeper 与 Kubernetes 交互的桥梁。它负责接收 API Server 的准入请求,解析 AdmissionReview 对象,并将请求转发给 Rego 引擎。
2.2.1 Webhook 配置与注册
Gatekeeper 通过 ValidatingWebhookConfiguration 和 MutatingWebhookConfiguration 资源注册自身。关键配置字段包括:
| 字段 | 说明 | 典型值 |
|---|---|---|
clientConfig.service |
指向 Gatekeeper 的 Service | gatekeeper-webhook-service |
rules |
匹配的资源操作(CREATE/UPDATE/DELETE) | apiGroups: ["*"] |
failurePolicy |
Webhook 不可用时的行为 | Fail 或 Ignore |
timeoutSeconds |
Webhook 超时时间 | 3(默认) |
failurePolicy 设为 Ignore 可避免 Gatekeeper 故障时阻塞集群,但会降低策略强制力。生产环境建议设为 Fail 并配合高可用部署。
2.2.2 请求处理流程
- 接收请求: API Server 将
AdmissionReview对象 POST 到 Gatekeeper 的/v1/admit端点。 - 解析对象: 提取请求中的
object(新资源)、oldObject(旧资源,仅 UPDATE)和operation。 - 构建输入: 将解析后的数据封装为 Rego 引擎可识别的
input文档。 - 调用 Rego: 将
input传递给 Rego 引擎,触发策略评估。 - 返回响应: 根据 Rego 引擎的决策,构造
AdmissionResponse(允许/拒绝/变更)。
2.3 Rego 引擎:策略评估核心
Rego 是 OPA 的声明式查询语言,Gatekeeper 使用 Rego 引擎执行策略规则。引擎的工作分为 编译 和 评估 两个阶段。
2.3.1 编译阶段
当 Gatekeeper 启动或策略模板(ConstraintTemplate)更新时,Rego 引擎会:
- 解析 Rego 源码: 将字符串形式的 Rego 规则解析为抽象语法树(AST)。
- 类型检查: 验证规则中的变量、函数和引用是否合法。
- 优化查询计划: 对规则进行重写和索引优化,生成高效的执行计划。
- 缓存编译结果: 将编译后的策略对象缓存到内存中,避免重复编译。
2.3.2 评估阶段
每次 Webhook 请求到达时,Rego 引擎执行以下步骤:
| 步骤 | 操作 | 性能影响 |
|---|---|---|
| 1 | 加载 input 文档(来自 Webhook) |
低 |
| 2 | 加载 data 文档(来自缓存层) |
中(取决于缓存命中率) |
| 3 | 执行规则体(Rule Body) | 高(规则复杂度决定) |
| 4 | 聚合结果(Allow/Deny/变更) | 低 |
http.send 进行外部 API 调用会显著增加延迟,且无法被缓存。应优先使用数据缓存层提供外部数据。
2.4 数据缓存层:减少 API 调用延迟
数据缓存层是 Gatekeeper 性能优化的核心。它负责缓存 Kubernetes 资源对象(如 Namespace、Pod、Service)和外部数据,避免 Rego 引擎在每次评估时都直接调用 K8s API。
2.4.1 缓存架构
Gatekeeper 使用 OPA 内置的 data 文档 作为缓存容器。缓存数据通过以下方式填充:
- K8s 数据同步: Gatekeeper 通过
kube-mgmt或opa-kube-mgmt组件,使用 Informer 机制监听集群资源变化,并将数据写入 OPA 的data文档。 - 外部数据注入: 通过
data.inventory或自定义数据源(如 ConfigMap、Secret)将外部策略数据注入缓存。 - TTL 过期: 部分缓存项支持 TTL(Time-To-Live),避免数据过时。
2.4.2 缓存数据分类
| 数据类型 | 来源 | 缓存方式 | 典型延迟 |
|---|---|---|---|
| 集群资源(Pod/Namespace) | K8s API | Informer 全量同步 + 增量 Watch | < 100ms(缓存命中) |
| 策略配置(ConstraintTemplate) | K8s API | Informer 同步 | < 50ms |
| 外部数据(黑名单/白名单) | ConfigMap / Secret | 定期轮询或 Watch | 取决于更新频率 |
| 动态数据(外部 API 结果) | 外部服务 | TTL 缓存(如 30s) | 取决于 TTL 设置 |
2.4.3 缓存命中与未命中处理
- 缓存命中: Rego 引擎直接从
data文档读取数据,延迟极低(微秒级)。 - 缓存未命中: 如果数据尚未同步或已过期,Rego 引擎会触发 回退查询,直接调用 K8s API。这会增加 200-500ms 的延迟。
- 预热策略: 在 Gatekeeper 启动时,Informer 会执行一次全量同步,确保缓存中包含所有必要数据。
data.kubernetes 直接调用 API,这会绕过缓存。
2.5 三大组件的协作关系
Admission Webhook、Rego 引擎和数据缓存层通过以下方式协同工作:
- Webhook 接收请求,解析为
input文档。 - Rego 引擎加载
input,并从 数据缓存层 获取data文档。 - Rego 引擎执行策略规则,生成决策(Allow/Deny/变更)。
- Webhook 将决策封装为 AdmissionResponse,返回给 API Server。
- 数据缓存层持续同步 K8s 资源变化,确保
data文档始终最新。
这种架构将 策略评估 与 数据获取 解耦,使得 Gatekeeper 能够在毫秒级完成复杂策略检查,同时避免对 K8s API 造成过大压力。