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 模式,形成“先修改、后验证”的准入控制链:

  1. MutatingWebhook(变更准入):在资源持久化之前执行,用于注入默认值、添加标签/注解、设置 Pod 安全上下文等灾备策略所需的标准化配置。
  2. 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 返回准入决策的完整链路:

Kyverno 资源变更拦截与准入控制流程 用户/客户端 Kubernetes API Server MutatingWebhook 注入默认值 / 标准化配置 ValidatingWebhook 校验灾备策略合规性 策略引擎(Mutate) 匹配 → 预处理 → 执行 → 聚合 策略引擎(Validate) 匹配 → 预处理 → 执行 → 聚合 资源持久化 / 拒绝 流程说明:用户请求 → API Server 拦截 → Mutating Webhook(注入灾备标准化配置)→ Validating Webhook(校验合规性)→ 最终准入决策

4.6 准入控制流程详细步骤

结合上述架构图,完整的准入控制流程可拆解为以下 8 个步骤:

  1. 用户发起请求:通过 kubectl、API 调用或控制器向 API Server 发送资源创建/更新请求。
  2. API Server 拦截:API Server 根据注册的 MutatingWebhookConfiguration 将 AdmissionReview 请求转发至 Kyverno Webhook Server。
  3. Mutating 阶段:Kyverno 从策略缓存中加载匹配的 Mutate 规则,执行策略引擎生成 JSON Patch 补丁。
  4. 补丁应用:API Server 应用补丁,生成修改后的资源对象,并记录变更注解。
  5. Validating 阶段:API Server 将修改后的资源再次封装为 AdmissionReview,转发至 Kyverno ValidatingWebhook。
  6. 策略校验:策略引擎执行 Validate 规则,检查资源是否满足灾备策略约束(如副本数、存储类、Pod 安全策略)。
  7. 准入决策:Kyverno 返回 AdmissionResponse,包含 allowed=true/false 及失败原因。
  8. 资源持久化/拒绝: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 能够在灾备场景下提供稳定、高效、可审计的准入控制能力,确保所有资源变更都经过灾备策略的标准化注入与合规性校验。