4. 策略即代码(Policy as Code)概述:OPA、Rego语言、与Prometheus规则的结合点
在云原生可观测性体系中,Prometheus 规则(告警规则与记录规则)的变更频率高、影响面广。传统的手动审批或静态配置文件管理方式难以应对多租户场景下的配额合规与回滚安全需求。策略即代码(Policy as Code, PaC) 将治理逻辑从人工判断和硬编码中剥离,以可编程、可测试、可版本控制的方式嵌入 CI/CD 流水线。本章聚焦 OPA(Open Policy Agent)、Rego 语言及其与 Prometheus 规则的结合点,为后续“回滚护栏”与“租户配额校准”奠定策略层基础。
4.1 策略即代码的核心价值
策略即代码并非单一工具,而是一种将组织策略(安全、合规、配额、命名规范)转化为可执行代码的工程实践。其核心价值体现在三个维度:
| 维度 | 传统方式 | 策略即代码 |
|---|---|---|
| 变更管理 | 人工审核、邮件审批、事后审计 | 自动化准入、预检、版本化、可回滚 |
| 一致性 | 依赖个人经验,不同环境策略漂移 | 同一份代码,跨环境执行结果一致 |
| 可观测性 | 策略执行结果难以追踪 | 决策日志结构化,可审计、可告警 |
4.2 OPA:云原生策略引擎的事实标准
OPA(Open Policy Agent)是一个开源的、通用的策略引擎,由 Cloud Native Computing Foundation(CNCF)孵化。它不绑定任何特定系统,通过统一的 决策请求/响应 模型与各类服务集成。
- 解耦策略与业务逻辑: 业务服务无需内嵌策略判断代码,只需向 OPA 发送 JSON 格式的查询请求,OPA 返回 Allow/Deny 或更复杂的结构化决策。
- 声明式策略语言 Rego: OPA 使用 Rego 语言编写策略,Rego 专注于“数据应该是什么样子”,而非“如何遍历数据”。
- 高性能与缓存: OPA 支持增量更新和决策缓存,适合在 CI/CD 流水线或 API 网关中高频调用。
4.3 Rego 语言基础与策略结构
Rego 是一种受 Datalog 启发的声明式查询语言。理解 Rego 的关键在于掌握其 规则(Rule) 和 表达式(Expression) 的运作方式。
4.3.1 基本语法要素
| 概念 | 说明 | 示例 |
|---|---|---|
| 规则 | 定义一组条件,当条件满足时规则为真 | allow { input.metric == "cpu_usage" } |
| 变量 | 以 = 绑定值,支持模式匹配 |
name := input.alertname |
| 迭代 | 使用 some 关键字遍历集合 |
some i; input.rules[i].severity == "critical" |
| 内置函数 | 提供字符串、正则、时间等操作 | startswith(input.record, "node_") |
4.3.2 一个完整的 Rego 策略示例
以下策略检查 Prometheus 告警规则中是否包含必要的 team 标签,且 severity 值必须为 critical、warning 或 info 之一:
package prometheus.rules.quota
import future.keywords.if
import future.keywords.in
# 允许通过的规则:必须包含 team 标签,且 severity 合法
allow if {
input.kind == "PrometheusRule"
some rule in input.spec.groups[_].rules
rule.labels.team != ""
rule.labels.severity in {"critical", "warning", "info"}
}
# 拒绝原因:缺失 team 标签
deny[{"msg": "规则 " + rule.alert + " 缺少 team 标签"}] if {
some rule in input.spec.groups[_].rules
rule.labels.team == ""
}
# 拒绝原因:severity 不合法
deny[{"msg": "规则 " + rule.alert + " 的 severity 不合法"}] if {
some rule in input.spec.groups[_].rules
not rule.labels.severity in {"critical", "warning", "info"}
}
deny 规则通常返回一个包含详细原因的对象列表,而非简单的 true/false。这有助于在 CI 流水线中生成可读性强的错误报告。
4.4 OPA 与 Prometheus 规则的结合点
OPA 与 Prometheus 规则的结合并非直接修改 Prometheus 运行时配置,而是在 规则发布前 进行策略校验。结合点主要分布在三个环节:
4.5 结合点详细说明
上述架构图中的三个结合点,分别对应不同的防护阶段:
| 结合点 | 触发时机 | 校验内容示例 | 失败后果 |
|---|---|---|---|
| Git 预提交 | 本地 git commit 前 |
规则命名是否包含租户前缀 | 提交被拒绝,本地修复 |
| CI 准入 | PR 创建或更新时 | 租户配额是否超限、severity 是否合法 | PR 无法合并,CI 标记失败 |
| GitOps 预检 | ArgoCD 同步前 | 规则是否被篡改、是否匹配当前集群版本 | 同步暂停,触发告警 |
4.6 Rego 策略与 Prometheus 规则的数据模型映射
要让 OPA 理解 Prometheus 规则,需要将 PrometheusRule CRD(Custom Resource Definition)的 YAML 结构映射为 Rego 可以处理的 input 对象。典型的映射关系如下:
# PrometheusRule YAML 简化结构
input = {
"apiVersion": "monitoring.coreos.com/v1",
"kind": "PrometheusRule",
"metadata": {
"name": "node-high-cpu",
"namespace": "monitoring",
"labels": {
"tenant": "team-alpha"
}
},
"spec": {
"groups": [
{
"name": "node-exporter",
"rules": [
{
"alert": "NodeCPUUsageHigh",
"expr": "100 - (avg by(instance) (rate(node_cpu_seconds_total{mode='idle'}[5m])) * 100) > 80",
"for": "5m",
"labels": {
"severity": "critical",
"team": "team-alpha"
},
"annotations": {
"summary": "Node CPU usage is high"
}
}
]
}
]
}
}
在 Rego 中,通过 input.spec.groups[i].rules[j] 即可遍历所有规则。这种直接映射使得策略编写非常直观。
4.7 本章小结
- 策略即代码 将治理逻辑代码化,解决了传统人工审核的效率和一致性问题。
- OPA 作为 CNCF 毕业项目,提供统一的策略决策层,与 Prometheus 规则治理天然契合。
- Rego 语言通过声明式规则表达策略意图,支持复杂的条件判断和数据迭代。
- OPA 与 Prometheus 规则的结合点集中在 Git 预提交、CI 准入 和 GitOps 预检 三个环节,形成多级防护。
- 理解 PrometheusRule 的 JSON 数据模型是编写 Rego 策略的前提。