2. Kyverno 策略基础:策略结构解析、规则(rule)与匹配(match/exclude)机制、策略的验证(validate)模式
2.1 策略(Policy)顶层结构
Kyverno 策略使用标准的 Kubernetes 自定义资源(CRD)定义,遵循 apiVersion、kind、metadata、spec 四层结构。策略分为两类:ClusterPolicy(集群范围)和 Policy(命名空间范围)。
| 字段 | 说明 | 示例值 |
|---|---|---|
apiVersion |
Kyverno API 版本 | kyverno.io/v1 |
kind |
策略类型 | ClusterPolicy / Policy |
metadata.name |
策略名称(集群内唯一) | require-pod-limits |
spec.rules[] |
规则数组(至少 1 条) | 见下文 |
spec.background |
是否对存量资源执行扫描 | true / false |
spec.schemaValidation |
是否启用 OpenAPI 模式校验 | true(默认) |
关键区别: ClusterPolicy 不绑定命名空间,可匹配集群范围资源(如 Namespace、Node、PersistentVolume);Policy 必须指定
metadata.namespace,仅在该命名空间内生效。
2.2 规则(rule)核心结构
每条规则由 匹配条件、排除条件 和 策略行为 三部分组成。规则名称在策略内必须唯一。
spec:
rules:
- name: check-container-limits
match:
any:
- resources:
kinds:
- Pod
namespaces:
- production
exclude:
any:
- resources:
namespaces:
- kube-system
validate:
message: "容器必须设置 CPU 和内存 limits"
pattern:
spec:
containers:
- resources:
limits:
cpu: "?*"
memory: "?*"
2.3 匹配(match)与排除(exclude)机制
Kyverno 使用 任意匹配(any) 和 全部匹配(all) 两种逻辑运算符来控制匹配条件。匹配与排除的字段结构完全一致。
2.3.1 匹配条件字段
| 字段 | 类型 | 说明 |
|---|---|---|
resources.kinds |
[]string | 匹配的资源类型(如 Pod、Deployment) |
resources.namespaces |
[]string | 匹配的命名空间列表 |
resources.names |
[]string | 匹配的资源名称(支持通配符 *) |
resources.annotations |
map[string]string | 匹配资源注解键值对 |
resources.selector |
map[string]string | 匹配资源标签选择器 |
subjects |
[]rbacv1.Subject | 匹配操作主体(User/Group/ServiceAccount) |
roles |
[]string | 匹配操作者角色(ClusterRole/Role) |
2.3.2 匹配逻辑:any 与 all
- any:数组中任意一个条件满足即匹配(OR 逻辑)。
- all:数组中所有条件必须同时满足才匹配(AND 逻辑)。
最佳实践: 使用
any 匹配多种资源类型(如 Pod 和 Job),使用 all 同时约束命名空间和标签。排除条件优先于匹配条件——资源先被排除则不再进入匹配判断。
2.4 验证(validate)模式详解
验证模式是 Kyverno 最常用的策略行为,用于检查资源是否符合预期规范。验证模式支持三种子模式:pattern、anyPattern 和 deny。
2.4.1 pattern(模式匹配)
使用 YAML 模板定义期望的资源字段值。支持以下特殊操作符:
| 操作符 | 含义 | 示例 |
|---|---|---|
* |
任意非空值 | cpu: "*" |
?* |
任意值(允许为空) | memory: "?*" |
"" |
必须为空 | hostPID: "" |
>0 |
数值比较 | replicas: ">0" |
^regex$ |
正则表达式 | image: "^registry.example.com/" |
2.4.2 anyPattern(多模式备选)
当需要满足多个模式中的任意一个时使用。例如:允许容器使用 CPU limits 或 memory limits 至少一个。
validate:
message: "容器必须设置 CPU 或 memory limits"
anyPattern:
- spec:
containers:
- resources:
limits:
cpu: "*"
- spec:
containers:
- resources:
limits:
memory: "*"
2.4.3 deny(拒绝条件)
当需要拒绝特定条件时使用。例如:禁止使用 latest 标签。
validate:
message: "禁止使用 latest 镜像标签"
deny:
conditions:
any:
- key: "{{ request.object.spec.containers[].image }}"
operator: Contains
value: ":latest"
注意:
deny 模式使用 conditions 字段定义拒绝条件,支持 Equals、NotEquals、Contains、GreaterThan 等操作符。条件中的 key 支持 JMESPath 表达式从请求对象中提取字段。
2.5 策略执行流程示意图
2.6 策略结构完整示例
以下是一个完整的 ClusterPolicy 示例,展示 match、exclude 和 validate 的协同工作:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-resource-limits
spec:
background: true
rules:
- name: check-container-limits
match:
any:
- resources:
kinds:
- Pod
- Deployment
- StatefulSet
- Job
all:
- resources:
namespaces:
- production
- staging
exclude:
any:
- resources:
namespaces:
- kube-system
- kyverno
- subjects:
- kind: ServiceAccount
name: ci-pipeline
namespace: ci
validate:
message: "所有容器必须设置 CPU 和 memory 的 limits 和 requests"
pattern:
spec:
containers:
- resources:
limits:
cpu: "*"
memory: "*"
requests:
cpu: "*"
memory: "*"
工程提示: 在集群升级前,建议使用
kyverno test 命令对现有策略进行回归测试,确保新版本 Kyverno 的匹配逻辑和验证行为没有变化。升级后使用 kubectl get policyreport 查看存量资源的合规状态。