2. Kyverno 架构基础:Admission Controller 模式、Webhook 生命周期、策略引擎核心组件
要理解 Kyverno 的策略冷启动瓶颈,首先需要掌握其底层架构。Kyverno 本质上是一个运行在 Kubernetes 集群内部的 动态准入控制器(Dynamic Admission Controller),它通过拦截资源请求、匹配策略规则并执行相应的 mutate/validate/generate 操作来实现策略即代码。
2.1 Admission Controller 模式:Kubernetes 请求拦截点
Kubernetes API Server 在处理任何资源请求(create/update/delete)时,会依次经过一系列内置和动态注册的 Admission Controller。Kyverno 利用的就是这一机制,将自己注册为 MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook。
关键概念:Admission Controller 是 API Server 与 etcd 之间的最后一道防线。请求必须先通过所有准入控制器的检查,才能持久化到 etcd。Kyverno 在这一环节执行策略,确保只有符合规则的资源才能被创建或更新。
Kyverno 的 Webhook 配置(MutatingWebhookConfiguration 和 ValidatingWebhookConfiguration)定义了哪些资源、哪些操作需要被拦截。默认情况下,Kyverno 会拦截所有核心资源(Pod、Service、Deployment 等)的 CREATE 和 UPDATE 操作。
| Webhook 类型 | 作用阶段 | Kyverno 行为 | 失败策略 |
|---|---|---|---|
| MutatingWebhook | 对象持久化之前,先于验证 | 执行 mutate 策略(注入 sidecar、添加标签、修改镜像等) | Fail(默认) |
| ValidatingWebhook | 对象持久化之前,后于变更 | 执行 validate 策略(检查安全上下文、资源限制、禁止特权容器等) | Fail(默认) |
冷启动关联:当 Kyverno Pod 首次启动或 Webhook 配置重新加载时,API Server 会立即将大量请求转发至 Kyverno。如果策略引擎尚未完成初始化(例如规则缓存未预热、CEL 编译环境未就绪),就会产生显著的请求排队和超时,这就是冷启动瓶颈的直接表现。
2.2 Webhook 生命周期:从注册到故障恢复
Kyverno 的 Webhook 并非静态存在,而是经历一个完整的生命周期。理解这一生命周期对于诊断冷启动问题至关重要。
- 注册阶段:Kyverno 启动时,通过
MutatingWebhookConfiguration和ValidatingWebhookConfiguration资源向 API Server 注册自身。注册信息包括 Webhook 服务地址(kyverno-svc.kyverno.svc:443)、匹配规则(resources、operations)、超时时间(默认 10s)、失败策略(Fail/Ignore)等。 - 就绪阶段:Kyverno 启动后,会等待内部策略引擎完成初始化(加载所有 ClusterPolicy/Policy、编译 CEL 表达式、预热规则缓存)。只有就绪探针(readinessProbe)通过后,Kyverno 才会开始接收请求。
- 运行阶段:API Server 将匹配的请求以
AdmissionReview对象形式发送给 Kyverno。Kyverno 处理完成后返回AdmissionResponse,包含 allowed(是否允许)、patch(mutate 操作)、status(拒绝原因)等字段。 - 故障/恢复阶段:如果 Kyverno 响应超时或返回错误,API Server 根据失败策略决定是否忽略该 Webhook(Ignore)或拒绝整个请求(Fail)。Kyverno 重启后,Webhook 配置通常保持不变,但需要重新完成就绪阶段。
冷启动陷阱:在 Kyverno 重启后的就绪阶段,如果就绪探针配置过于宽松(例如只检查 TCP 端口而不检查策略引擎是否真正就绪),API Server 可能会在引擎尚未完成初始化时就将请求转发过来,导致大量请求超时或失败。这是冷启动瓶颈的核心成因之一。
2.3 策略引擎核心组件
Kyverno 的策略引擎由多个内部组件协同工作,每个组件在冷启动时都有各自的初始化开销。
| 组件名称 | 职责 | 冷启动开销 |
|---|---|---|
| Policy Controller | 监听 ClusterPolicy/Policy 资源变化,维护策略的声明式状态 | 中等:需要从 API Server 同步所有策略定义 |
| Rule Cache | 将策略规则编译为内部可执行结构,缓存匹配结果 | 高:首次启动时缓存为空,所有规则需重新编译 |
| CEL Engine | 执行 CEL(Common Expression Language)表达式,用于复杂的条件判断 | 高:CEL 环境初始化、表达式解析和类型检查耗时显著 |
| Webhook Server | 处理 HTTP/HTTPS 请求,解析 AdmissionReview,调用引擎执行策略 | 低:主要开销在网络和序列化 |
| Metrics & Logging | 收集策略执行指标(延迟、通过率、拒绝率),输出日志 | 低:初始化后持续运行 |
2.4 组件间的依赖关系与冷启动时序
冷启动瓶颈的本质在于组件间的 串行依赖。以下是 Kyverno 启动时的关键时序:
- Pod 启动:容器启动,Webhook Server 开始监听 443 端口。
- 策略同步:Policy Controller 通过 List/Watch 从 API Server 获取所有 ClusterPolicy 和 Policy 资源。如果集群中有大量策略(例如 200+),这一步可能耗时 5-15 秒。
- 规则编译:Rule Cache 将每条策略的规则(match、exclude、mutate、validate、generate)编译为内部 AST(抽象语法树)。CEL 表达式需要额外的解析和类型检查。
- 缓存预热:编译后的规则存入内存缓存。此时缓存为空,所有请求都需要实时编译,直到缓存被填满。
- 就绪探针通过:只有上述步骤完成后,readinessProbe 才返回成功,API Server 开始转发请求。
性能数据:在 100 条策略、50 个 CEL 表达式的典型场景下,Kyverno 冷启动时间约为 20-40 秒。在此期间,如果就绪探针配置不当,API Server 可能提前转发请求,导致大量 500 错误和 AdmissionReview 超时。