4. Kyverno 架构解析:Webhook 模式、策略引擎、策略缓存、资源变更拦截与准入控制流程
Kyverno 作为 Kubernetes 原生的策略引擎,其核心架构围绕 动态准入控制(Dynamic Admission Control) 构建。本章深入解析 Kyverno 的内部组件协作机制,涵盖 Webhook 模式、策略引擎执行链路、策略缓存优化以及完整的资源变更拦截与准入控制流程。
4.1 核心架构组件与职责
Kyverno 以 Deployment 形式运行在集群中,主要包含以下关键组件:
| 组件 | 职责 | 运行模式 |
|---|---|---|
| Webhook Controller | 管理 MutatingWebhookConfiguration 和 ValidatingWebhookConfiguration 的生命周期 | 控制面组件 |
| Policy Controller | 监听 ClusterPolicy/Policy 资源,编译规则并生成策略缓存 | 控制面组件 |
| Webhook Server | 接收 API Server 的 AdmissionReview 请求,执行策略匹配与引擎调用 | 工作负载(HTTPS 服务) |
| Policy Engine | 解析规则、执行 JMESPath 表达式、调用预编译函数库 | 运行时库 |
| Cache Layer | 缓存已编译的策略规则、集群资源状态、RBAC 绑定信息 | 内存缓存 |
架构要点: Kyverno 不直接修改 API Server 源码,而是通过标准的
admissionregistration.k8s.io/v1 API 注册 Webhook,完全遵循 Kubernetes 扩展机制,具备良好的兼容性与可观测性。
4.2 Webhook 模式:Mutating 与 Validating
Kyverno 同时注册两种 Webhook 模式,形成“先修改、后验证”的准入控制链:
- MutatingWebhook(变更准入):在资源持久化之前执行,用于注入默认值、添加标签/注解、设置 Pod 安全上下文等灾备策略所需的标准化配置。
- ValidatingWebhook(验证准入):在资源经过变更后执行,用于校验最终资源是否符合灾备策略要求,如强制副本数、存储类、跨区域拓扑约束等。
两种 Webhook 的调用顺序由 API Server 的 admission webhook chain 保证:Mutating 先于 Validating,且 Kyverno 的 Mutating 阶段会为资源添加 policies.kyverno.io/last-applied 注解,供 Validating 阶段追溯变更历史。
灾备场景示例: 当用户创建 Deployment 时,Mutating Webhook 自动注入
pod-anti-affinity 规则和 topologySpreadConstraints;Validating Webhook 随后检查最终配置是否满足 minReplicas >= 3 且 storageClassName == "dr-replicated"。
4.3 策略引擎与规则执行链路
策略引擎是 Kyverno 的核心计算单元,其执行链路分为四个阶段:
| 阶段 | 输入 | 处理逻辑 | 输出 |
|---|---|---|---|
| 1. 匹配(Match) | AdmissionReview + 策略规则 | 按 resourceKind、resourceName、namespaceSelector、labelSelector 过滤 | 匹配成功/失败 |
| 2. 预处理(Preprocess) | 原始资源对象 | 执行 preconditions 检查,跳过不满足前置条件的规则 | 预处理通过/跳过 |
| 3. 执行(Execute) | 资源对象 + 规则定义 | 调用 JMESPath 表达式、条件判断、变量替换、补丁生成 | 补丁列表 / 验证结果 |
| 4. 聚合(Aggregate) | 多条规则执行结果 | 合并补丁、汇总验证失败信息、生成 AdmissionResponse | 最终准入响应 |
引擎内部使用 预编译规则缓存 避免重复解析 YAML 策略定义,JMESPath 表达式在首次执行时编译为 AST 并缓存,后续请求直接复用,显著降低延迟。
4.4 策略缓存机制
Kyverno 采用多级缓存策略来提升准入控制性能,避免每次请求都从 API Server 重新获取集群状态:
- 规则缓存(Rule Cache):存储已编译的 ClusterPolicy/Policy 对象,键为
policyName/ruleName,包含匹配条件、预编译 JMESPath 表达式、补丁模板。 - 资源缓存(Resource Cache):缓存集群中已有的 Namespace、Deployment、Service 等资源列表,用于策略中的
context变量引用(如context.namespace.labels)。 - RBAC 缓存(RBAC Cache):缓存 ServiceAccount、RoleBinding、ClusterRoleBinding 信息,用于策略中基于身份的权限校验。
缓存一致性保障: Kyverno 通过 Informer 监听机制实时更新缓存,当策略或集群资源发生变化时,缓存自动失效并重新加载。缓存默认 TTL 为 5 分钟,可通过
--cacheTTL 参数调整。在灾备场景下,建议将 TTL 缩短至 60 秒,以快速响应策略变更。
4.5 资源变更拦截与准入控制完整流程
下图展示了从用户发起资源请求到 Kyverno 返回准入决策的完整链路:
4.6 准入控制流程详细步骤
结合上述架构图,完整的准入控制流程可拆解为以下 8 个步骤:
- 用户发起请求:通过 kubectl、API 调用或控制器向 API Server 发送资源创建/更新请求。
- API Server 拦截:API Server 根据注册的 MutatingWebhookConfiguration 将 AdmissionReview 请求转发至 Kyverno Webhook Server。
- Mutating 阶段:Kyverno 从策略缓存中加载匹配的 Mutate 规则,执行策略引擎生成 JSON Patch 补丁。
- 补丁应用:API Server 应用补丁,生成修改后的资源对象,并记录变更注解。
- Validating 阶段:API Server 将修改后的资源再次封装为 AdmissionReview,转发至 Kyverno ValidatingWebhook。
- 策略校验:策略引擎执行 Validate 规则,检查资源是否满足灾备策略约束(如副本数、存储类、Pod 安全策略)。
- 准入决策:Kyverno 返回 AdmissionResponse,包含 allowed=true/false 及失败原因。
- 资源持久化/拒绝:API Server 根据决策结果将资源写入 etcd 或返回错误信息给用户。
性能优化点: 在步骤 3 和步骤 6 中,策略引擎优先查询 规则缓存 和 资源缓存,避免重复编译和远程调用。对于不匹配任何策略的请求,Kyverno 在匹配阶段即快速返回
allowed: true,不进入引擎执行,减少延迟。
4.7 灾备场景下的架构设计考量
在灾备准入策略场景中,Kyverno 架构需要额外关注以下设计要点:
| 考量维度 | 设计建议 | 说明 |
|---|---|---|
| 高可用 | Kyverno Deployment 副本数 ≥ 2,配置 PodAntiAffinity | 避免单点故障导致整个集群准入控制失效 |
| 缓存预热 | 启动时预加载所有 ClusterPolicy 和常用 Namespace 资源 | 减少首次请求的冷启动延迟 |
| 故障隔离 | 为灾备策略单独创建 Policy 资源,与通用策略分离 | 灾备策略变更不影响其他策略,降低爆炸半径 |
| 审计日志 | 启用 Kyverno 的 --audit 模式,记录所有策略评估结果 |
用于灾备合规性审计和事后追溯 |
| 超时控制 | Webhook 超时时间设置为 10s,避免长耗时策略阻塞 API Server | 灾备策略应避免复杂的外部调用,保持轻量 |
通过上述架构设计,Kyverno 能够在灾备场景下提供稳定、高效、可审计的准入控制能力,确保所有资源变更都经过灾备策略的标准化注入与合规性校验。