3. Kyverno 策略进阶:变更(Mutate)模式、生成(Generate)模式、策略的优先级与背景上下文
在掌握了 Kyverno 策略的基本结构与验证(Validate)模式后,本章深入探讨策略引擎的核心进阶能力:变更(Mutate)与生成(Generate)模式。这两种模式赋予了 Kyverno 主动修改集群资源或按需创建新资源的能力,是自动化运维与合规基线管理的利器。同时,我们将解析策略的优先级机制与背景上下文(Background Context),确保策略在复杂场景下可预测、可控制地执行。
3.1 变更(Mutate)模式:资源准入时的自动修正
变更模式在资源进入集群的准入阶段(Admission Review)触发,自动修改资源的 YAML 定义,无需用户手动干预。这常用于注入 Sidecar、添加标签/注解、设置默认安全上下文等场景。
3.1.1 变更策略的核心结构
一个典型的 Mutate 策略使用 mutate 规则,并通过 patchStrategicMerge 或 patchesJson6902 定义修改逻辑。
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: add-default-security-context
spec:
rules:
- name: set-run-as-non-root
match:
any:
- resources:
kinds:
- Pod
mutate:
patchStrategicMerge:
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
containers:
- (name): "*"
securityContext:
allowPrivilegeEscalation: false
patchStrategicMerge 使用 Kubernetes 原生的 Strategic Merge Patch 语法,支持条件覆盖(如 (name): "*" 匹配所有容器)。对于更复杂的 JSON 操作,可使用 patchesJson6902 实现精确的增、删、改。
3.1.2 变更模式的典型应用场景
| 场景 | 变更内容 | 策略示例 |
|---|---|---|
| 注入 Sidecar 代理 | 在 Pod 的 spec.containers 中追加 Istio/Envoy 容器 |
匹配 Namespace 标签 sidecar-injection: enabled |
| 强制资源标签 | 为所有 Deployment 添加 app.kubernetes.io/managed-by: kyverno |
匹配所有 Deployment 资源 |
| 设置默认资源限制 | 为未设置 resources.limits 的容器添加默认值 |
使用 preconditions 检查字段是否为空 |
| 修正镜像仓库地址 | 将 image: nginx 自动补全为 image: registry.internal/nginx:latest |
使用 patchesJson6902 替换 spec.containers[*].image |
3.2 生成(Generate)模式:按需创建关联资源
Generate 模式允许 Kyverno 在检测到特定资源创建时,自动生成另一个关联资源。这常用于为每个 Namespace 创建默认的 NetworkPolicy、ResourceQuota、LimitRange,或基于 Service 自动生成对应的 ConfigMap。
3.2.1 生成策略的核心结构
Generate 策略通过 generate 规则定义,需要指定 kind、name、namespace(可选)以及 data 或 clone 来源。
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: generate-default-networkpolicy
spec:
rules:
- name: deny-all-ingress
match:
any:
- resources:
kinds:
- Namespace
generate:
kind: NetworkPolicy
name: default-deny-ingress
namespace: "{{request.object.metadata.name}}"
synchronize: true
data:
spec:
podSelector: {}
policyTypes:
- Ingress
synchronize: true 表示 Kyverno 会持续同步生成的资源。如果用户手动修改了生成的 NetworkPolicy,Kyverno 会将其恢复为策略定义的原始状态。这在强制合规基线时非常有用,但也意味着需要谨慎使用。
3.2.2 生成模式的数据来源
| 数据来源 | 说明 | 适用场景 |
|---|---|---|
data |
直接在策略中内联定义生成资源的完整 YAML | 生成结构固定、内容简单的资源(如默认 NetworkPolicy) |
clone |
从集群中已有的某个资源复制其内容作为模板 | 生成需要包含复杂配置或 Secret 数据的资源 |
3.3 策略的优先级:规则执行顺序与覆盖
当多个 Kyverno 策略(或同一策略中的多个规则)匹配同一个资源时,执行顺序和优先级决定了最终的资源状态。理解优先级机制对于避免策略冲突至关重要。
3.3.1 优先级决定因素
| 因素 | 说明 | 示例 |
|---|---|---|
| 策略类型 | ClusterPolicy 优先级高于 Policy | ClusterPolicy 的 Mutate 规则会覆盖 Policy 的规则 |
| 规则类型 | Mutate 规则在 Validate 规则之前执行 | 先注入 Sidecar,再验证 Pod 是否满足安全策略 |
| 策略背景上下文 | Background 模式下的策略优先级低于 Admission 模式 | 后台扫描发现的违规不会影响准入决策 |
| 规则顺序 | 同一策略中,规则按定义顺序依次执行 | 先添加标签,再设置资源限制 |
3.3.2 避免策略冲突的最佳实践
- 使用
preconditions细化匹配条件:确保每个规则只在其预期的场景下生效,减少重叠。 - 明确 Mutate 规则的覆盖意图:如果多个 Mutate 规则修改同一字段,后执行的规则会覆盖先执行的规则。使用
patchesJson6902的replace操作时需格外小心。 - 利用
policy.kyverno.io/priority注解:在 Kyverno 1.8+ 中,可以通过注解显式设置策略优先级(数值越小优先级越高)。
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: high-priority-mutate
annotations:
policies.kyverno.io/priority: "10" # 数值越小,优先级越高
spec:
...
3.4 背景上下文(Background Context):后台扫描与审计
背景上下文决定了 Kyverno 策略在何种场景下执行。除了默认的 Admission 模式(资源创建/更新时触发),Kyverno 还支持 Background 模式,用于对集群中已有的资源进行周期性扫描和审计。
3.4.1 背景上下文配置
在策略的 spec 级别,通过 background 字段控制是否启用后台扫描。
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: audit-existing-resources
spec:
background: true # 启用后台扫描
rules:
- name: check-pod-security
match:
any:
- resources:
kinds:
- Pod
validate:
message: "Pod 必须设置 runAsNonRoot: true"
pattern:
spec:
securityContext:
runAsNonRoot: true
- Admission 模式:实时拦截,阻止不合规资源创建/更新。
- Background 模式:异步扫描,仅报告违规(不阻止),适用于审计和合规报告。
3.4.2 背景上下文的实际应用
| 应用场景 | Admission 模式 | Background 模式 |
|---|---|---|
| 新资源合规检查 | 强制阻止不合规 Pod 创建 | 不适用(新资源由 Admission 处理) |
| 存量资源合规审计 | 不适用(无法回溯已有资源) | 扫描所有已有 Pod,生成违规报告 |
| 变更策略的生效范围 | 仅对新创建/更新的资源生效 | 不执行变更操作,仅用于验证 |
| 集群升级前合规检查 | 可配合升级流程使用 | 适合在升级前进行全集群扫描 |
background 临时设置为 true,运行一次全量扫描,生成合规报告。这有助于提前发现因升级可能导致的不兼容问题,避免升级过程中出现大规模准入拒绝。
通过深入理解 Mutate 与 Generate 模式、优先级机制以及 Background 上下文,运维人员可以构建出既灵活又安全的策略体系,在自动化运维与集群稳定性之间取得平衡。