3. 策略基础:Policy 与 ClusterPolicy 的区别、规则(Rule)结构详解
在 Kyverno 中,策略是声明式准入控制的核心载体。理解 Policy 与 ClusterPolicy 的差异,以及规则(Rule)的内部结构,是编写安全策略的基础。本节将拆解这两个关键概念,并深入规则引擎的构成要素。
3.1 Policy 与 ClusterPolicy:作用域与目标
Kyverno 提供了两种策略资源类型,它们的核心区别在于作用范围和匹配目标。选择哪种类型取决于你希望策略生效的边界。
| 特性 | Policy(命名空间级) | ClusterPolicy(集群级) |
|---|---|---|
| 作用域 | 仅在其所属的单个命名空间内生效 | 在整个集群范围内生效,可跨命名空间 |
| 匹配资源 | 只能匹配同一命名空间内的资源 | 可匹配所有命名空间或特定命名空间的资源 |
| 典型用途 | 租户隔离、团队级安全基线、命名空间专属标签 | 全局安全基线、Pod 安全标准(PSS)、集群级资源限制 |
| 资源名称 | 使用 kind: Policy |
使用 kind: ClusterPolicy |
| spec 字段 | 无需 spec.rules 外额外字段 |
支持 spec.rules 及 spec.background 等集群级配置 |
实践建议: 当策略需要应用于整个集群(如禁止特权容器)时,使用
ClusterPolicy;当策略仅针对某个团队或项目(如强制特定标签)时,使用命名空间级的 Policy。
3.2 规则(Rule)结构详解
无论是 Policy 还是 ClusterPolicy,其核心逻辑都封装在 spec.rules 数组中。每个规则(Rule)都是一个独立的“匹配-执行”单元。一个策略可以包含多个规则,它们按顺序评估。
一个完整的规则由以下四个核心部分组成:
- 名称(name): 规则的唯一标识符,用于日志和审计。
- 匹配(match): 定义规则适用的资源条件(必须满足)。
- 排除(exclude): 定义规则不适用的资源条件(可选,优先级高于 match)。
- 执行动作(validate / mutate / generate / verifyImages): 定义匹配后执行的具体操作。
规则执行逻辑: 一个请求必须满足
match 中的所有条件,且不命中 exclude 中的任何条件,才会触发规则的动作。
3.2.1 匹配(match)与排除(exclude)
match 和 exclude 使用相同的资源描述结构,支持按资源类型、标签选择器、命名空间、用户信息等维度进行筛选。
# 匹配示例:匹配所有命名空间中,标签为 app=web 的 Deployment
match:
any:
- resources:
kinds:
- Deployment
selector:
matchLabels:
app: web
# 排除示例:排除 kube-system 命名空间中的所有资源
exclude:
any:
- resources:
namespaces:
- kube-system
3.2.2 执行动作类型
Kyverno 规则支持四种核心动作,覆盖了准入控制的主要场景:
| 动作类型 | 关键字 | 功能描述 | 典型场景 |
|---|---|---|---|
| 验证 | validate |
检查资源是否符合预期,拒绝不符合的请求 | 强制只读根文件系统、禁止 hostNetwork |
| 变更 | mutate |
在资源创建/更新时自动修改其字段 | 自动注入 Sidecar、添加安全上下文 |
| 生成 | generate |
基于源资源创建新资源(如 ConfigMap、Secret) | 为每个命名空间生成默认 NetworkPolicy |
| 镜像验证 | verifyImages |
验证容器镜像的签名和来源 | 确保只使用经过签名的官方镜像 |
3.3 规则结构可视化
下图展示了一个典型 Kyverno 规则从匹配到执行的整体流程,帮助理解各组件之间的协作关系。
3.4 规则编写示例:准入权限变更风险场景
以下是一个针对“配置准入权限变更风险”的 ClusterPolicy 示例。该策略会验证所有 Pod 是否设置了 readOnlyRootFilesystem: true,从而降低容器逃逸风险。
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-readonly-rootfs
spec:
validationFailureAction: Enforce # 拒绝不符合规则的请求
background: true # 对现有资源进行扫描
rules:
- name: check-readonly-rootfs
match:
any:
- resources:
kinds:
- Pod
validate:
message: "根文件系统必须设置为只读,以防止恶意写入。"
pattern:
spec:
containers:
- securityContext:
readOnlyRootFilesystem: true
风险提示: 在编写
mutate 规则时,务必谨慎。错误的变更逻辑可能导致资源无法创建或集群状态异常。建议先在 validationFailureAction: Audit 模式下测试,确认无误后再切换为 Enforce。
3.5 规则评估顺序与优先级
当一个请求命中多个规则时,Kyverno 遵循以下顺序:
- 先执行 mutate 规则:所有变更规则按策略创建顺序执行,后执行的 mutate 可以覆盖先前的变更。
- 再执行 validate 规则:验证规则在 mutate 完成后执行,确保最终资源状态符合预期。
- 最后执行 generate 规则:生成规则通常用于创建附属资源,不影响当前请求的准入决策。
理解这一顺序对于设计复杂的策略组合至关重要,尤其是在需要先注入 Sidecar 再验证安全上下文的场景中。