4. 策略语法入门:Kyverno 策略 YAML 结构、match/exclude 规则、validate/mutate/generate 动作

Kyverno 策略本质上是 Kubernetes 自定义资源(CRD),使用标准的 YAML 清单定义。理解其语法结构是编写可靠策略的基础。本章将拆解策略的骨架、匹配/排除规则以及三种核心动作类型。

4.1 策略 YAML 顶层结构

一个完整的 Kyverno 策略由以下顶层字段构成:

字段必填说明
apiVersion是固定为 kyverno.io/v1
kind是ClusterPolicy(集群范围)或 Policy(命名空间范围)
metadata是名称、注解、标签
spec是策略核心定义,包含 rules 列表
spec.rules[]是规则数组,每条规则包含 match、exclude 和动作
关键区别: ClusterPolicy 作用于整个集群,Policy 仅作用于其所在的命名空间。在回滚流水线中,通常使用 ClusterPolicy 确保全局一致性。
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-image-signature
spec:
  rules:
  - name: check-signature
    match:
      resources:
        kinds:
        - Pod
    validate:
      message: "镜像必须经过签名验证"
      deny:
        conditions:
          any:
          - key: "{{ request.object.spec.containers[].image }}"
            operator: NotEquals
            value: "registry.example.com/signed/*"

4.2 match 与 exclude 规则:精准控制策略作用域

每条规则必须定义 match 条件,exclude 为可选。Kyverno 支持按资源类型、标签选择器、命名空间、名称模式等多种维度进行匹配。

4.2.1 match 规则

  • 资源类型(kinds): 支持核心 API 组和自定义资源,如 Pod、Deployment、Namespace。
  • 标签选择器(selector): 使用标准 Kubernetes 标签表达式 matchLabels 和 matchExpressions。
  • 命名空间(namespaces): 仅匹配指定命名空间中的资源。
  • 名称模式(names): 支持通配符 * 和 ?。
  • 注解(annotations): 按资源注解键值对匹配。

4.2.2 exclude 规则

结构与 match 完全相同,用于排除特定资源。在回滚场景中,常用 exclude 跳过系统命名空间或已标记为“紧急回滚”的资源。

最佳实践: 在回滚策略中,始终在 exclude 中添加 kube-system、kube-public 等系统命名空间,避免影响集群核心组件。
match:
  resources:
    kinds:
    - Pod
    - Deployment
    namespaces:
    - production
    - staging
    selector:
      matchLabels:
        app: my-service
exclude:
  resources:
    namespaces:
    - kube-system
    annotations:
      rollback-policy.kyverno.io/skip: "true"
match / exclude 规则匹配流程 K8s API 请求 match 条件匹配? kinds / selector / namespaces / annotations 跳过 继续 exclude 条件检查 匹配则跳过,不匹配则执行动作 执行 validate / mutate / generate

4.3 三大动作:validate、mutate、generate

Kyverno 提供三种核心动作,分别对应策略即代码的不同阶段:

动作触发时机行为回滚场景典型用途
validateAdmission 验证阶段检查资源是否符合规则,拒绝或允许验证回滚镜像标签是否存在于仓库
mutateAdmission 变更阶段自动修改资源字段(补丁)自动注入回滚注解、添加安全上下文
generate资源创建后创建关联资源(如 ConfigMap、NetworkPolicy)回滚时自动生成审计日志 ConfigMap

4.3.1 validate:准入控制与策略校验

validate 是使用最频繁的动作。支持两种模式:

  • deny 模式: 基于表达式引擎(CEL)或 JMESPath 条件,满足条件则拒绝请求。
  • pattern 模式: 定义期望的资源字段值,不匹配则拒绝。
validate:
  message: "回滚目标镜像必须来自受信任仓库"
  deny:
    conditions:
      any:
      - key: "{{ request.object.spec.template.spec.containers[0].image }}"
        operator: NotEquals
        value: "trusted-registry.internal/*"

4.3.2 mutate:自动修正与标准化

mutate 在资源持久化之前修改其内容。支持 JSON Patch(RFC 6902)和 strategic merge patch。

mutate:
  patchesJson6902: |-
    - op: add
      path: "/metadata/annotations/rollback-timestamp"
      value: "{{ time.now() }}"
    - op: replace
      path: "/spec/replicas"
      value: 3
注意: mutate 动作在回滚流水线中需谨慎使用。错误的补丁可能导致资源状态不一致。建议在 mutate 前先通过 validate 做前置检查。

4.3.3 generate:资源自动创建

generate 在匹配资源创建后,自动生成新的 Kubernetes 资源。常用于创建配套的监控、日志或网络策略。

generate:
  kind: ConfigMap
  name: rollback-audit-{{ request.object.metadata.name }}
  namespace: "{{ request.object.metadata.namespace }}"
  synchronize: true
  data:
    rollback-info: |
      resource: {{ request.object.metadata.name }}
      timestamp: {{ time.now() }}
      action: rollback-initiated

4.4 策略语法综合示例

以下是一个完整的 ClusterPolicy,结合了 match、exclude 和三种动作,用于回滚场景的镜像验证与审计:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: rollback-image-guard
spec:
  rules:
  - name: validate-rollback-image
    match:
      resources:
        kinds:
        - Deployment
        annotations:
          rollback.kyverno.io/triggered: "true"
    exclude:
      resources:
        namespaces:
        - kube-system
    validate:
      message: "回滚镜像必须包含 'rollback-' 前缀"
      pattern:
        spec:
          template:
            spec:
              containers:
              - image: "rollback-*"
  - name: annotate-rollback-time
    match:
      resources:
        kinds:
        - Deployment
    mutate:
      patchesJson6902: |-
        - op: add
          path: "/metadata/annotations/kyverno-rollback-time"
          value: "{{ time.now() }}"
  - name: generate-audit-configmap
    match:
      resources:
        kinds:
        - Deployment
    generate:
      kind: ConfigMap
      name: audit-{{ request.object.metadata.name }}
      namespace: "{{ request.object.metadata.namespace }}"
      data:
        event: "rollback-detected"
validate / mutate / generate 在 Admission 流程中的位置 Mutating Webhook mutate 动作执行 Validating Webhook validate 动作执行 etcd 持久化 资源写入存储 generate 动作 异步创建关联资源 mutate 先于 validate 执行;generate 在资源持久化后异步触发

4.5 常见语法陷阱与调试技巧

  • 变量引用: 使用 {{ }} 模板语法,注意 request.object 代表当前资源,request.oldObject 代表更新前的资源(仅 UPDATE 操作可用)。
  • JMESPath 表达式: 在 deny.conditions 中,key 字段支持 JMESPath 查询,如 spec.containers[?name=='app'].image | [0]。
  • 空值处理: 当字段不存在时,JMESPath 返回 null,可能导致条件判断异常。建议使用 contains() 或 has() 函数预检。
  • 策略冲突: 多个 ClusterPolicy 可能对同一资源生效,执行顺序由 Kyverno 内部排序决定。建议在规则名称中使用前缀控制优先级。
调试命令: 使用 kubectl kyverno test 在本地测试策略 YAML,无需部署到集群。使用 kubectl kyverno apply --dry-run=server 模拟集群端执行效果。