2. Kyverno 基础架构:组件、工作流程与策略引擎原理
理解 Kyverno 的基础架构是编写精准策略的前提。本章将拆解 Kyverno 的核心组件、准入控制器的完整工作流程,以及策略引擎如何评估和生成策略结果。掌握这些底层机制,能帮助你在面对复杂的安全基线场景时,快速定位策略失败原因并优化规则。
2.1 Kyverno 核心组件
Kyverno 以 Kubernetes 原生方式部署,主要包含以下三个关键组件,它们协同完成策略的加载、监听与执行。
| 组件名称 | 部署形态 | 核心职责 |
|---|---|---|
| Kyverno Admission Controller | Deployment(通常 2 副本) | 接收 API Server 的准入审查请求,调用策略引擎执行匹配与验证,返回准入响应。 |
| Kyverno Cleanup Controller | Deployment(通常 1 副本) | 管理 CleanupPolicy 资源,按 CronJob 调度清理过期或不符合策略的资源。 |
| Kyverno Reports Controller | Deployment(通常 1 副本) | 生成并维护 ClusterPolicyReport / PolicyReport,记录策略在集群中的历史评估结果。 |
关键认知: 在安全基线场景中,Admission Controller 是实时拦截高风险变更的第一道防线;Reports Controller 则用于事后审计和合规性巡检,两者互补。
2.2 准入控制器工作流程
当用户通过 kubectl apply 或 API 调用创建/更新资源时,Kyverno 的准入流程按以下步骤执行:
- API Server 接收请求:请求进入 Kubernetes API Server 的准入控制链。
- MutatingWebhookConfiguration 触发:Kyverno 注册的变更 Webhook 被调用,请求被转发至 Kyverno Admission Service。
- 策略匹配与变量注入:Kyverno 根据资源类型、标签、命名空间等匹配策略;若策略包含
preconditions,则先评估条件是否满足。 - 执行 mutate 规则:对匹配的资源进行 JSON 补丁操作(如自动添加安全上下文、只读根文件系统等)。
- ValidatingWebhookConfiguration 触发:变更完成后,验证 Webhook 被调用,再次将请求转发至 Kyverno。
- 执行 validate 规则:策略引擎对资源进行模式匹配或条件判断,生成
pass/fail结果。 - 返回准入响应:Kyverno 将
AdmissionResponse返回给 API Server,允许或拒绝资源创建/更新。
安全基线水位关键点: 步骤 4 和步骤 6 是策略生效的核心环节。对于高风险变更(如特权容器、hostPath 挂载),应在 validate 阶段直接拒绝;对于可自动修复的配置(如缺失的 readOnlyRootFilesystem),应在 mutate 阶段自动注入。
2.3 策略引擎原理
Kyverno 的策略引擎并非简单的规则匹配,它包含一套完整的评估生命周期。理解引擎的内部机制,有助于编写更高效、更精确的安全策略。
2.3.1 策略评估生命周期
- 加载阶段:Kyverno 启动时从集群中加载所有
ClusterPolicy和Policy资源,构建策略索引。 - 匹配阶段:根据准入请求中的资源类型(Kind)、API 版本、命名空间、标签选择器(
match/exclude)进行第一层过滤。 - 预处理阶段:解析策略中的
preconditions,使用 JMESPath 表达式从资源对象中提取字段,判断是否满足前置条件。 - 执行阶段:按规则类型(mutate / validate / generate)执行具体逻辑。对于 validate 规则,支持
pattern(模式匹配)、anyPattern(任一模式)、deny(条件拒绝)三种模式。 - 结果聚合阶段:将多条规则的评估结果聚合为最终的
AdmissionResponse。若任一 validate 规则失败,则整个请求被拒绝。
常见陷阱: 在安全基线策略中,
preconditions 使用不当可能导致策略“静默失效”。例如,检查 request.object.spec.containers[].securityContext 时,若容器未定义 securityContext,JMESPath 返回空值,可能导致 precondition 意外跳过。建议使用 contains 或 length 函数做防御性判断。
2.3.2 规则类型对比
| 规则类型 | 触发时机 | 安全基线典型用途 | 失败行为 |
|---|---|---|---|
| mutate | 变更 Webhook | 自动注入只读根文件系统、默认 seccomp 配置 | 补丁失败则拒绝请求 |
| validate | 验证 Webhook | 拒绝特权容器、禁止 hostPath、强制只读挂载 | 验证失败则拒绝请求 |
| generate | 资源创建后 | 自动生成 NetworkPolicy、LimitRange 等基线资源 | 生成失败记录事件,不阻塞原请求 |
2.4 策略引擎的变量与上下文
Kyverno 策略引擎在评估时,会构建一个丰富的上下文对象,供 JMESPath 表达式引用。以下是安全基线策略中最常用的上下文变量:
request.object:正在被创建或更新的资源对象。request.oldObject:更新操作前的资源对象(用于检测变更)。request.namespace:资源所属的命名空间。request.userInfo:发起请求的用户信息(用于 RBAC 审计)。images:解析后的容器镜像列表,包含 registry、repository、tag 和 digest。
安全基线实战技巧: 在编写拒绝特权容器的策略时,使用
request.object.spec.containers[].securityContext.privileged 结合 contains 函数,可以精准捕获显式设置为 true 的容器。对于未设置该字段的容器,表达式返回 null,不会误拦截。
2.5 安全基线水位下的架构要点总结
- 组件冗余:Admission Controller 建议至少 2 副本,避免单点故障导致集群不可用。
- Webhook 超时:Kubernetes 默认 Webhook 超时为 30 秒,复杂策略应优化 JMESPath 表达式,避免超时导致请求被拒绝。
- 策略顺序:mutate 规则先执行,可用于自动修复低风险配置;validate 规则后执行,用于拦截高风险变更。
- 审计模式:在安全基线水位上线初期,建议将 validate 规则设置为
audit模式(不拒绝请求,仅记录报告),验证策略准确性后再切换为enforce模式。
下一步行动: 在理解了 Kyverno 的组件与工作流程后,第 3 章将深入讲解如何编写具体的安全基线策略,包括特权容器、hostPath、容器用户权限等高风险场景的规则实现。