3. Policy as Code (PaC) 基础:定义、区别与云原生价值

Policy as Code(PaC)是将策略声明、合规规则与治理逻辑以机器可读的代码形式进行管理、版本化、测试与自动执行的工程实践。它并非简单的“把策略写成YAML”,而是将策略从人工审批的静态文档,转变为可集成到CI/CD流水线中的动态执行单元。

3.1 PaC 的核心定义

PaC 通过声明式语言(如 Rego、CUE、CEL)或通用编程语言(如 Go、Python)的 DSL,将策略抽象为可重复评估的规则集合。其核心特征包括:

  • 声明式表达:策略描述“期望状态”,而非“如何执行”。
  • 版本化与审计:策略存储在 Git 仓库中,每次变更都有完整历史记录。
  • 自动化执行:策略在部署前、部署中或运行时自动触发评估。
  • 可测试性:策略可以像软件代码一样编写单元测试与集成测试。
关键概念:PaC 将策略从“人治”转向“代码治”,使合规性成为软件交付流水线中的一等公民。

3.2 与传统策略管理的区别

传统策略管理依赖静态文档、人工审核与事后检查,而 PaC 实现了策略的自动化、可编程与持续验证。下表从多个维度对比两者的差异:

对比维度 传统策略管理 Policy as Code
表达形式 Word/PDF 文档、邮件通知 代码文件(.rego, .cue, .yaml)
存储方式 共享文件夹、Wiki 页面 Git 仓库(版本控制、分支管理)
执行时机 事后审计、定期检查 实时拦截(CI/CD 门禁、准入控制)
变更流程 邮件审批、会议讨论 Pull Request + Code Review + 自动化测试
可测试性 无测试机制 单元测试、集成测试、模拟评估
回滚能力 困难,依赖人工记忆 git revert 即可回滚到任意历史版本
扩展性 随组织规模线性增长,人力成本高 策略即代码,可复用、可组合、可共享
常见误区:PaC 不是简单的“把策略写成 YAML 文件”。如果 YAML 文件仍然需要人工逐行检查、没有自动化评估引擎,那它本质上还是传统策略管理,只是换了一种文件格式。

3.3 PaC 在云原生中的价值

云原生环境具有动态性、多租户、微服务化与基础设施即代码(IaC)等特征,传统策略管理方式难以应对其快速变化与复杂依赖。PaC 在云原生中的核心价值体现在以下四个层面:

  1. 安全左移与合规内建:策略在代码提交、镜像构建、部署编排阶段即执行检查,避免不合规配置进入生产环境。例如,禁止容器以 root 用户运行、限制镜像来源为私有仓库。
  2. 故障隔离的自动化保障:通过 PaC 定义“升级窗口”、“最大并发数”、“跨 AZ 分布”等策略,自动拒绝违反隔离规则的变更请求,从源头防止故障扩散。
  3. 多集群统一治理:在混合云或多集群场景下,PaC 作为统一的策略控制面,确保所有集群遵循相同的安全基线、资源配额与网络策略。
  4. 审计与可观测性增强:每次策略评估都会产生结构化日志,包含决策结果、输入上下文与触发规则,为事后审计和故障根因分析提供精确数据。
PaC 在云原生故障隔离中的价值流程 变更请求 PaC 策略引擎 (Rego/CUE/CEL) 策略仓库 ✅ 允许通过 ❌ 拒绝并告警 故障隔离保障 升级窗口 / 并发限制 策略即代码 自动化隔离

3.4 典型 PaC 工具生态

云原生领域已形成丰富的 PaC 工具链,覆盖策略定义、评估引擎与集成平台。下表列出主流工具及其适用场景:

工具 策略语言 主要场景 集成方式
Open Policy Agent (OPA) Rego Kubernetes 准入控制、API 授权、IaC 扫描 Sidecar / DaemonSet / Go SDK
Kyverno YAML (DSL) Kubernetes 原生策略管理 Admission Webhook / CLI
Sentinel Sentinel DSL HashiCorp 生态(Terraform, Vault, Consul) Enterprise 集成
Checkov / tfsec Python / HCL IaC 静态扫描(Terraform, CloudFormation) CLI / CI/CD 插件
Conftest Rego 配置文件与 IaC 策略测试 CLI / CI/CD 流水线
选型建议:如果团队已深度使用 Kubernetes,优先考虑 Kyverno(学习成本低)或 OPA Gatekeeper(生态成熟);如果策略需要跨平台(K8s + 云 API + 微服务),OPA 的通用性更强。
云原生 PaC 工具生态架构 策略定义层:Rego / CUE / CEL / YAML DSL 评估引擎层:OPA / Kyverno / Sentinel / Checkov 集成接入层:Admission Webhook / CLI / CI/CD Pipeline / SDK 分层解耦,灵活组合

3.5 一个简单的 PaC 策略示例

以下使用 OPA/Rego 语言定义一个“升级窗口控制”策略,限制只能在非高峰时段(UTC 时间 02:00–06:00)执行 Deployment 更新:

package kubernetes.admission

import future.keywords.if
import future.keywords.in

# 定义允许的升级窗口(UTC 时间)
allowed_hours := {h | h >= 2; h < 6}

# 拒绝在升级窗口外变更 Deployment
deny[msg] if {
    input.request.operation == "UPDATE"
    input.request.kind.kind == "Deployment"
    time_hour := time.now_ns() / 3600000000000 % 24
    not allowed_hours[time_hour]
    msg := sprintf("Deployment 更新被拒绝:当前 UTC 时间 %d:00 不在允许的升级窗口 (02:00-06:00) 内", [time_hour])
}
策略解读:该策略在 Kubernetes 准入控制器中实时拦截 Deployment 更新请求。如果当前时间不在 02:00–06:00(UTC),则返回拒绝消息。通过 PaC,升级窗口控制从“运维人员手动检查”变为“系统自动强制”,从根本上消除了人为疏忽导致的故障风险。