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

3.1 OPA 是什么

Open Policy Agent (OPA) 是一个开源的、通用策略引擎,它将策略决策与业务逻辑的执行分离。OPA 提供了一种统一的、声明式的语言(Rego)来描述策略,并通过 REST API 或 gRPC 接口对外提供策略查询服务。在云原生生态中,OPA 常被用于实现微服务、Kubernetes、服务网格等场景下的细粒度访问控制、合规检查和数据过滤。

核心设计理念: 策略即代码(Policy as Code)。OPA 不负责执行具体的业务操作,只负责回答“是否允许”或“应该怎么做”的问题。这种解耦使得策略可以独立于应用进行管理、测试和版本控制。

3.2 OPA 架构与决策流程

OPA 的决策流程遵循“输入-策略-输出”的模型。外部系统(如 Envoy、Kubernete API Server)将请求上下文(Input)发送给 OPA,OPA 根据加载的 Rego 策略和全局数据(Data)进行评估,最终返回决策结果(Decision)。

OPA 核心决策流程 外部系统 (Envoy / K8s) Input OPA 策略引擎 Rego 策略评估 数据查询 决策生成 Decision 执行系统 (允许/拒绝) 数据源 (Data) 加载

3.3 Rego 语言简介

Rego 是 OPA 的原生策略语言,受 Datalog 启发,专为在复杂嵌套文档(如 JSON、YAML)上定义策略而设计。Rego 的核心是规则(Rules)和查询(Queries)。策略编写者通过定义规则来描述允许或禁止的条件。

3.3.1 Rego 基础语法

  • 包(Package): 用于组织策略,类似命名空间。
  • 规则(Rule): 形如 allow { condition },当条件为真时,规则为真。
  • 默认值(Default): 使用 default allow = false 设置规则的默认拒绝行为。
  • 迭代(Iteration): 使用 some 关键字遍历集合。
  • 内置函数(Built-in Functions): 如 http.send、regex.match、time.now_ns 等。
关键概念: Rego 中的规则是“完备的”——如果没有任何规则明确允许,则默认拒绝。这符合安全策略的最小权限原则。

3.3.2 Rego 策略示例

以下示例展示了一个简单的 Rego 策略,用于控制服务网格中服务 A 对服务 B 的访问:

package service_mesh.authz

import future.keywords.if
import future.keywords.in

# 默认拒绝所有请求
default allow := false

# 允许规则:如果请求来自 service-a,目标为 service-b,且 HTTP 方法为 GET
allow if {
    input.source_service == "service-a"
    input.destination_service == "service-b"
    input.http_method == "GET"
}

# 允许规则:如果请求携带有效的 JWT ,且  中的角色为 "admin"
allow if {
    input.jwt.role == "admin"
}

3.4 OPA 部署模式

OPA 可以以多种模式集成到服务网格或 Kubernetes 环境中。选择合适的部署模式取决于性能、延迟、管理复杂度和安全隔离需求。下表对比了三种主流部署模式:

部署模式 架构描述 延迟 管理复杂度 适用场景
Sidecar OPA 作为独立容器与业务容器同 Pod 运行 极低(本地 IPC) 中等(需管理 Sidecar 注入) 对延迟敏感、需要隔离策略执行的场景
Daemon OPA 作为 DaemonSet 在每个节点上运行 低(节点内通信) 低(集中管理,节点级共享) 节点级策略执行,如节点安全审计
外部服务 OPA 作为独立服务集群部署,通过网络调用 中等(网络开销) 高(需考虑高可用、负载均衡) 策略逻辑复杂、需要全局数据聚合的场景

3.4.1 Sidecar 模式

在服务网格中,Sidecar 模式是最常见的 OPA 部署方式。每个微服务 Pod 内除了业务容器和 Envoy 代理外,还会运行一个 OPA 容器。Envoy 通过 ext_authz 过滤器将请求上下文发送给本地的 OPA 实例进行决策。这种模式延迟最低,且策略执行失败不会影响其他 Pod。

3.4.2 Daemon 模式

Daemon 模式将 OPA 部署为 Kubernetes DaemonSet,每个节点上运行一个 OPA 实例。节点上的所有 Pod 可以共享该 OPA 实例进行策略查询。这种模式减少了 Pod 内的资源开销,但引入了节点级别的单点故障风险。

3.4.3 外部服务模式

外部服务模式将 OPA 部署为一个独立的、可水平扩展的服务。所有 Envoy 代理或应用通过 DNS 或 Service Mesh 的流量规则将策略查询请求发送到 OPA 集群。这种模式便于统一管理和更新策略,但会增加网络延迟,且需要额外的负载均衡和故障转移机制。

OPA 三种部署模式对比 Sidecar 模式 业务容器 Envoy OPA ext_authz Pod 内本地通信 Daemon 模式 Pod A Pod B OPA 节点级共享 外部服务模式 Pod A Pod B OPA 集群 网络调用
选择建议: 在服务网格流量拓扑的细粒度访问控制场景中,Sidecar 模式通常是首选。它提供了最低的决策延迟和最强的故障隔离性,确保每个微服务的策略执行互不干扰。如果集群规模极大且对 Pod 资源开销敏感,可以考虑外部服务模式,但必须做好缓存和降级策略。