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"
4.3 三大动作:validate、mutate、generate
Kyverno 提供三种核心动作,分别对应策略即代码的不同阶段:
| 动作 | 触发时机 | 行为 | 回滚场景典型用途 |
|---|---|---|---|
| validate | Admission 验证阶段 | 检查资源是否符合规则,拒绝或允许 | 验证回滚镜像标签是否存在于仓库 |
| mutate | Admission 变更阶段 | 自动修改资源字段(补丁) | 自动注入回滚注解、添加安全上下文 |
| 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"
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 模拟集群端执行效果。