4. Kyverno 策略基础:策略结构(Policy/ClusterPolicy)、规则(rule)、匹配(match)与排除(exclude)
Kyverno 策略引擎的核心是 策略对象。理解策略的结构是编写有效基线核验规则的前提。Kyverno 提供了两种策略作用域:Policy(命名空间级)和 ClusterPolicy(集群级),它们共享相同的规则结构。
4.1 策略作用域:Policy 与 ClusterPolicy
| 特性 | Policy | ClusterPolicy |
|---|---|---|
| 作用范围 | 仅作用于特定命名空间 | 作用于整个集群(所有命名空间) |
| 资源类型 | 仅匹配命名空间内的资源 | 匹配集群范围资源(如 Node、PV)及所有命名空间资源 |
| 典型用途 | 团队级安全基线、命名空间隔离策略 | 全局基线、合规性标准、平台级强制策略 |
| YAML kind | Policy |
ClusterPolicy |
最佳实践:在 Backstage 插件集成中,通常使用
ClusterPolicy 定义全局基线核验规则,确保所有通过 Backstage 模板创建的组件都遵循统一的安全标准。
4.2 策略结构总览
一个 Kyverno 策略由 元数据(metadata)、策略主体(spec) 和 规则数组(rules) 组成。规则是策略的核心执行单元。
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: pod-security-baseline
spec:
validationFailureAction: Enforce # 或 Audit
background: true
rules:
- name: check-privileged-containers
match:
resources:
kinds:
- Pod
exclude:
resources:
namespaces:
- kube-system
- kyverno
validate:
message: "特权容器被禁止。"
pattern:
spec:
containers:
- securityContext:
privileged: false
关键字段说明:
validationFailureAction:Enforce表示强制拒绝违规资源;Audit仅记录违规,不阻止创建。background:true表示对集群中已有资源进行扫描核验。
4.3 规则(rule)结构
每个规则包含三个核心部分:匹配(match)、排除(exclude) 和 策略主体(validate/mutate/generate)。匹配与排除决定了规则作用于哪些资源。
4.4 匹配(match)详解
match 定义了规则适用的资源范围。Kyverno 支持多种匹配条件,可以组合使用。
| 匹配字段 | 描述 | 示例 |
|---|---|---|
resources.kinds |
按资源类型匹配 | [Pod, Deployment, Service] |
resources.namespaces |
按命名空间匹配 | [production, staging] |
resources.names |
按资源名称匹配(支持通配符) | ["app-*", "web-*"] |
resources.selector |
按标签选择器匹配 | matchLabels: { app: frontend } |
resources.annotations |
按注解匹配 | security.kyverno.io/scan: "required" |
注意:如果
match 中未指定 kinds,规则将不会匹配任何资源。始终至少指定一个 kinds 值。
4.5 排除(exclude)详解
exclude 用于从匹配结果中移除特定资源。排除条件优先级高于匹配条件。
exclude:
resources:
kinds:
- Pod
namespaces:
- kube-system
- kyverno
names:
- "*-canary"
selector:
matchLabels:
app: legacy
annotations:
policy.kyverno.io/exclude: "true"
排除策略最佳实践:
- 始终排除系统命名空间(
kube-system、kyverno)以避免影响集群核心组件。 - 使用注解
policy.kyverno.io/exclude: "true"为特定资源提供“豁免”机制。 - 在 Backstage 集成中,可以为开发环境或测试组件添加排除标签,允许临时绕过基线核验。
4.6 匹配与排除的优先级逻辑
Kyverno 处理规则的顺序是:先检查 match,再检查 exclude。只有当资源同时满足 match 条件且不满足 exclude 条件时,规则才会生效。
4.7 实际案例:Backstage 组件基线核验策略
以下是一个完整的 ClusterPolicy 示例,用于核验通过 Backstage 创建的组件是否满足安全基线:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: backstage-component-baseline
annotations:
policies.kyverno.io/title: "Backstage 组件安全基线"
policies.kyverno.io/category: "Security Baseline"
spec:
validationFailureAction: Enforce
background: true
rules:
- name: check-run-as-non-root
match:
resources:
kinds:
- Pod
annotations:
backstage.io/created-by: "*"
exclude:
resources:
namespaces:
- kube-system
- kyverno
annotations:
baseline.kyverno.io/exempt: "true"
validate:
message: "容器必须以非 root 用户运行。"
pattern:
spec:
containers:
- securityContext:
runAsNonRoot: true
- name: check-readonly-rootfs
match:
resources:
kinds:
- Pod
annotations:
backstage.io/created-by: "*"
exclude:
resources:
namespaces:
- kube-system
validate:
message: "根文件系统必须设置为只读。"
pattern:
spec:
containers:
- securityContext:
readOnlyRootFilesystem: true
Backstage 集成要点:
- 使用注解
backstage.io/created-by: "*"匹配所有由 Backstage 创建的组件。 - 提供
baseline.kyverno.io/exempt: "true"注解作为开发环境的临时豁免机制。 - 建议在 Backstage 模板中自动注入
backstage.io/created-by注解,确保策略能够准确识别。
4.8 常见错误与调试
| 错误场景 | 原因 | 解决方案 |
|---|---|---|
| 策略未生效 | match 中未指定 kinds |
添加 kinds: [Pod] 等资源类型 |
| 系统组件被误拦截 | 未排除系统命名空间 | 在 exclude 中添加 kube-system |
| 规则匹配范围过大 | 未使用 namespaces 或 selector 限制 |
添加命名空间或标签选择器缩小范围 |
| 排除条件不生效 | 排除条件与匹配条件冲突 | 检查排除条件的字段是否与匹配条件一致 |
调试命令:使用
kubectl describe clusterpolicy <policy-name> 查看策略状态和规则匹配统计。使用 kubectl get policyreport 查看审计结果。