4. OPA 基础入门:OPA 是什么、Rego 语言简介、OPA 部署模式
4.1 OPA 是什么
Open Policy Agent (OPA) 是一个开源的、通用策略引擎,它将策略决策与业务逻辑的执行分离。OPA 不负责处理请求,而是作为策略决策点(PDP),接收来自任何系统(如 API 网关、服务网格、Kubernetes、CI/CD 管道)的查询,并基于预定义的策略返回决策结果(允许/拒绝/修改)。
核心价值: 统一策略描述、策略即代码、上下文感知、高性能决策缓存。
| 特性 | 说明 |
|---|---|
| 策略解耦 | 策略从微服务代码中剥离,独立管理、审计和热更新。 |
| 通用输入模型 | 任何结构化数据(JSON、YAML)均可作为输入,OPA 输出决策结果。 |
| 声明式语言 | 使用 Rego 语言编写策略,表达能力强且易于推理。 |
| 可嵌入性 | 可作为库、Sidecar、Daemon 或 Webhook 集成到任意架构中。 |
4.2 Rego 语言简介
Rego 是 OPA 的原生声明式查询语言,灵感来源于 Datalog。它专注于定义“数据应该是什么样”,而不是“如何遍历数据”。
4.2.1 基本语法结构
package example.authz
# 默认拒绝
default allow = false
# 允许规则:用户是 admin 角色
allow {
input.user.role == "admin"
}
# 允许规则:用户是资源的所有者
allow {
input.user.id == input.resource.owner_id
}
4.2.2 关键概念
- Package(包):策略的命名空间,用于组织规则。
- Rule(规则):由条件体(body)和结果(head)组成。当所有条件为真时,规则为真。
- Input(输入):外部系统传入的请求数据,如 HTTP 请求、Kubernetes 资源对象。
- Data(数据):OPA 加载的外部文档,如角色列表、黑名单、服务拓扑信息。
- Default(默认值):为规则定义默认值,避免未定义行为。
4.2.3 常用操作符与函数
| 操作符/函数 | 示例 | 说明 |
|---|---|---|
== |
input.method == "GET" |
相等比较 |
!= |
input.role != "guest" |
不等比较 |
in |
"admin" in input.user.roles |
成员关系检查 |
count() |
count(input.items) > 0 |
集合/数组长度 |
glob.match() |
glob.match("/api/v1/*", [], input.path) |
路径模式匹配 |
提示: Rego 中的变量一旦绑定,在同一规则内不可重新赋值。这种“单一赋值”特性保证了策略的确定性和可测试性。
4.3 OPA 部署模式
OPA 支持多种部署模式,以适应不同的架构场景。在服务网格中,最常用的模式是 Sidecar 和 Daemon;在 Kubernetes 准入控制中,Gatekeeper 是标准方案。
4.3.1 部署模式对比
| 模式 | 部署位置 | 典型场景 | 优点 | 缺点 |
|---|---|---|---|---|
| Sidecar | 每个 Pod 内作为独立容器 | 服务网格(Istio/Envoy) | 低延迟、隔离性好、策略本地化 | 资源消耗随 Pod 数量线性增长 |
| Daemon | 每个节点一个实例 | 节点级策略、共享缓存 | 资源利用率高、策略集中管理 | 网络延迟略高、单点故障风险 |
| Gatekeeper | Kubernetes 集群级 Webhook | K8s 资源准入控制 | 原生 K8s 集成、约束模板化 | 仅适用于 K8s 场景 |
4.3.2 架构对比图
下图展示了三种部署模式在服务网格与 Kubernetes 环境中的位置关系:
4.3.3 模式选择建议
推荐: 在服务网格(如 Istio)中,优先使用 Sidecar 模式 实现每个微服务的细粒度权限控制;若节点级策略缓存可接受,Daemon 模式 可降低资源开销。对于 Kubernetes 集群的合规性检查,Gatekeeper 是官方推荐方案。
4.4 本章小结
- OPA 是通用的策略决策引擎,核心优势在于策略与业务逻辑分离。
- Rego 语言采用声明式语法,通过规则、输入、数据完成策略定义。
- 三种部署模式(Sidecar、Daemon、Gatekeeper)分别适用于服务网格、节点级策略和 K8s 准入控制场景。