2. OPA基础回顾:Rego策略语言核心概念、OPA架构、数据模型与查询
在深入Helm发布集成之前,必须牢固掌握OPA(Open Policy Agent)的核心基础。本章将系统回顾Rego策略语言的核心概念、OPA的整体架构、数据模型以及查询机制,为后续的自动化合规校验流水线设计奠定坚实的理论基础。
2.1 OPA架构概览
OPA是一个开源的、通用策略引擎,它将策略决策与业务逻辑执行分离。其核心架构遵循“决策请求-策略评估-决策响应”的闭环模型。
架构要点:OPA 不直接管理策略,而是通过 Bundle API 从外部加载策略和数据。外部系统(如 Kubernetes API Server、Helm 或自定义应用)通过 HTTP RESTful API 向 OPA 发起决策查询,OPA 基于加载的 Rego 策略和数据进行评估,并返回
allow 或 deny 等决策结果。
2.2 Rego策略语言核心概念
Rego 是专为 OPA 设计的声明式查询语言,灵感来源于 Datalog。它并非通用编程语言,而是专注于策略定义和逻辑推理。
2.2.1 基本语法与规则
Rego 中的核心单元是 规则(Rule)。规则定义了一个决策或一个中间值。规则可以是完整的(complete)或部分的(partial)。
| 概念 | 说明 | 示例 |
|---|---|---|
| 完整规则 | 为某个变量赋予一个确定的值,通常用于布尔决策。 | allow := true |
| 部分规则 | 定义一组条件,当条件满足时规则为真。 | allow { input.role == "admin" } |
| 默认规则 | 为规则提供默认值,避免未定义错误。 | default allow := false |
| 迭代规则 | 使用 some 关键字遍历集合或数组。 |
some i; input.users[i].name == "Alice" |
2.2.2 内置函数与聚合
Rego 提供了丰富的内置函数,用于字符串处理、集合操作、时间比较等。聚合函数如 count()、sum()、any()、all() 在策略中非常常用。
# 检查容器镜像是否来自允许的仓库
allowed_repos := ["docker.io/verified", "gcr.io/my-company"]
violation[msg] {
container := input.containers[_]
not startswith(container.image, allowed_repos[_])
msg := sprintf("容器 %v 使用了未授权的镜像仓库: %v", [container.name, container.image])
}
2.3 数据模型与查询
OPA 的数据模型基于 文档(Document) 模型。所有输入数据、外部数据和策略本身都被视为嵌套的 JSON 文档。OPA 通过 查询(Query) 来检索这些文档中的值。
2.3.1 数据模型层次
input:每次查询时由调用方提供的临时数据,例如 Helm 的 values.yaml 或 Kubernetes 的 AdmissionReview。data:OPA 加载的持久化数据,包括 Rego 策略文件(.rego)和外部数据文件(.json/.yaml)。result:查询执行后返回的决策结果,通常是一个 JSON 对象。
2.3.2 查询方式
OPA 支持两种主要的查询方式:
| 查询类型 | 描述 | 适用场景 |
|---|---|---|
| Ad-hoc 查询 | 通过 OPA 的 REST API 直接查询某个规则的值。 | 调试、手动验证策略。 |
| 批量查询(Partial Evaluation) | 将策略部分求值,生成针对特定输入的简化策略。 | 大规模集群中预计算策略,减少运行时开销。 |
关键理解:在 Helm 发布场景中,
input 通常包含 Helm Chart 的 values.yaml 和渲染后的 Kubernetes 资源清单。OPA 通过查询 data 中的合规策略,对 input 进行校验,最终输出一个包含 allowed 布尔值和 violations 列表的 JSON 响应。
2.4 策略包(Bundle)与模块
为了便于管理和分发,Rego 策略被组织成 Bundle。一个 Bundle 是一个包含 .rego 策略文件、.json 或 .yaml 数据文件以及一个可选 .manifest 文件的压缩包(.tar.gz)。
- 模块(Module):每个
.rego文件定义了一个模块,模块内包含包声明(package)和规则。 - 包(Package):用于组织规则,避免命名冲突。例如,
package kubernetes.admission。 - Bundle 版本管理:通过
.manifest文件中的revision字段实现策略的版本控制和原子更新。
# 示例:一个简单的 Rego 策略模块
package helm.policies
# 默认拒绝
default allow := false
# 规则:必须包含 "app" 标签
allow {
input.metadata.labels.app != ""
}
# 违规报告
violation[msg] {
not allow
msg := "Helm Release 必须包含 'app' 标签"
}
常见陷阱:Rego 中的变量一旦赋值,在同一个规则体内不可重新赋值。这与命令式语言不同。例如,
x := 1; x := 2 会导致编译错误。正确的做法是使用 some 关键字或创建新的变量。
2.5 本章小结
本章回顾了 OPA 的核心基础:
- 架构:OPA 作为策略决策点,通过 Bundle 加载策略和数据,对外提供统一的查询接口。
- Rego 语言:声明式、基于 Datalog,核心是规则定义,支持完整规则、部分规则和丰富的内置函数。
- 数据模型:基于文档模型,
input和data是两大核心数据源。 - 查询机制:支持 Ad-hoc 查询和部分求值,输出结构化的 JSON 决策结果。