2. OPA 核心概念:Policy、Rego 语言、Data、Input、Output 模型详解

在深入 OPA 与 Helm Chart 的集成之前,必须透彻理解 OPA 的五大核心概念:Policy(策略)、Rego 语言、Data(数据)、Input(输入) 和 Output(输出)。这五个要素构成了 OPA 决策引擎的完整工作闭环,也是后续编写合规策略的基础。

核心理解:OPA 本质上是一个 策略决策引擎,它不负责执行策略(如拦截请求),而是根据 Input + Data 通过 Rego 策略 计算出 Output(允许/拒绝/原因)。这种“策略与执行分离”的架构是 OPA 在云原生合规治理中的最大优势。

2.1 五大核心概念总览

下表从定义、来源、作用三个维度对比了 OPA 的五个核心概念,帮助你快速建立整体认知:

概念 定义 来源/载体 在决策中的作用
Policy 用 Rego 语言编写的规则集合,定义“什么是合规” .rego 文件、ConfigMap、Bundle 决策逻辑的载体,决定如何评估 Input 和 Data
Rego 语言 OPA 专用的声明式查询语言,基于 Datalog 嵌入在 Policy 文件中 提供策略编写语法,支持逻辑推理和集合操作
Data 全局上下文数据,通常是 JSON/YAML 文档 外部加载(文件、API、Bundle) 提供策略评估所需的“背景知识”,如白名单、集群配置
Input 每次决策请求的即时数据 调用 OPA API 时传入 代表被评估的对象(如一个 Helm Release 的 values.yaml)
Output 策略评估的结果 OPA 返回的 JSON 响应 包含决策(allow/deny)及详细的违规原因
OPA 核心概念关系图 OPA 决策引擎 Input(输入) Helm Values / K8s 资源 Policy + Rego 语言 合规规则定义 Data(数据) 白名单 / 集群配置 / 外部数据 Output(输出) allow / deny + 原因 核心公式:Output = Policy(Input, Data) —— 策略 + 输入 + 数据 → 决策结果 OPA 本身不执行决策结果,只返回决策结果给外部系统(如 Admission Controller)

2.2 Policy(策略)—— 合规规则的载体

Policy 是 OPA 的核心产物,由一组 Rego 规则组成。在 Helm Chart 合规治理场景中,Policy 通常定义以下内容:

  • 镜像来源合规:只允许从指定 Registry 拉取镜像。
  • 资源限制合规:所有容器必须设置 CPU/Memory 的 requests 和 limits。
  • 安全上下文合规:禁止容器以 root 用户运行。
  • 网络策略合规:必须为 Service 配置 NetworkPolicy。
最佳实践:在 Helm 治理中,建议将 Policy 文件打包为 OPA Bundle,通过 ConfigMap 或 OPA 插件动态加载到集群中,实现策略的热更新。

2.3 Rego 语言 —— 声明式策略语言

Rego 是 OPA 的原生查询语言,受 Datalog 启发,采用声明式范式。与传统的命令式语言(如 Python、Go)不同,Rego 只描述“想要什么结果”,而不描述“如何计算”。

2.3.1 Rego 核心语法要素

语法要素 示例 说明
规则(Rule) allow { ... } 定义一条决策规则,条件满足时规则为 true
表达式(Expression) input.kind == "Deployment" 比较、赋值、集合操作等逻辑判断
迭代(Iteration) some i; input.spec.containers[i] 遍历数组或集合中的元素
内置函数 count(), split(), regex.match() 字符串、正则、集合等常用操作
默认值 default allow = false 设置规则的默认值,避免未定义行为

2.3.2 一个完整的 Rego 策略示例

以下策略检查 Helm Release 中所有容器是否设置了资源限制:

package helm.kubernetes.resources

# 默认拒绝
default allow = false

# 规则:允许的条件是所有容器都设置了 limits
allow {
    # 遍历所有容器
    every container in input.spec.template.spec.containers {
        container.resources.limits.cpu != ""
        container.resources.limits.memory != ""
    }
}

# 违规详情:返回未设置资源限制的容器列表
deny[msg] {
    some container in input.spec.template.spec.containers
    not container.resources.limits.cpu
    msg = sprintf("容器 %v 未设置 CPU 限制", [container.name])
}

deny[msg] {
    some container in input.spec.template.spec.containers
    not container.resources.limits.memory
    msg = sprintf("容器 %v 未设置 Memory 限制", [container.name])
}
常见误区:Rego 中的变量一旦赋值就不可变(immutable)。不要尝试在规则内部修改变量值,而是通过迭代和条件组合来表达逻辑。

2.4 Data(数据)—— 策略评估的上下文

Data 是 OPA 在评估策略时使用的全局数据,通常以 JSON 或 YAML 格式加载。Data 与 Input 的区别在于:Data 是静态的、全局的,而 Input 是动态的、每次请求不同。

2.4.1 Data 的常见来源

  • 文件系统:OPA 启动时加载本地 JSON/YAML 文件。
  • Bundle:从 HTTP 服务器拉取打包的 Data + Policy 文件。
  • API 拉取:通过 opa.data API 动态注入数据。
  • Kubernetes ConfigMap:将 Data 存储在 ConfigMap 中挂载到 OPA 容器。

2.4.2 在 Helm 治理中的 Data 示例

假设我们有一个允许的镜像仓库白名单 Data 文件 allowed_registries.json:

{
    "allowed_registries": [
        "docker.io/mycompany",
        "gcr.io/mycompany",
        "harbor.internal.mycompany.com"
    ]
}

在 Rego 策略中引用 Data:

package helm.kubernetes.images

default allow = false

allow {
    some container in input.spec.template.spec.containers
    registry := split(container.image, "/")[0]
    registry == data.allowed_registries[_]
}

deny[msg] {
    some container in input.spec.template.spec.containers
    registry := split(container.image, "/")[0]
    not registry == data.allowed_registries[_]
    msg = sprintf("容器 %v 使用了未授权的镜像仓库: %v", [container.name, registry])
}

2.5 Input(输入)—— 被评估的对象

Input 是每次调用 OPA 决策 API 时传入的即时数据。在 Helm Chart 合规治理中,Input 通常是一个 Kubernetes 资源对象(如 Deployment、Service)或 Helm 渲染后的 values.yaml。

2.5.1 Input 的结构

Input 必须是一个 JSON 对象,OPA 通过 input 关键字访问。以下是一个典型的 Helm Release 的 Input 示例:

{
    "apiVersion": "apps/v1",
    "kind": "Deployment",
    "metadata": {
        "name": "my-app",
        "namespace": "production"
    },
    "spec": {
        "template": {
            "spec": {
                "containers": [
                    {
                        "name": "app",
                        "image": "docker.io/mycompany/app:v1.0",
                        "resources": {
                            "limits": {
                                "cpu": "500m",
                                "memory": "512Mi"
                            }
                        }
                    }
                ]
            }
        }
    }
}
集成要点:在 Helm Chart 发布流程中,OPA 的 Input 通常由 Kubernetes Admission Webhook 或 Helm 插件 在资源创建/更新时自动构造并发送。确保 Input 包含完整的资源定义,否则策略可能因缺少字段而误判。

2.6 Output(输出)—— 决策结果

Output 是 OPA 执行策略后返回的 JSON 响应。Output 的结构由策略中的规则决定,通常包含以下内容:

输出字段 类型 说明
allow boolean 是否允许该操作(true/false)
deny array[string] 违规原因列表,每个元素是一条具体的违规描述
warn array[string] 警告信息,不阻止操作但提示风险
audit object 审计日志,记录决策的详细上下文

2.6.1 一个典型的 Output 示例

{
    "allow": false,
    "deny": [
        "容器 app 未设置 CPU 限制",
        "容器 app 使用了未授权的镜像仓库: docker.io/unauthorized"
    ],
    "warn": [
        "建议为容器 app 设置 livenessProbe"
    ]
}
OPA 决策流程:Input + Data → Policy → Output 阶段 1:输入 Input + Data 就绪 阶段 2:策略评估 Rego 规则逐条匹配 阶段 3:输出 allow / deny + 原因 决策流程详细说明 1. 外部系统(如 Admission Controller)构造 Input(K8s 资源 JSON)并发送给 OPA。 2. OPA 将 Input 与已加载的 Data(白名单、配置等)合并为评估上下文。 3. OPA 引擎执行 Rego 策略,逐条匹配规则,计算 allow、deny、warn 等结果。 4. OPA 返回 Output JSON 给外部系统,外部系统根据 allow 字段决定是否放行。 5. 整个流程在毫秒级完成,支持高并发决策请求。

2.7 核心概念在 Helm Chart 治理中的映射

将上述五个概念映射到 Helm Chart 发布合规治理场景中,可以更直观地理解它们的作用:

OPA 概念 在 Helm 治理中的具体体现
Policy 一组 Rego 文件,定义“允许哪些镜像”、“必须设置资源限制”、“禁止 hostNetwork”等规则
Rego 语言 编写上述规则的语法,支持遍历容器、检查字段、正则匹配等操作
Data 公司级的镜像白名单、允许的命名空间列表、集群级别的安全基线配置
Input Helm 渲染后的 Kubernetes 资源 YAML/JSON,包含 Deployment、Service、Ingress 等
Output 决策结果:如果 allow=false,则 Helm Release 发布被拒绝,并返回具体的违规原因
关键洞察:在 Helm Chart 治理中,Data 是静态的(公司策略),Input 是动态的(每次发布的 Chart 不同),Policy 是桥梁,将静态规则与动态输入结合,输出合规决策。这种分离使得策略可以集中管理、复用,而无需修改 Helm Chart 本身。