1. OPA 与 Kubernetes 准入控制概述

1.1 什么是 OPA(Open Policy Agent)

OPA 是一个开源的、通用策略引擎,它将策略决策与业务逻辑解耦。OPA 使用一种名为 Rego 的声明式语言来编写策略,允许你以“策略即代码”的方式定义、测试和分发规则。

核心设计理念: OPA 不负责执行策略,只负责做出决策。它接收 JSON 格式的输入(如 Kubernetes 资源对象),结合策略规则,输出“允许/拒绝”或更复杂的结构化决策。
特性 说明
声明式策略 使用 Rego 语言描述“期望状态”,而非“如何执行”。
上下文无关 OPA 不依赖特定平台,可嵌入到任何需要策略决策的系统。
可组合性 策略可以拆分为模块,通过 import 和 data 复用。
可测试性 Rego 策略支持单元测试,便于 CI/CD 集成。

1.2 Kubernetes 准入控制器工作原理

Kubernetes 准入控制器是一段代码,在 API 请求经过认证和授权之后、对象被持久化到 etcd 之前拦截请求。它可以修改(Mutating)或验证(Validating)资源对象。

  1. MutatingAdmissionWebhook: 先执行,允许修改请求对象(如注入 Sidecar、设置默认值)。
  2. ValidatingAdmissionWebhook: 后执行,仅验证请求对象是否符合策略,不能修改。
  3. 内置准入控制器: 如 NamespaceLifecycle、LimitRanger、ResourceQuota 等。
关键时序: 所有准入控制器按链式顺序执行。如果任何一个验证控制器拒绝请求,整个 API 请求立即失败,对象不会被创建或更新。
Kubernetes API 请求准入控制流程 kubectl / 用户 API Server 认证 / 授权 准入控制链 Mutating → Validating (含 OPA Gatekeeper) etcd 持久化 拒绝请求 拒绝后对象不写入 etcd

1.3 OPA Gatekeeper 的架构与角色

OPA Gatekeeper 是 OPA 在 Kubernetes 生态中的原生集成方案,以 Admission Webhook 的形式运行。它允许集群管理员通过 CRD(Custom Resource Definition)声明式地管理策略。

核心组件

组件 角色 说明
Gatekeeper 控制器 策略引擎 运行 OPA 实例,监听 ConstraintTemplate 和 Constraint 资源变化,动态编译 Rego 策略。
ConstraintTemplate (CT) 策略模板 定义 Rego 策略逻辑和参数 schema,是策略的“类”。
Constraint 策略实例 实例化 ConstraintTemplate,传入具体参数(如允许的命名空间列表)。
Webhook 服务 准入拦截 注册到 Kubernetes 的 ValidatingWebhookConfiguration,拦截资源请求。

工作流程

  1. 策略定义: 管理员创建 ConstraintTemplate,编写 Rego 规则。
  2. 策略实例化: 创建 Constraint 资源,指定生效范围(如 match: namespaces: ["production"])。
  3. 请求拦截: 用户提交资源(如 Pod),API Server 调用 Gatekeeper Webhook。
  4. 策略评估: Gatekeeper 将资源对象转为 JSON 输入,执行所有匹配的 Constraint 策略。
  5. 决策返回: 返回 allowed: true/false 及拒绝消息。
性能关键点: 每个准入请求都会触发 OPA 策略评估。如果 Rego 规则复杂度高(如大量循环、嵌套查询),或 Constraint 数量过多,会直接增加 API 请求延迟,甚至导致 kube-apiserver 超时。
OPA Gatekeeper 架构与策略评估流程 集群管理员 ConstraintTemplate Constraint Gatekeeper 控制器 OPA 引擎 Rego 编译 & 缓存 策略热加载 Webhook 服务 拦截请求 JSON 输入转换 返回决策 kube- apiserver 策略变更无需重启 Webhook Gatekeeper 自动热加载 Constraint

1.4 为什么需要关注规则复杂度

OPA Gatekeeper 虽然强大,但 Rego 策略的编写质量直接影响集群的 API 响应延迟。常见问题包括:

  • 循环嵌套: 在 Rego 中使用多层 some 或 walk 遍历大量资源。
  • 数据依赖: 策略中频繁查询集群状态(如 data.kubernetes.namespaces),导致 OPA 缓存压力增大。
  • Constraint 数量膨胀: 每个 Constraint 独立评估,数量过多时 Webhook 处理时间线性增长。