2. OPA 与 Rego 基础:OPA 架构、Rego 语言核心概念
在深入 Gatekeeper 约束规则之前,必须理解其底层引擎——开放策略代理(OPA) 以及它的策略语言 Rego。OPA 是一个通用的、开源的策略引擎,它将策略从软件中解耦;而 Rego 则是专为 OPA 设计的声明式查询语言。本章将拆解 OPA 的核心架构,并建立 Rego 语言的基本认知,为后续编写 Gatekeeper 约束奠定基础。
2.1 OPA 架构:策略决策的“大脑”
OPA 并非一个代理或 sidecar,而是一个独立的服务或库。其核心职责是:接收查询(输入),结合策略(Policy)和数据(Data),输出决策(Decision)。下图展示了 OPA 的高层架构与请求流。
关键理解: OPA 将“策略决策”与“策略执行”分离。OPA 只负责“决策”,不负责“执行”。例如,Kubernetes 准入控制器(Gatekeeper)负责拦截请求并调用 OPA,OPA 返回“允许”或“拒绝”,准入控制器再执行该决定。
2.2 Rego 语言核心概念
Rego 是一种受 Datalog 启发的声明式查询语言。与命令式编程(如 Python、Go)不同,Rego 不描述“如何做”,而是描述“数据应该是什么样子”。策略编写者定义一组规则,OPA 引擎自动评估这些规则并返回结果。
2.2.1 规则(Rules)
规则是 Rego 策略的基本构建块。一个规则定义了一个决策或一个派生值。规则有两种主要形式:
| 规则类型 | 语法特征 | 示例 | 说明 |
|---|---|---|---|
| 完整规则 | 单个条件,结果为单个值 | allow := true { input.role == "admin" } |
当条件满足时,allow 被赋值为 true;否则为 undefined。 |
| 部分规则 | 多个条件,结果为集合或对象 | allowed_users[user] { user := input.users[_]; user.role == "viewer" } |
生成一个包含所有满足条件用户的集合。 |
| 默认规则 | 提供回退值 | default allow = false |
当其他规则未定义时,使用默认值,避免未定义错误。 |
避坑指南: 在 Gatekeeper 约束中,最常用的是 完整规则。约束模板通常定义一个
violation 规则,当检测到违规时返回 {"msg": "..."},否则不返回任何值(即未定义)。不要混淆 true/false 与 undefined 的区别。
2.2.2 查询(Queries)
查询是向 OPA 引擎提问的方式。在 Rego 中,查询可以简单到只引用一个规则,也可以复杂到包含多个条件和迭代。查询的结果是 绑定 或 布尔值。
- 布尔查询: 判断某个条件是否成立。例如:
allow返回true或false(或 undefined)。 - 数据查询: 获取满足条件的数据集合。例如:
data.allowed_users返回用户列表。 - 迭代查询: 使用
some关键字遍历集合。例如:some i; input.namespaces[i] == "production"。
2.2.3 数据(Data)
OPA 中的“数据”分为两类:
| 数据来源 | 访问路径 | 典型内容 |
|---|---|---|
| 基础文档 | data |
通过 OPA API 加载的静态 JSON 数据(如集群资源清单、外部配置)。 |
| 输入文档 | input |
每次查询时由外部系统传入的动态数据(如 Kubernetes 准入请求的 AdmissionReview)。 |
| 虚拟文档 | data.package.rule |
由 Rego 规则计算得出的派生数据,是策略评估的结果。 |
2.3 第一个 Rego 规则示例
以下是一个完整的 Rego 规则示例,展示了规则、查询和数据的协作。该规则检查输入的用户是否具有“admin”角色。
package example.auth
# 默认规则:拒绝所有请求
default allow = false
# 完整规则:如果用户角色是 admin,则允许
allow {
input.role == "admin"
}
# 部分规则:列出所有具有 viewer 角色的用户
viewers[user] {
user := input.users[_]
user.role == "viewer"
}
执行逻辑: 当 OPA 收到查询
data.example.auth.allow 时,它会检查 input.role 是否等于 "admin"。如果匹配,allow 返回 true;否则返回 false(因为默认规则)。查询 data.example.auth.viewers 则会返回所有 viewer 角色的用户集合。
2.4 本章小结
- OPA 架构 遵循“输入 → 策略 + 数据 → 决策”的简洁模型,实现了策略与执行的解耦。
- Rego 规则 是声明式的,分为完整规则、部分规则和默认规则,用于定义策略逻辑。
- 查询 是向 OPA 提问的方式,结果可以是布尔值或数据集合。
- 数据 分为基础文档(静态)、输入文档(动态)和虚拟文档(派生),通过
data和input路径访问。 - 理解这些基础概念是编写 Gatekeeper 约束模板的前提,下一章将直接应用这些知识来构建第一个安全基线约束。