4. 策略语言入门:Rule 结构、Match/Exclude 条件、Mutate/Validate/Generate 动作

Kyverno 策略的核心是 Rule(规则)。一个策略文件可以包含一个或多个 Rule,每个 Rule 定义了“在什么条件下(Match/Exclude)对哪些资源执行什么动作(Mutate/Validate/Generate)”。理解 Rule 的结构是编写安全策略的基础。

4.1 Rule 基本结构

一个典型的 Kyverno Rule 包含以下关键字段:

字段 必填 说明
name 是 规则名称,在同一策略内必须唯一
match 是 定义规则适用的资源选择条件
exclude 否 从 match 中排除特定资源
mutate 否 对匹配的资源进行修改(覆盖、补丁)
validate 否 对匹配的资源进行校验(允许/拒绝)
generate 否 基于匹配的资源创建新资源
context 否 引入外部数据(ConfigMap、API 调用等)
preconditions 否 在执行动作前的额外条件判断
关键原则:一个 Rule 中只能包含 mutate、validate、generate 中的一个动作。如果需要同时执行多种动作,必须拆分为多个 Rule。

4.2 Match 与 Exclude 条件

match 和 exclude 使用相同的过滤语法,支持按资源类型、标签、命名空间、注解等维度进行选择。它们的结构完全一致,但语义相反。

4.2.1 匹配维度

维度 字段 示例
资源类型 resources.kinds ["Pod", "Deployment"]
资源名称 resources.names ["myapp-*"]
命名空间 resources.namespaces ["production"]
标签选择器 resources.selector matchLabels: { app: nginx }
注解 resources.annotations {"security.kyverno.io/scan": "required"}
用户信息 subjects 匹配特定用户或 ServiceAccount

4.2.2 匹配逻辑

  • 多维度组合:同一维度内的多个值为 OR 关系;不同维度之间为 AND 关系。
  • 通配符:支持 *(匹配任意字符)和 ?(匹配单个字符)。
  • 排除优先级:exclude 的优先级高于 match,即先匹配再排除。
最佳实践:在生产环境中,建议始终为关键策略添加 exclude 条件,排除系统命名空间(如 kube-system、kyverno),避免误拦截系统组件。

4.3 三种动作详解

Kyverno 提供三种核心动作:Mutate(修改)、Validate(校验)、Generate(生成)。它们分别对应不同的安全场景。

4.3.1 Mutate(修改)

在资源创建或更新时自动修改其配置。常用于强制注入安全配置,如 Sidecar、标签、注解、安全上下文。

# 强制为所有 Pod 注入 readOnlyRootFilesystem
mutate:
  patchesJson6902: |
    - op: add
      path: /spec/containers/0/securityContext/readOnlyRootFilesystem
      value: true

4.3.2 Validate(校验)

对资源进行合规性检查,决定允许或拒绝。支持两种模式:

模式 行为 适用场景
deny 不满足条件时拒绝请求 禁止特权容器、禁止 hostNetwork
pattern 检查资源是否符合预期模式 验证镜像仓库来源、验证标签格式
# 拒绝 privileged 容器
validate:
  message: "特权容器不被允许"
  deny:
    conditions:
      any:
        - key: "{{ request.object.spec.containers[].securityContext.privileged }}"
          operator: AnyIn
          value: [true]

4.3.3 Generate(生成)

基于源资源自动创建关联资源。常用于创建 Namespace 默认的 NetworkPolicy、LimitRange、ResourceQuota。

# 为每个新 Namespace 生成默认 NetworkPolicy
generate:
  synchronize: true
  apiVersion: networking.k8s.io/v1
  kind: NetworkPolicy
  name: default-deny-all
  namespace: "{{ request.object.metadata.name }}"
  data:
    spec:
      podSelector: {}
      policyTypes:
        - Ingress
        - Egress
注意:generate 动作仅在资源创建时触发,不会在更新时重新生成。如果需要保持同步,请设置 synchronize: true。

4.4 动作选择决策流程

Kyverno Rule 动作选择决策流程 收到准入请求 Match / Exclude 条件评估 跳过规则 动作类型判断 Mutate 修改资源配置 Validate 校验并决定允许/拒绝 Generate 创建关联资源 返回准入响应 一个 Rule 只能包含 Mutate、Validate、Generate 中的一个动作,不可混用 如需多种动作,请拆分为多个 Rule 或使用多个策略

4.5 完整策略示例

以下是一个完整的 Kyverno 策略,展示了 Rule 结构、Match/Exclude 条件和 Validate 动作的组合使用:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-readonly-rootfs
spec:
  validationFailureAction: Enforce
  background: true
  rules:
    - name: check-readonly-rootfs
      match:
        resources:
          kinds:
            - Pod
          selector:
            matchLabels:
              security-level: high
      exclude:
        resources:
          namespaces:
            - kube-system
            - kyverno
      validate:
        message: "高安全等级的 Pod 必须设置 readOnlyRootFilesystem"
        pattern:
          spec:
            containers:
              - securityContext:
                  readOnlyRootFilesystem: true
关键字段说明:
  • validationFailureAction: Enforce — 拒绝不合规资源(Audit 模式仅记录)
  • background: true — 对已有资源进行后台扫描
  • match — 仅匹配标签为 security-level: high 的 Pod
  • exclude — 排除系统命名空间,避免误拦截

4.6 常见错误与避坑指南

错误场景 问题说明 正确做法
Match 条件过于宽泛 未指定命名空间或标签,导致影响范围过大 始终添加命名空间或标签选择器限制范围
忘记 Exclude 系统命名空间 策略误拦截 kube-system 等关键组件 始终排除 kube-system、kyverno 等命名空间
Mutate 与 Validate 混用 在同一个 Rule 中同时包含 mutate 和 validate 拆分为两个独立的 Rule
Generate 未设置 synchronize 源资源更新后,生成资源不会自动同步 需要同步时设置 synchronize: true
Pattern 语法错误 YAML 缩进或路径错误导致策略不生效 使用 kubectl kyverno test 本地验证
安全提示:在将策略切换到 Enforce 模式前,务必先在 Audit 模式下运行一段时间,观察策略对现有资源的影响,避免意外拒绝合法请求。