3. 策略即代码(Policy as Code)概述:OPA/Gatekeeper、Kyverno、策略引擎在K8s中的角色

在云原生环境中,传统的手动审批和静态配置文件已无法满足安全、合规与运维效率的要求。策略即代码(Policy as Code, PaC) 将治理规则、安全约束和运维最佳实践以声明式代码的形式表达,并通过策略引擎在 Kubernetes 集群中自动执行。本章聚焦三大主流策略引擎:OPA/Gatekeeper、Kyverno 以及通用策略引擎在 K8s 中的核心角色。

3.1 为什么 K8s 需要策略即代码?

Kubernetes 的声明式 API 和动态准入控制为策略执行提供了天然接口。PaC 解决了以下关键问题:

  • 安全基线:禁止特权容器、限制 hostPath 挂载、强制只读根文件系统。
  • 合规审计:确保所有命名空间包含指定标签(如 cost-center、environment)。
  • 资源治理:强制设置 CPU/内存 limits 和 requests,防止资源争抢。
  • 运维护栏:禁止使用 latest 镜像标签、限制镜像仓库来源。
  • 多租户隔离:确保非管理员用户无法修改集群关键组件。
核心价值:策略即代码将治理从“人治”转变为“代码治”,实现可版本控制、可审计、可自动测试的合规体系。

3.2 策略引擎在 K8s 中的工作角色

策略引擎通常以 动态准入 Webhook 的形式集成到 K8s API 请求链路中。当用户提交资源(如 Pod、Deployment、Service)时,API Server 在持久化之前调用 Webhook,策略引擎评估请求并返回 allowed 或 denied。

策略引擎在 K8s 准入控制中的角色 用户 / CI API Server 策略引擎 (Admission Webhook) etcd 创建/更新 准入审查 允许/拒绝 持久化(仅允许时) 流程说明 1. 用户/CI 提交资源清单(如 kubectl apply) 2. API Server 拦截请求,调用策略引擎 Webhook 3. 策略引擎评估约束,返回 allowed 或 denied 4. 仅当 allowed 时,API Server 将资源写入 etcd

3.3 三大策略引擎对比

特性 OPA / Gatekeeper Kyverno 通用策略引擎
策略语言 Rego(声明式查询语言) YAML 清单(无新语言) 多种(CEL、Lua、自定义)
学习曲线 中高(需学习 Rego) 低(K8s 原生 YAML 风格) 视引擎而定
部署方式 Gatekeeper 作为 Webhook 单个 Pod 作为 Webhook 独立服务或 Sidecar
策略模板 ConstraintTemplate + Constraint ClusterPolicy / Policy 自定义 CRD
突变能力 有限(需额外配置) 原生支持(Mutate 规则) 视引擎而定
社区生态 CNCF 毕业项目,生态丰富 CNCF 孵化项目,增长迅速 较分散
适用场景 复杂逻辑、跨集群策略 K8s 原生团队、快速上手 异构环境、自定义需求

3.4 OPA / Gatekeeper 深度解析

开放策略代理(OPA) 是一个通用的策略引擎,使用 Rego 语言表达策略。Gatekeeper 是 OPA 在 K8s 上的原生集成实现,作为准入 Webhook 运行。

3.4.1 核心组件

  • ConstraintTemplate:定义策略逻辑(Rego 代码)和参数 schema。
  • Constraint:实例化模板,传入具体参数(如允许的镜像仓库列表)。
  • Gatekeeper Webhook:拦截 API 请求,执行所有匹配的 Constraint。

3.4.2 示例:禁止特权容器

# ConstraintTemplate: 定义 Rego 逻辑
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
  name: k8spspprivilegedcontainer
spec:
  crd:
    spec:
      names:
        kind: K8sPSPPrivilegedContainer
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8spspprivilegedcontainer
        violation[{"msg": msg}] {
          container := input.review.object.spec.containers[_]
          container.securityContext.privileged
          msg := sprintf("Privileged container %v is not allowed", [container.name])
        }
---
# Constraint: 应用策略
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPPrivilegedContainer
metadata:
  name: no-privileged-containers
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]
注意:Rego 语法对新手有一定门槛。建议从 Gatekeeper 内置的 k8spsp 模板库开始,逐步自定义。

3.5 Kyverno 深度解析

Kyverno 是专为 Kubernetes 设计的策略引擎,策略使用纯 YAML 编写,无需学习新语言。它同时支持 验证(Validate)、突变(Mutate) 和 生成(Generate) 三种策略类型。

3.5.1 策略类型

类型 作用 示例
Validate 拒绝不符合规则的资源 禁止 latest 镜像标签
Mutate 自动修改资源字段 自动添加 app.kubernetes.io/name 标签
Generate 根据规则创建新资源 为每个命名空间自动创建 NetworkPolicy

3.5.2 示例:强制镜像标签不为 latest

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-latest-tag
spec:
  validationFailureAction: Enforce
  rules:
    - name: require-image-tag
      match:
        any:
          - resources:
              kinds:
                - Pod
      validate:
        message: "Using 'latest' tag for image is not allowed."
        pattern:
          spec:
            containers:
              - image: "!*:latest"
最佳实践:Kyverno 的 validationFailureAction 可设置为 Audit 模式,先观察策略影响,再切换为 Enforce 强制执行。

3.6 策略引擎选型建议

策略引擎选型决策树 团队熟悉 Rego? OPA / Gatekeeper Kyverno 是 否 补充考量 • 需要突变能力?→ Kyverno 原生支持;Gatekeeper 需额外配置 • 已有 OPA 投资?→ 继续使用 Gatekeeper 保持统一

3.7 策略即代码的 SRE 视角

从 SRE 角度看,策略引擎是 回滚护栏 和 错误预算 的底层执行者:

  • 回滚护栏:策略可以禁止回滚到不符合安全基线的旧版本镜像,或强制回滚时必须保留审计日志。
  • 错误预算:策略可以限制变更频率(如每天最多 5 次 Deployment 更新),防止过度消耗错误预算。
  • SLO 保护:策略可以拒绝可能影响 SLO 的配置(如移除健康检查探针、降低副本数至 1)。
关键结论:策略即代码不是安全团队的专属工具,而是 SRE 实现自动化治理、减少人为失误、保障服务等级目标的核心基础设施。