4. OPA 策略引擎入门:OPA 是什么、Rego 语言简介、OPA 的部署模式

在构建服务目录平台容量水位巡检系统时,核心挑战在于如何将分散的容量规则(如“CPU 使用率超过 80% 触发告警”“磁盘剩余空间低于 10% 禁止调度新实例”)从应用代码中解耦,实现策略的集中管理与动态热更新。Open Policy Agent (OPA) 正是为解决这一需求而生的云原生策略引擎。

4.1 OPA 是什么

OPA 是一个开源的、通用的策略引擎,它将策略决策与业务逻辑执行分离。OPA 不负责处理请求,也不直接管理资源,而是作为一个统一的决策点,回答“是否允许某个操作”或“某个状态是否符合预期”。

核心设计理念: 策略即代码(Policy as Code)。OPA 使用专用的声明式语言 Rego 编写策略,通过 REST API 或 gRPC 对外提供决策服务。

OPA 在云原生生态中的定位非常清晰:

  • 策略决策点 (PDP): 接收输入(如资源指标、用户属性、请求上下文),结合策略规则,输出决策结果(allow/deny、合规/不合规、风险等级)。
  • 与数据解耦: OPA 本身不存储业务数据,决策所需的数据(如集群节点列表、Pod 资源使用量)由调用方通过输入传入,或通过内置的 data 文档从外部数据源加载。
  • 可嵌入与可独立部署: 既可作为 sidecar 与微服务一起运行,也可作为独立的守护进程或外部服务供多个系统调用。
特性 说明 在容量巡检中的价值
策略与逻辑分离 策略规则独立于巡检调度代码 容量阈值调整无需修改巡检程序,只需更新 Rego 策略
声明式策略 使用 Rego 描述“期望状态” 直接表达“CPU 使用率 < 80%”等合规条件
热加载 策略变更无需重启服务 巡检规则可动态下发,适应快速变化的容量需求
细粒度决策 支持复杂条件组合与嵌套 可针对不同服务、不同环境(生产/预发)设置差异化水位线

4.2 Rego 语言简介

Rego 是 OPA 的原生策略语言,受 Datalog 启发,专为表达策略规则而设计。Rego 的核心思想是:策略是一组规则,规则是一组逻辑条件,当条件满足时,规则产生一个输出值。

快速上手: Rego 不是通用编程语言,它没有循环、变量赋值(不可变)、面向对象等概念。它专注于“查询”和“匹配”。

以下是一个简单的 Rego 策略示例,用于判断某个节点的 CPU 水位是否合规:

package capacity.waterlevel

# 默认允许(合规)
default allow = true

# 规则:如果 CPU 使用率超过 80%,则拒绝(不合规)
allow = false {
    input.cpu_usage_percent > 80
}

# 规则:如果内存使用率超过 90%,也拒绝
allow = false {
    input.mem_usage_percent > 90
}

# 输出决策详情(可选)
violation_reasons[reason] {
    input.cpu_usage_percent > 80
    reason = "CPU 水位超过 80%"
}

violation_reasons[reason] {
    input.mem_usage_percent > 90
    reason = "内存水位超过 90%"
}

Rego 的关键语法元素:

  • Package: 策略的命名空间,如 package capacity.waterlevel。
  • Rule: 由头部(head)和体部(body)组成。体部中的条件全部为真时,头部被满足。
  • Default: 为规则设置默认值,避免所有条件都不匹配时规则未定义。
  • Input: 调用方传入的临时数据,如巡检指标。
  • Data: 全局数据文档,可加载外部配置或静态数据。
  • Comprehension: 类似函数式编程的集合推导,用于生成复杂结果。
常见误区: Rego 中的变量一旦绑定,在同一规则内不可重新赋值。例如 x := 1; x := 2 会编译错误。这种设计保证了策略的纯声明式特性,避免副作用。

4.3 OPA 的部署模式

OPA 支持三种主流部署模式,分别适用于不同的架构场景。在服务目录平台容量水位巡检中,选择哪种模式取决于巡检系统的架构、性能要求以及运维复杂度。

OPA 三种部署模式对比 Sidecar 模式 • 与巡检服务同 Pod 部署 • 本地 HTTP/gRPC 调用 • 低延迟,隔离性好 • 策略变更需重启 Pod • 适合高吞吐、低延迟场景 Daemon 模式 • 每节点部署一个 OPA 实例 • 节点内所有服务共享 • 资源利用率高 • 策略变更需逐节点更新 • 适合节点级策略(如 K8s) 外部服务模式 • 独立部署的 OPA 集群 • 所有服务远程调用 • 策略统一管理,热更新 • 网络延迟增加 • 适合多服务共享策略 部署模式选择建议 • 服务目录平台巡检场景:推荐使用 外部服务模式 或 Daemon 模式 • 外部服务模式:策略集中管理,支持热更新,适合多集群、多租户的容量巡检平台 • Daemon 模式:适合 Kubernetes 节点级巡检,如节点磁盘、网络带宽水位 • Sidecar 模式:适合对延迟极度敏感的核心服务巡检,但策略变更不够灵活

4.4 三种部署模式详细对比

维度 Sidecar 模式 Daemon 模式 外部服务模式
部署粒度 每个服务 Pod 一个 OPA 每个节点一个 OPA 独立集群部署
调用方式 本地 localhost 调用 节点内 Unix Socket 或 localhost 远程 HTTP/gRPC
延迟 < 1ms < 2ms 2-10ms(取决于网络)
策略管理 分散,需逐个 Pod 更新 按节点管理 集中管理,支持热更新
资源消耗 高(每个 Pod 一份) 中(每个节点一份) 低(共享实例)
适用场景 延迟敏感、策略差异大的服务 节点级策略(K8s Admission) 多服务共享策略、集中管控
容量巡检适配性 低(策略变更不灵活) 中(适合节点级水位) 高(推荐)
实践建议: 在服务目录平台容量水位巡检项目中,我们采用 外部服务模式 部署 OPA。巡检调度器作为客户端,将采集到的容量指标(CPU、内存、磁盘、网络等)封装为 input 发送给 OPA 服务,OPA 根据预定义的 Rego 策略返回合规/违规结果。这种模式使得容量策略的调整只需修改 OPA 服务端的策略文件,巡检调度器无需任何变更,真正实现了策略与执行的解耦。