3. 策略即代码(PaC)概念解析

策略即代码(Policy as Code, PaC)是云原生治理的核心实践,它将传统上由人工审核、文档记录或硬编码在应用中的策略规则,转化为可版本控制、可自动化测试、可编程执行的代码。在本章中,我们将深入剖析 PaC 的本质、与传统策略管理的差异,以及 OPA 与 Rego 语言在配额管理中的关键作用。

3.1 什么是策略即代码(PaC)

策略即代码是一种将组织策略(如安全规则、合规要求、资源配额限制)以机器可读的声明式语言进行描述,并通过自动化引擎在系统运行时进行持续评估的方法论。其核心思想是“策略即软件”,将策略视为与应用程序代码同等重要的资产。

核心特征:
  • 声明式:策略描述“想要什么状态”,而非“如何实现”。
  • 版本化:策略存储在 Git 等版本控制系统中,支持审计、回滚与协作。
  • 自动化:策略评估集成到 CI/CD 流水线或运行时准入控制器中,无需人工干预。
  • 可测试:策略可以像代码一样编写单元测试和集成测试。

3.2 传统策略管理与 PaC 的对比

传统策略管理通常依赖静态文档、人工审核或硬编码逻辑,而 PaC 则通过代码化实现了策略的自动化与动态化。下表从多个维度对比两者的关键差异:

对比维度 传统策略管理 策略即代码(PaC)
表达形式 自然语言文档、PDF、邮件 声明式代码(如 Rego、JSON/YAML)
存储方式 文件服务器、Wiki、共享目录 版本控制系统(Git)
执行时机 事后审计、人工检查 实时(准入控制)、持续(审计)
变更流程 邮件审批、会议讨论 Pull Request + CI 流水线
可测试性 几乎不可测试 支持单元测试与集成测试
一致性 依赖个人理解,易产生偏差 机器执行,结果可重复
扩展性 随系统增长而崩溃 水平扩展,支持大规模集群
实践建议:在迁移到 PaC 时,建议从“最频繁变更”或“风险最高”的策略开始,例如资源配额限制和命名空间隔离规则,逐步替换传统人工审核流程。

3.3 OPA(Open Policy Agent)与 Rego 语言简介

OPA(Open Policy Agent)是 CNCF 毕业项目,也是目前云原生领域最流行的通用策略引擎。它通过将策略决策与策略执行解耦,为微服务、Kubernetes、CI/CD 等场景提供统一的策略评估能力。

3.3.1 OPA 架构概览

OPA 的核心是一个轻量级的策略评估引擎,它接收结构化数据(输入)和策略规则(Rego 代码),输出决策结果(允许/拒绝/修改)。下图展示了 OPA 在 Kubernetes 准入控制中的典型架构:

OPA 在 Kubernetes 准入控制中的架构 OPA 在 Kubernetes 准入控制中的架构 用户 / 客户端 Kubernetes API Server OPA 策略引擎 策略数据存储 创建/更新资源 准入审查请求 读取策略 允许/拒绝决策 响应结果 说明: 1. 用户通过 kubectl 或 API 向 API Server 发送资源请求。 2. API Server 将请求转换为 AdmissionReview 并发送给 OPA。 3. OPA 根据 Rego 策略和缓存数据评估,返回 allow/deny 决策。

3.3.2 Rego 语言核心概念

Rego 是 OPA 专用的声明式查询语言,灵感来源于 Datalog。它专注于表达“如果……那么……”的逻辑规则,而非编写命令式流程。以下是一个简单的 Rego 策略示例,用于限制命名空间中的 Pod 数量:

package kubernetes.admission

import data.kubernetes.namespaces

# 定义默认决策:允许
default allow := false

# 规则:如果请求来自受信任的命名空间,则允许
allow {
    input.request.operation == "CREATE"
    input.request.kind.kind == "Pod"
    namespace := input.request.namespace
    count_pods(namespace) < 10
}

# 辅助函数:计算命名空间中现有 Pod 数量
count_pods(namespace) := count {
    pods := namespaces[namespace].pods
    count := count(pods)
}
注意:Rego 语言对缩进敏感,且不支持循环和可变变量。所有逻辑必须通过递归或集合操作实现。初学者容易混淆“=”与“:=”的用法,前者用于相等性检查,后者用于变量赋值。

3.4 PaC 在配额管理中的角色

在资源配额管理场景中,PaC 扮演着“动态策略执行者”的角色。与 Kubernetes 原生 ResourceQuota 的静态限制不同,PaC 可以实现更精细、更灵活的配额控制:

  • 基于上下文的配额:根据命名空间标签、团队归属、环境类型(dev/staging/prod)动态调整配额上限。
  • 配额预留与抢占:支持“先到先得”或“高优先级预留”策略,而非简单的硬限制。
  • 配额审计与报告:记录每次配额决策的上下文,用于成本分析和容量规划。
  • 多维度配额:同时考虑 CPU、内存、GPU、存储、网络带宽等多个维度的组合限制。

下图展示了 PaC 在配额管理中的决策流程:

PaC 在配额管理中的决策流程 PaC 在配额管理中的决策流程 输入:资源请求 OPA 策略引擎 数据源:集群状态 策略库:Rego 规则 决策输出 请求数据 实时查询 加载规则 评估结果 决策类型 允许 拒绝 配额管理场景:当用户请求创建 Pod 时,OPA 结合集群当前资源使用量和 Rego 策略,动态判断是否允许该请求,并返回详细的拒绝原因。
最佳实践:在配额管理中使用 PaC 时,建议将“配额上限”与“配额使用率”分开管理。配额上限作为静态配置存储在 ConfigMap 中,而配额使用率通过 OPA 实时查询集群状态获取。这样既保证了策略的灵活性,又避免了频繁修改 Rego 代码。

3.5 本章小结