4. Kyverno 策略语言入门:策略结构、规则定义与动作类型
Kyverno 策略语言的核心设计哲学是“Kubernetes 原生”——策略本身就是 Kubernetes 资源(CRD),使用 YAML 声明式定义,无需学习额外的 DSL(领域特定语言)。本章将系统拆解策略的顶层结构、规则(rule)的构成要素、选择器(match/exclude)的匹配逻辑,以及三种核心动作类型(validate/mutate/generate)的适用场景。
4.1 策略顶层结构:Policy 与 ClusterPolicy
Kyverno 提供两种策略作用域,区别在于生效范围与资源类型:
| 属性 | Policy(命名空间级) | ClusterPolicy(集群级) |
|---|---|---|
| API 版本 | kyverno.io/v1 |
kyverno.io/v1 |
| 作用范围 | 仅匹配指定 Namespace 内的资源 | 匹配整个集群所有 Namespace 的资源 |
| 资源类型 | 集群资源(如 Namespace、Node)无法被 Policy 匹配 | 可匹配集群资源与命名空间资源 |
| 典型场景 | 租户隔离、团队级安全基线 | 全局准入控制、基础设施合规 |
| spec 字段 | rules[] + 可选 background |
rules[] + 可选 background |
最佳实践:在 IDP(内部开发者平台)拓扑中,ClusterPolicy 用于平台团队定义的全局安全基线(如禁止特权容器、强制只读根文件系统),Policy 用于租户或项目组自定义的局部策略(如限制特定 Namespace 的出口流量)。两者可以共存,Kyverno 按规则优先级合并生效。
4.2 规则(rule)定义:策略的最小执行单元
每个策略可以包含多个规则,规则之间是“OR”逻辑——只要有一条规则匹配并执行动作,策略即生效。规则的 YAML 骨架如下:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-pod-security
spec:
rules:
- name: require-readonly-rootfs
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
validate:
message: "根文件系统必须设置为只读"
pattern:
spec:
containers:
- securityContext:
readOnlyRootFilesystem: true
规则的核心字段包括:
- name(必填):规则标识,在策略内唯一,用于审计日志与告警。
- match(必填):定义哪些资源触发该规则,支持
any或all条件组。 - exclude(可选):从匹配结果中排除特定资源,优先级高于 match。
- 动作类型(三选一):
validate、mutate、generate,决定规则对资源执行的操作。 - context(可选):从外部数据源(如 ConfigMap、API 调用)注入变量,用于动态策略。
4.3 match/exclude 选择器:精准控制策略作用域
选择器是策略的“瞄准镜”,通过资源属性组合实现精细匹配。Kyverno 支持两种逻辑运算符:
- any:满足任意一个条件即匹配(OR 逻辑)。
- all:满足所有条件才匹配(AND 逻辑)。
常用的匹配维度包括:
| 匹配维度 | 字段路径 | 示例值 |
|---|---|---|
| 资源类型 | resources.kinds |
["Pod", "Deployment"] |
| 资源名称 | resources.names |
["my-app-*"](支持通配符) |
| 命名空间 | resources.namespaces |
["production", "staging"] |
| 标签选择器 | resources.selector.matchLabels |
{ "app": "frontend" } |
| 注解 | resources.annotations |
{ "security.kyverno.io/scan": "required" } |
| 用户信息 | subjects |
[{"kind": "User", "name": "admin"}] |
避坑指南:match 和 exclude 都支持
any 和 all,但两者不能在同一规则中混用不同运算符。例如,match 使用 any 时,exclude 也必须使用 any,否则 Kyverno 会报 schema 校验错误。
4.4 三种动作类型:validate / mutate / generate
动作类型是策略的“执行器”,决定了规则对匹配资源的具体操作。下表对比三种动作的核心差异:
| 动作类型 | 执行时机 | 对资源的影响 | 典型场景 |
|---|---|---|---|
| validate | 准入阶段(Admission Review) | 仅检查,不修改;拒绝或允许请求 | 强制安全上下文、禁止 hostNetwork、校验镜像仓库 |
| mutate | 准入阶段(Admission Review) | 自动修改资源字段,用户无感知 | 注入 Sidecar、添加标签/注解、设置默认资源限制 |
| generate | 资源创建后(Background 模式) | 创建新资源(如 ConfigMap、NetworkPolicy) | 自动为每个 Namespace 创建默认网络策略、生成 RBAC 绑定 |
4.4.1 validate:准入校验与拒绝
validate 是使用最频繁的动作类型,支持两种校验模式:
- pattern:声明期望的资源字段值,Kyverno 检查实际值是否匹配。支持通配符
*和条件操作符(如>、<)。 - deny:基于 CEL(Common Expression Language)或原始条件表达式,当条件为 true 时拒绝请求。适用于复杂逻辑校验。
# pattern 模式示例:强制容器镜像必须来自内部仓库
validate:
message: "镜像必须来自 registry.internal.io"
pattern:
spec:
containers:
- image: "registry.internal.io/*"
4.4.2 mutate:自动修改与注入
mutate 在资源被创建或更新时自动修改其字段,用户无需手动操作。支持两种策略:
- patchesJson6902:使用 JSON Patch 标准(RFC 6902)进行精确修改。
- patchStrategicMerge:使用 Kubernetes 战略合并补丁,适合覆盖或追加字段。
# 自动为所有 Pod 添加标签 "team: platform"
mutate:
patchStrategicMerge:
metadata:
labels:
team: platform
4.4.3 generate:资源自动创建
generate 在触发资源(如 Namespace)创建后,自动生成关联资源。常用于平台初始化场景:
- 为每个新 Namespace 生成默认的 NetworkPolicy(拒绝所有入站流量)。
- 为每个 ServiceAccount 生成对应的 Secret(用于镜像拉取)。
- 为每个 Namespace 生成 ResourceQuota 和 LimitRange。
# 自动为每个 Namespace 生成默认网络策略
generate:
kind: NetworkPolicy
name: default-deny-ingress
namespace: "{{request.object.metadata.name}}"
synchronize: true
data:
spec:
podSelector: {}
policyTypes:
- Ingress
注意:generate 动作默认只在资源创建时触发一次。如果目标资源被手动删除,Kyverno 不会自动重建,除非设置
synchronize: true(同步模式),此时 Kyverno 会持续确保生成资源与策略定义一致。
4.5 策略执行流程与规则优先级
当 Kubernetes API Server 收到资源请求时,Kyverno 作为动态准入 Webhook 介入,执行流程如下:
- 匹配阶段:遍历所有 ClusterPolicy 和 Policy,检查资源的 kind、namespace、labels 等是否匹配规则的 match 条件。
- 排除阶段:对匹配的资源,检查 exclude 条件,排除命中项。
- 动作执行:按 mutate → validate → generate 的顺序执行。mutate 先修改资源,validate 再校验修改后的结果,generate 在资源持久化后异步执行。
- 结果聚合:所有规则执行完毕后,Kyverno 向 API Server 返回允许/拒绝/补丁响应。
4.6 策略语言核心概念总结
Kyverno 策略语言的本质是“用 Kubernetes 资源描述安全规则”。掌握以下三个关键点即可快速上手:
- 结构分层:Policy/ClusterPolicy → rules[] → match/exclude → 动作类型,每一层都有明确的职责边界。
- 选择器灵活性:通过
any/all组合资源类型、标签、命名空间等维度,实现从粗粒度到细粒度的策略控制。 - 动作类型分工:validate 做“安检”,mutate 做“自动修正”,generate 做“资源预置”,三者配合可覆盖绝大多数安全权限场景。
IDP 集成提示:在内部开发者平台中,建议将 validate 策略用于“硬性安全红线”(如禁止特权容器),mutate 策略用于“平台默认值注入”(如自动添加 Istio Sidecar),generate 策略用于“租户初始化”(如自动创建 NetworkPolicy 和 ResourceQuota)。这种分工可以最大程度减少开发者的认知负担,同时保障平台安全基线。