2. OPA 与 Rego 基础回顾:OPA 架构、Rego 策略语言核心概念、数据模型

2.1 OPA 整体架构与核心组件

Open Policy Agent (OPA) 是一个开源的、通用策略引擎,它将策略决策与业务逻辑解耦。在资源配额监控场景中,OPA 作为决策点,接收来自 Kubernetes API Server 或自定义监控系统的查询,并基于预定义的 Rego 策略返回“允许/拒绝”或“审计警告”等决策。

OPA 的架构遵循“决策请求-策略评估-响应”的闭环模型,核心组件包括:

  • 服务端 (OPA Server):常驻进程,通过 HTTP/gRPC 暴露决策 API。支持热加载策略和数据进行策略更新,无需重启。
  • Rego 引擎:OPA 的核心,负责解析、编译和执行 Rego 策略。引擎将策略编译为高效的内部表示,并利用缓存和索引优化查询。
  • 数据文档 (Data Document):OPA 的全局数据源,通常以 JSON 格式注入。在配额监控中,数据文档包含集群资源使用量、节点容量、命名空间配额等实时或近实时的监控数据。
  • 输入文档 (Input Document):每次决策请求时携带的临时数据,例如一个 Pod 的创建请求、一个 Namespace 的当前资源使用快照。
  • Bundle 系统:用于将策略和数据打包成压缩包,通过 HTTP 或 OCI 分发到 OPA 实例,实现策略的版本管理和原子更新。
OPA 架构与决策流程 外部请求 (K8s API / 监控系统) Input 文档 (请求上下文) OPA 引擎 Rego 编译 + 评估 (缓存 / 索引) Data 文档 (配额 / 监控数据) 策略库 (Policies) Rego 模块 / Bundle 决策输出 (allow / deny / warn) 关键路径 Input + Data → 引擎评估 → 决策输出 延迟瓶颈点
架构要点:在资源配额监控场景下,Data 文档通常体积较大(包含全集群资源数据),而 Input 文档较小(单次请求)。OPA 引擎的评估延迟主要受 Data 文档大小、策略复杂度以及缓存命中率影响。理解这一架构是后续延迟定位的基础。

2.2 Rego 策略语言核心概念

Rego 是一种声明式查询语言,专为定义策略而设计。它基于 Datalog 逻辑编程范式,支持丰富的模式匹配、集合操作和聚合函数。以下是 Rego 中必须掌握的核心概念:

概念 语法示例 说明
规则 (Rule) allow { ... } 策略的基本单元,定义一组条件。规则体为真时规则成立。
变量 (Variable) user := input.user 使用 := 进行局部赋值,变量不可变。
迭代 (Iteration) some i; data.pods[i].cpu > 100 使用 some 关键字遍历集合或数组。
聚合 (Aggregation) sum([x | data.pods[_].cpu]) 支持 sum、count、max、min 等聚合函数。
内置函数 (Built-in) io.jwt.decode() 提供 JWT 验证、时间处理、正则匹配等能力。
默认规则 (Default) default allow = false 为规则设置默认值,避免未定义行为。

在配额监控策略中,最常用的模式是:遍历 Data 文档中的资源列表,聚合计算当前使用量,然后与配额阈值进行比较。例如:

# 检查 Namespace 的 CPU 使用是否超过配额
default cpu_quota_exceeded = false

cpu_quota_exceeded {
    ns := input.namespace
    used_cpu := sum([p.cpu | data.pods[p.namespace == ns].cpu])
    quota := data.quotas[ns].cpu_limit
    used_cpu > quota
}
性能陷阱:在 Rego 中,data.pods[_].cpu 这种全量遍历写法在 Data 文档较大时会产生 O(n) 复杂度。如果策略中多次出现类似遍历,且未使用索引或缓存,将直接导致评估延迟飙升。后续章节将专门讲解如何通过 Rego 索引和部分求值来优化此类查询。

2.3 OPA 数据模型:分层文档与查询路径

OPA 的数据模型基于分层文档(Hierarchical Documents),所有数据都以 JSON 对象的形式组织在 data 根路径下。理解数据模型是编写高效 Rego 策略的前提。

数据模型的核心特征:

  • 全局数据 (Data Document):挂载在 data 根路径下,可通过 Bundle、API 推送或文件加载注入。例如:data.cluster.nodes、data.namespaces。
  • 请求数据 (Input Document):每次决策请求时传入,挂载在 input 根路径下。例如:input.pod、input.operation。
  • 策略模块 (Policy Modules):Rego 文件本身也作为数据的一部分,可通过 data.package.rule 路径引用其他模块定义的规则。
  • 虚拟文档 (Virtual Documents):由 Rego 规则计算得出的中间结果,可被其他规则引用,形成策略的层级结构。
OPA 分层数据模型 data data.cluster data.namespaces data.pods data.quotas .nodes .default .production .cpu_limit 查询路径示例 data.quotas["production"].cpu_limit → 获取 production 命名空间的 CPU 配额上限 data.pods[p.namespace == "production"].cpu → 获取 production 下所有 Pod 的 CPU 使用量

在编写策略时,应优先使用精确路径查询(如 data.quotas["production"].cpu_limit)而非全量遍历。OPA 引擎对精确路径查询会启用哈希索引,时间复杂度为 O(1);而对 data.pods[_] 这类通配符遍历则无法使用索引,性能随数据量线性下降。

数据模型最佳实践:
  • 将频繁查询的字段(如 Namespace 名称、资源类型)设计为文档的 Key,而非嵌套在数组内。
  • 对于配额监控场景,建议将 Data 文档按 Namespace 分区,例如 data.quotas[namespace],这样策略可以直接通过 Key 访问,避免遍历。
  • 利用 OPA 的 rego.metadata.rule() 内置函数获取规则元数据,辅助调试和审计。