4. 策略语言入门:Rule 结构、Match/Exclude 条件、Mutation/Validation/Generation 三种动作
Kyverno 的策略语言是声明式的 Kubernetes 原生 DSL(领域特定语言)。理解其核心结构是编写安全策略的基础。本章将拆解一条策略的骨架、条件匹配逻辑以及三种核心动作类型。
4.1 Rule 结构:策略的基本单元
一条 Kyverno 策略(ClusterPolicy 或 Policy)可以包含多个 rule。每个 rule 都是一个独立的“如果-那么”声明:如果资源满足 Match 条件(且不满足 Exclude 条件),那么执行 Mutation、Validation 或 Generation 动作。
| 字段 | 类型 | 说明 |
|---|---|---|
name |
string | Rule 的唯一标识,用于日志和审计 |
match |
object | 定义哪些资源被该规则选中(必填) |
exclude |
object | 定义哪些资源不被该规则选中(可选) |
preconditions |
object | 在动作执行前的额外条件检查(可选) |
context |
object | 从外部 API 或 ConfigMap 加载数据(可选) |
mutate |
object | 定义资源的修改动作 |
validate |
object | 定义资源的验证规则 |
generate |
object | 定义资源的生成规则 |
关键理解: Rule 是策略的最小执行单元。一个策略可以包含多个 rule,每个 rule 可以有不同的 match 条件和不同的动作类型。Kyverno 会按顺序评估 rule,直到命中第一个匹配的 rule 并执行其动作。
4.2 Match / Exclude 条件:精准定位目标资源
Match 和 Exclude 使用相同的过滤语法,支持按资源类型、标签、命名空间、注解等维度筛选。Exclude 的优先级高于 Match:如果一个资源同时匹配了 Match 和 Exclude,则不会被规则选中。
4.2.1 常用匹配维度
- 资源类型:
kind(支持通配符*) - 命名空间:
namespaces(列表)或namespaceSelector(标签选择器) - 标签:
selector(标准 Kubernetes 标签选择器) - 名称:
name(精确匹配)或names(通配符列表) - 注解:
annotations(键值对匹配)
4.2.2 匹配模式对比
| 模式 | 示例 | 适用场景 |
|---|---|---|
| 精确匹配 | kind: "Pod" |
只针对单一资源类型 |
| 通配符 | kind: "Deployment" |
匹配所有资源类型 |
| 标签选择器 | selector: matchLabels: {app: nginx} |
按业务标签分组 |
| 命名空间选择器 | namespaceSelector: matchExpressions: ... |
动态排除特定环境(如 kube-system) |
最佳实践: 在 Exclude 中始终排除
kube-system 和 kube-public 命名空间,避免影响系统组件。使用 namespaceSelector 比硬编码命名空间列表更灵活。
4.3 三种核心动作:Mutation / Validation / Generation
这是 Kyverno 策略语言的灵魂。三种动作分别对应“修改”、“检查”和“创建”三种安全运维场景。
4.3.1 Mutation(修改)
在资源创建或更新时,自动注入或修改字段。常用于强制添加安全上下文、标签、注解或 Sidecar 容器。
mutate:
patchesJson6902: |-
- op: add
path: /spec/containers/0/securityContext
value:
runAsNonRoot: true
runAsUser: 1000
capabilities:
drop: ["ALL"]
- 覆盖策略:
overlay(合并覆盖)或patchesJson6902(JSON Patch 操作) - 典型安全场景:强制只读根文件系统、禁止特权提升、注入网络策略标签
4.3.2 Validation(验证)
检查资源是否符合安全基线。支持 deny(拒绝)和 pattern(模式匹配)两种模式。
validate:
message: "容器必须设置 CPU 和内存限制"
pattern:
spec:
containers:
- resources:
limits:
memory: "?*"
cpu: "?*"
- deny 模式:使用
anyPattern或allPattern定义拒绝条件 - pattern 模式:使用
pattern定义期望状态,不匹配则拒绝 - 典型安全场景:禁止 latest 镜像标签、禁止 hostNetwork、强制 Pod 安全标准
4.3.3 Generation(生成)
当特定资源创建时,自动生成关联资源。常用于自动创建 NetworkPolicy、LimitRange、RBAC 绑定等。
generate:
kind: NetworkPolicy
name: "default-deny-{{request.object.metadata.name}}"
namespace: "{{request.object.metadata.namespace}}"
synchronize: true
data:
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
- 同步模式:
synchronize: true确保生成的资源与源资源保持同步 - 模板变量:使用
{{request.object...}}引用被触发资源的字段 - 典型安全场景:为每个命名空间自动生成默认拒绝网络策略、为每个 ServiceAccount 生成 RBAC 绑定
4.4 三种动作对比与选择
| 动作 | 触发时机 | 对资源的影响 | 安全用途 |
|---|---|---|---|
| Mutation | 资源创建/更新时 | 修改资源内容 | 强制安全基线、注入 Sidecar |
| Validation | 资源创建/更新时 | 拒绝或允许 | 合规检查、安全准入 |
| Generation | 资源创建时 | 创建新资源 | 自动安全配置、策略联动 |
注意: Mutation 和 Validation 可以组合使用。Kyverno 会先执行所有 Mutation 规则,再执行 Validation 规则。这意味着 Validation 检查的是 Mutation 修改后的最终资源状态。
4.5 策略执行流程(SVG)
4.6 完整策略示例:强制只读根文件系统
以下是一个完整的 ClusterPolicy,演示了 Match、Exclude 和 Mutation 的组合使用:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-readonly-rootfs
spec:
validationFailureAction: Enforce
rules:
- name: check-readonly-rootfs
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
- kyverno
preconditions:
all:
- key: "{{ request.operation }}"
operator: In
value:
- CREATE
- UPDATE
mutate:
patchesJson6902: |-
- op: add
path: /spec/containers/0/securityContext/readOnlyRootFilesystem
value: true
安全要点: 只读根文件系统是容器安全的重要基线。该策略自动为所有新建 Pod(排除系统命名空间)注入
readOnlyRootFilesystem: true,防止恶意进程写入文件系统。
4.7 策略语言进阶:Preconditions 与 Context
除了基础的 Match/Exclude,Kyverno 还提供两个高级机制:
- Preconditions:在动作执行前进行更细粒度的条件判断,支持
all、any逻辑组合。常用于区分 CREATE 和 UPDATE 操作。 - Context:允许从外部数据源(如 ConfigMap、API 调用、变量)加载数据,用于动态策略决策。
| 特性 | 作用阶段 | 典型用途 |
|---|---|---|
| Preconditions | Match/Exclude 之后,动作之前 | 只对特定操作类型生效 |
| Context | 动作执行前 | 加载白名单、动态阈值 |
掌握 Rule 结构、Match/Exclude 条件和三种动作,你就掌握了 Kyverno 策略语言的核心。下一阶段将深入每种动作的高级用法和最佳实践。