2. OPA基础回顾:Rego策略语言核心概念、OPA架构、数据模型与查询

在深入Helm发布集成之前,必须牢固掌握OPA(Open Policy Agent)的核心基础。本章将系统回顾Rego策略语言的核心概念、OPA的整体架构、数据模型以及查询机制,为后续的自动化合规校验流水线设计奠定坚实的理论基础。

2.1 OPA架构概览

OPA是一个开源的、通用策略引擎,它将策略决策与业务逻辑执行分离。其核心架构遵循“决策请求-策略评估-决策响应”的闭环模型。

OPA 核心架构与决策流程 OPA 核心架构与决策流程 外部系统 (K8s API / Helm / App) 决策请求 OPA 引擎 Rego 策略评估 查询接口 决策响应 执行方 允许/拒绝 数据加载与策略分发 JSON/YAML 数据 (集群状态、配置) Rego 策略 Bundle (.rego 文件) Bundle 加载器 (HTTP / 文件系统)
架构要点: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) 将策略部分求值,生成针对特定输入的简化策略。 大规模集群中预计算策略,减少运行时开销。
OPA 数据模型与查询流程 OPA 数据模型与查询流程 输入层 (input) Helm Values / K8s 对象 数据层 (data) 策略 Bundle + 外部数据 查询引擎 Rego 解释器 输出层 (result) JSON 决策结果(allow / deny / violations)
关键理解:在 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 决策结果。