4. 策略基础概念:Policy与ClusterPolicy区别、规则(Rule)结构、匹配(Match)与排除(Exclude)条件
在 Kyverno 中,策略是准入控制的执行单元。理解 Policy 与 ClusterPolicy 的差异、规则的构成以及匹配/排除逻辑,是编写安全策略的基础。本章将逐一拆解这些核心概念。
4.1 Policy 与 ClusterPolicy:作用域与资源范围
Kyverno 提供了两种策略类型,它们的核心区别在于 作用域:
| 特性 | Policy(命名空间级) | ClusterPolicy(集群级) |
|---|---|---|
| 作用范围 | 仅作用于同一命名空间内的资源 | 作用于整个集群所有命名空间中的资源 |
| 资源类型 | 只能匹配命名空间级资源(如 Pod、Service) | 可匹配命名空间级资源 + 集群级资源(如 Namespace、Node、ClusterRole) |
| 典型场景 | 租户隔离、团队级安全基线 | 全局安全策略、合规基线、基础设施加固 |
| YAML 中 kind | Policy |
ClusterPolicy |
安全评审提示: 在权限评审中,
ClusterPolicy 的变更影响面远大于 Policy。任何对 ClusterPolicy 的修改都应触发更严格的审批流程,因为它可能影响整个集群的准入行为。
以下 SVG 展示了两种策略在集群中的逻辑作用范围:
4.2 规则(Rule)结构:策略的执行单元
每个 Policy 或 ClusterPolicy 可以包含一个或多个 规则(Rule)。规则是策略的最小执行单元,其结构决定了“对谁、在何时、做什么”。一个完整的规则包含以下核心字段:
- name:规则名称,在同一策略内必须唯一。
- match:定义规则适用的资源条件(必填)。
- exclude:定义从匹配中排除的资源条件(可选)。
- preconditions:基于资源上下文变量的前置条件(可选,常用于 mutate)。
- context:从外部数据源(如 ConfigMap、API 调用)注入变量(可选)。
- validate / mutate / generate / verifyImages:规则的动作类型,决定策略的行为。
规则结构示例(YAML):
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-pod-security
spec:
rules:
- name: check-run-as-non-root
match:
any:
- resources:
kinds:
- Pod
exclude:
any:
- resources:
namespaces:
- kube-system
validate:
message: "容器必须设置 runAsNonRoot: true"
pattern:
spec:
securityContext:
runAsNonRoot: true
4.3 匹配(Match)与排除(Exclude)条件
匹配与排除是规则的门控逻辑,决定了策略是否对某个资源生效。Kyverno 支持灵活的匹配表达式,包括 any 和 all 两种逻辑组合方式。
4.3.1 匹配条件(Match)
匹配条件定义规则应处理的资源集合。支持以下维度:
| 匹配维度 | 说明 | 示例 |
|---|---|---|
| kinds | 资源类型(必填) | kinds: ["Pod", "Deployment"] |
| names | 资源名称 | names: ["web-*"] |
| namespaces | 命名空间 | namespaces: ["prod"] |
| selector | 标签选择器 | selector: matchLabels: {app: nginx} |
| annotations | 注解匹配 | annotations: {security.kyverno.io/scan: "required"} |
4.3.2 排除条件(Exclude)
排除条件用于从匹配结果中移除特定资源。其结构与匹配条件完全相同,但语义为“如果满足排除条件,则跳过该规则”。
常见误区: 排除条件的优先级高于匹配条件。即使资源完全符合 match 条件,只要它命中 exclude 中的任意一条,规则就不会执行。在安全评审中,应特别关注排除条件是否过于宽泛,导致安全策略被绕过。
4.3.3 any 与 all 逻辑组合
Kyverno 支持在 match 和 exclude 中使用 any 或 all 来组合多个条件:
- any:满足任意一个条件即生效(OR 逻辑)。
- all:满足所有条件才生效(AND 逻辑)。
以下 SVG 展示了匹配与排除的决策流程:
4.4 匹配与排除的常见安全陷阱
安全评审要点:
- 排除条件过于宽泛: 使用
namespaces: ["*"]或names: ["*"]会完全绕过策略,应严格限制。 - 缺失 kinds 限制: 如果 match 中未指定 kinds,规则可能意外匹配到所有资源类型,导致非预期行为。
- any 与 all 误用: 使用
any时,只要一个条件满足即生效,可能导致匹配范围扩大;all则更严格。 - ClusterPolicy 的排除影响: 在 ClusterPolicy 中排除某个命名空间,意味着该命名空间完全不受该策略约束,需确认是否有合规风险。
4.5 最佳实践:策略设计原则
| 原则 | 说明 |
|---|---|
| 最小匹配原则 | match 条件应尽可能精确,避免使用通配符或空匹配。 |
| 显式排除 | 排除条件应明确列出需要豁免的资源,而非使用模糊匹配。 |
| 规则拆分 | 一个规则只做一件事。将 validate、mutate、generate 拆分为独立规则,便于审计和调试。 |
| 命名规范 | 规则名称应体现其功能,如 check-run-as-non-root、block-latest-tag。 |
| 优先使用 ClusterPolicy | 对于安全基线类策略,优先使用 ClusterPolicy 确保全局一致性,再通过 exclude 处理例外。 |
评审清单: 在安全权限评审中,逐条检查每个规则的 match/exclude 条件,确认其覆盖范围是否符合预期,排除条件是否有合规风险。建议使用
kyverno test 命令对策略进行单元测试,验证匹配逻辑的正确性。