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 动作选择决策流程
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的 Podexclude— 排除系统命名空间,避免误拦截
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 模式下运行一段时间,观察策略对现有资源的影响,避免意外拒绝合法请求。