3. Kyverno 策略模型:策略(Policy)与规则(Rule)结构、match/exclude条件、mutate/validate/generate动作类型

Kyverno 的策略模型是其核心设计哲学——“策略即代码”的具象化体现。理解策略(Policy)与规则(Rule)的层级关系、匹配/排除条件以及三大动作类型,是编写生产级策略的基石。本章将拆解这一模型,帮助你在云原生运行基线核验中精准表达安全与合规意图。

3.1 策略与规则的层级结构

一个 Kyverno 策略(Policy)是一个顶层资源,内部包含一个或多个规则(Rule)。规则是策略的执行单元,每个规则独立定义匹配条件、排除条件和动作。策略分为两种作用域:

策略类型 作用域 典型用途
ClusterPolicy 集群级别,影响所有命名空间 全局基线核验、集群安全策略
Policy 命名空间级别,仅作用于指定命名空间 租户隔离、环境特定规则

策略的 YAML 骨架如下:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-pod-labels
spec:
  validationFailureAction: Enforce   # 或 Audit
  rules:
    - name: check-required-labels
      match:
        resources:
          kinds:
            - Pod
      exclude:
        resources:
          namespaces:
            - kube-system
      validate:
        message: "Pod 必须包含 'app.kubernetes.io/name' 标签"
        pattern:
          metadata:
            labels:
              app.kubernetes.io/name: "?*"
关键概念: 一个策略可以包含多条规则,规则按顺序评估。如果一条规则匹配并执行动作,后续规则默认继续执行(除非使用 preconditions 或 context 控制流程)。

3.2 match 与 exclude 条件

每个规则必须定义 match 条件,exclude 为可选。Kyverno 使用声明式资源选择器,支持按资源类型、标签、命名空间、名称、注解等维度进行筛选。

3.2.1 match 匹配策略

  • 资源类型(kinds): 支持核心 API 组(Pod、Service)和自定义资源(CRD)。
  • 标签选择器(selector): 使用标准 Kubernetes 标签表达式(matchLabels / matchExpressions)。
  • 命名空间(namespaces): 直接指定命名空间列表。
  • 名称(name): 支持通配符 * 和 ?。
  • 注解(annotations): 按注解键值对匹配。

3.2.2 exclude 排除策略

排除条件的语法与 match 完全一致。当资源同时满足 match 和 exclude 时,exclude 优先,规则不执行。典型排除场景:

  • 排除系统命名空间(kube-system、kyverno)
  • 排除特定标签的 Pod(如 tier: system)
  • 排除已存在的资源(使用 resource.operation 条件)
最佳实践: 在 match 中尽量缩小范围,在 exclude 中处理边界情况。避免使用过于宽泛的 match 导致性能开销。

3.3 三大动作类型:mutate / validate / generate

Kyverno 的规则动作决定了策略对匹配资源施加的影响。三种动作覆盖了从预防、修正到自动补全的完整策略生命周期。

动作类型 触发时机 核心行为 典型场景
validate Admission 请求时 校验资源是否符合预期模式,拒绝或审计不合规资源 强制只读根文件系统、禁止特权容器
mutate Admission 请求时(在 validate 之前) 自动修改资源字段,补全或覆盖配置 自动注入 Sidecar、添加安全上下文
generate 资源创建后(或按需触发) 基于源资源创建新资源,支持同步更新 自动创建 NetworkPolicy、生成命名空间配额

3.3.1 validate:安全基线的守门员

validate 动作支持两种模式:

  • pattern(模式匹配): 定义期望的资源字段值,支持通配符和条件表达式。
  • deny(拒绝规则): 使用 CEL(Common Expression Language)或原始条件表达式定义拒绝逻辑。
validate:
  message: "容器必须设置 CPU 和内存限制"
  pattern:
    spec:
      containers:
        - resources:
            limits:
              memory: "?*"
              cpu: "?*"

3.3.2 mutate:自动修正与注入

mutate 动作在资源持久化之前修改其内容,用户无感知。支持两种策略:

  • patchStrategicMerge: 使用 Kubernetes 战略合并补丁,适合覆盖或添加字段。
  • patchesJson6902: 使用 JSON Patch 标准,支持精确的增删改操作。
mutate:
  patchStrategicMerge:
    spec:
      containers:
        - (name): "*"
          securityContext:
            readOnlyRootFilesystem: true

3.3.3 generate:自动化资源供给

generate 动作在源资源创建后,自动生成一个或多个关联资源。支持 synchronize: true 实现源资源与生成资源的同步更新。

generate:
  kind: NetworkPolicy
  name: default-deny
  namespace: "{{request.object.metadata.name}}"
  synchronize: true
  data:
    spec:
      podSelector: {}
      policyTypes:
        - Ingress
        - Egress
注意: generate 动作不会在 Admission 阶段拦截请求,而是通过 Kyverno 的控制器异步创建资源。因此,它不适用于需要即时拒绝的场景。

3.4 策略模型整体架构

下图展示了 Kyverno 策略模型从接收到执行的完整流程,以及 match/exclude 条件与三大动作的协作关系。

Kyverno 策略模型执行流程 ClusterPolicy / Policy 包含一个或多个规则(Rule),按顺序评估 Rule:check-security-context 每个规则独立定义 match / exclude / 动作 match 条件 kinds / selector / namespaces / name 匹配则进入动作评估 exclude 条件 kinds / selector / namespaces / name 排除则跳过规则 动作类型:mutate → validate → generate(按顺序执行) mutate 自动修改资源字段 validate 校验并拒绝/审计 generate 异步创建关联资源

3.5 动作执行顺序与组合策略

当一条规则同时包含多个动作时(实际场景中通常一个规则只定义一个动作),Kyverno 遵循以下顺序:

  1. mutate 先执行:修改资源字段,为后续校验做准备。
  2. validate 后执行:校验修改后的资源是否符合预期。
  3. generate 异步执行:不阻塞 Admission 响应,由控制器后台处理。
组合策略示例: 先使用 mutate 自动添加 securityContext.readOnlyRootFilesystem: true,再使用 validate 确保该字段存在且为 true。这种组合实现了“自动修复 + 强制校验”的双重保障。

3.6 策略模型设计原则

  • 单一职责: 每个规则只做一件事(要么校验、要么修改、要么生成),便于测试和复用。
  • 最小权限匹配: match 条件尽量精确,避免影响无关资源。
  • 显式排除: 对系统组件、监控组件等特殊资源,在 exclude 中明确排除。
  • Audit 先行: 新策略先使用 validationFailureAction: Audit 观察影响,确认无误后再切换为 Enforce。
实战建议: 在编写策略时,先画出 match/exclude 的决策树,再选择动作类型。对于云原生运行基线核验,validate 是最常用的动作,配合 mutate 可以实现“自动修复不合规配置”的闭环。