2. Kyverno 基础架构:组件、Webhook 原理与工作流
在生产环境中落地策略即代码(Policy as Code),首先需要理解 Kyverno 的运行骨架。本章从组件拓扑、Admission Webhook 拦截机制、Policy Controller 内部工作流三个层次,拆解 Kyverno 如何将 YAML 策略转化为对 Kubernetes API 请求的实时校验与变异。
2.1 核心组件与部署拓扑
Kyverno 以一组 Pod 的形式运行在集群内,通常部署在 kyverno 命名空间下。其架构由四个主要组件构成,各司其职:
| 组件 | 职责 | 关键特性 |
|---|---|---|
| Kyverno Admission Controller | 接收并处理 AdmissionReview 请求,执行策略匹配、校验与变异 | 无状态,可水平扩展;核心策略引擎所在 |
| Kyverno Cleanup Controller | 根据 CleanupPolicy 定时清理集群资源 | 基于 CronJob 调度,支持标签选择器 |
| Kyverno Reports Controller | 生成并管理 PolicyReport 与 ClusterPolicyReport 资源 | 将策略审计结果持久化,供外部工具消费 |
| Kyverno Background Controller | 处理后台扫描(Audit 模式)、Generate 规则、资源变更触发 | 负责非拦截路径的策略执行 |
部署建议:生产环境建议将 Admission Controller 副本数设为 ≥2,并配置 PodDisruptionBudget。Reports Controller 与 Background Controller 对延迟不敏感,可共用资源配额。
2.2 Admission Webhook 原理
Kyverno 通过注册 ValidatingWebhookConfiguration 与 MutatingWebhookConfiguration 来拦截资源请求。其核心流程遵循 Kubernetes 准入控制链:
- 请求到达 API Server:用户或控制器通过 kubectl / client-go 发起资源创建、更新、删除请求。
- 认证与鉴权:API Server 完成身份验证与 RBAC 检查。
- Mutating Webhooks 拦截:Kyverno 的 Mutating Webhook 按配置的
matchConditions匹配请求,执行策略变异(如注入 Sidecar、添加标签)。 - 对象模式校验:API Server 对变异后的对象进行 Schema 校验。
- Validating Webhooks 拦截:Kyverno 的 Validating Webhook 执行策略校验,返回 allow / deny。
- 持久化:通过所有准入检查后,资源写入 etcd。
关键区别:Mutating Webhook 在 Validating Webhook 之前执行。这意味着 Kyverno 可以先修改资源(如补全安全上下文),再对修改后的结果进行校验。两个 Webhook 使用相同的策略定义,但 Kyverno 内部根据策略的
mutate 和 validate 规则自动分发到对应的 Webhook 端点。
2.3 Policy Controller 工作流
Policy Controller 是 Kyverno 策略执行的核心逻辑单元,负责将用户定义的 ClusterPolicy / Policy 资源转化为可执行的规则链。其内部工作流分为五个阶段:
| 阶段 | 输入 | 处理逻辑 | 输出 |
|---|---|---|---|
| 1. 策略加载 | CRD 对象(YAML) | 解析策略的 spec.rules,构建规则索引树 |
内存中的规则缓存 |
| 2. 请求匹配 | AdmissionReview + 规则缓存 | 按 match / exclude 条件过滤资源类型、命名空间、标签 |
匹配的规则列表 |
| 3. 预处理 | 匹配规则 + 原始资源对象 | 执行变量替换({{ request.object.metadata.name }})、Context 数据加载 |
预处理的资源上下文 |
| 4. 规则执行 | 预处理上下文 | 按规则类型分发: - validate:CEL / 模式校验- mutate:JSON Patch / 覆盖- generate:资源模板生成 |
校验结果 / 变异补丁 / 生成请求 |
| 5. 响应聚合 | 各规则执行结果 | 合并所有校验错误、变异补丁;生成 AdmissionResponse | allow / deny + patch JSON |
性能注意:规则执行阶段中,
context 数据加载(如调用外部 API、查询 ConfigMap)可能引入延迟。建议将外部数据查询放在 preconditions 之后,避免不必要的远程调用。对于高频资源(如 Pod 创建),优先使用 CEL 表达式而非 JMESPath 调用外部服务。
2.4 工作流时序示例
以下是一个完整的策略执行时序,展示从用户提交 Deployment 到 Kyverno 返回准入响应的全过程:
用户 kubectl apply -f deploy.yaml
│
▼
kube-apiserver 接收请求
│
├─ 认证 / 鉴权通过
│
├─ MutatingWebhookConfiguration 匹配
│ └─ Kyverno 接收 AdmissionReview
│ ├─ PolicyController.LoadRules()
│ ├─ PolicyController.MatchResource()
│ ├─ PolicyController.PreprocessContext()
│ ├─ PolicyController.ExecuteMutate()
│ │ └─ 返回 JSON Patch [{"op":"add","path":"/metadata/labels/security","value":"high"}]
│ └─ 返回 AdmissionResponse { allowed: true, patch: ... }
│
├─ Schema 校验(变异后的对象)
│
├─ ValidatingWebhookConfiguration 匹配
│ └─ Kyverno 接收 AdmissionReview
│ ├─ PolicyController.LoadRules()
│ ├─ PolicyController.MatchResource()
│ ├─ PolicyController.PreprocessContext()
│ ├─ PolicyController.ExecuteValidate()
│ │ └─ 校验结果:allow / deny + 消息
│ └─ 返回 AdmissionResponse { allowed: true/false, status: ... }
│
└─ 写入 etcd(仅当所有 Webhook 返回 allowed: true)
调试技巧:当策略未按预期生效时,检查以下三个位置:
1.
2. Kyverno 日志:
3. PolicyReport 资源:
1.
kubectl get validatingwebhookconfiguration kyverno-resource-validating-webhook-cfg -o yaml 确认 matchConditions 是否覆盖目标资源。2. Kyverno 日志:
kubectl logs -n kyverno -l app.kubernetes.io/name=kyverno --tail=50 查看 AdmissionReview 处理记录。3. PolicyReport 资源:
kubectl get policyreport -A 查看审计模式下的策略结果。
2.5 组件间通信总结
Kyverno 各组件之间不直接通信,全部通过 Kubernetes API Server 进行数据交换。这种设计保证了组件的松耦合与可替换性:
- Admission Controller 只与 API Server 通过 Webhook 交互,不依赖其他 Kyverno 组件。
- Reports Controller 监听 Policy 资源变化,并将执行结果写入 PolicyReport CRD。
- Background Controller 通过 Informer 监听资源变化,触发 Audit 扫描或 Generate 规则。
- Cleanup Controller 独立运行定时任务,直接调用 API Server 删除资源。
这种架构使得每个组件可以独立扩缩容、独立升级,且任意组件故障不会阻塞整个准入控制链——Admission Controller 即使无法连接 Reports Controller,仍能正常执行策略校验。