3. Kyverno 基础架构:组件、工作流程与对比

本章深入剖析 Kyverno 的策略引擎核心。理解其内部组件、请求处理流程以及与业界主流方案 OPA/Gatekeeper 的差异,是后续在 GitOps 架构中正确落地 Kyverno 的前提。我们将从三个维度展开:组件职责、端到端工作流、以及关键对比分析。

3.1 核心组件架构

Kyverno 以 Kubernetes 原生方式运行,其架构由三个主要组件构成,它们协同工作以实现策略的声明式管理和动态执行。

关键设计理念: Kyverno 本身就是一个运行在集群内的 Kubernetes 控制器,它利用标准的 Admission Webhook 机制拦截资源请求,无需重新编译 kube-apiserver 或引入外部 Sidecar。
Kyverno 核心组件架构图 Kyverno 核心组件架构 kube-apiserver Admission Webhook (Mutating / Validating) Policy Controller (策略引擎) Report Controller (策略报告) 说明:所有组件均以 Deployment 形式运行在 kyverno 命名空间,通过 CRD 与 kube-apiserver 交互。

3.1.1 组件职责详解

组件名称 核心职责 关键特性
Admission Controller 注册并管理 MutatingWebhookConfiguration 和 ValidatingWebhookConfiguration,拦截资源请求。 自动管理 Webhook 证书;支持故障注入模式(Fail/ Ignore)。
Webhook Server 接收 kube-apiserver 转发的 AdmissionReview 请求,执行策略匹配与处理。 内置 Mutating(修改资源)和 Validating(验证资源)两种端点。
Policy Controller 监听 ClusterPolicy / Policy CRD 资源,将策略规则编译为可执行的匹配模式。 支持背景扫描(Background Scan)和准入控制两种模式。
Report Controller 生成并管理 PolicyReport 和 ClusterPolicyReport 资源,记录策略执行结果。 支持聚合报告、失败原因记录、与审计系统集成。

3.2 工作流程:从策略定义到执行

Kyverno 的工作流程分为两个主要阶段:策略加载与编译阶段 和 资源请求处理阶段。理解这两个阶段有助于排查策略未生效或误拦截问题。

3.2.1 策略加载与编译阶段

  1. 策略创建: 用户通过 kubectl apply 创建 ClusterPolicy 或 Policy 资源。
  2. 策略监听: Policy Controller 通过 Informer 机制监听 CRD 变化。
  3. 规则编译: 将 YAML 中的 match、exclude、validate、mutate、generate 规则编译为内部 AST(抽象语法树)。
  4. Webhook 注册: Admission Controller 根据策略的 match 规则,自动更新 Webhook 配置,决定拦截哪些资源类型和操作。

3.2.2 资源请求处理阶段

  1. 请求发起: 用户或控制器向 kube-apiserver 发送资源创建/更新/删除请求。
  2. 请求拦截: kube-apiserver 根据注册的 Webhook 配置,将请求封装为 AdmissionReview 对象,发送给 Kyverno Webhook Server。
  3. 策略匹配: Webhook Server 根据请求的资源类型、命名空间、操作类型,匹配已编译的策略规则。
  4. 策略执行:
    • Mutating 策略: 修改请求中的资源对象(如注入 Sidecar、添加标签)。
    • Validating 策略: 验证资源对象是否符合规则,返回允许或拒绝。
    • Generate 策略: 在后台创建关联资源(如自动创建 NetworkPolicy)。
  5. 响应返回: Webhook Server 将处理结果(允许/拒绝/补丁)封装为 AdmissionReview 响应,返回给 kube-apiserver。
  6. 报告生成: Report Controller 异步生成 PolicyReport,记录本次策略执行结果。
GitOps 集成提示: 在 GitOps 工作流中,策略定义(ClusterPolicy)应存储在 Git 仓库中,通过 ArgoCD 或 Flux 同步到集群。Kyverno 的 generate 策略特别适合自动创建 GitOps 工具所需的 RBAC 或网络策略。
Kyverno 请求处理工作流程 Kyverno 资源请求处理工作流程 用户 / 控制器 kubectl apply kube-apiserver AdmissionReview Kyverno Webhook Server Mutating Validating 策略匹配 & 修改 策略验证 响应返回 API Server PolicyReport 生成

3.3 Kyverno 与 OPA/Gatekeeper 对比

OPA(Open Policy Agent)结合 Gatekeeper 是 Kubernetes 生态中另一主流的策略引擎方案。两者在设计哲学、策略语言、集成方式上存在显著差异。下表从多个关键维度进行对比,帮助团队根据自身场景做出技术选型。

对比维度 Kyverno OPA / Gatekeeper
策略语言 纯 YAML(声明式),无学习曲线 Rego(声明式 + 逻辑编程),学习曲线陡峭
策略定义方式 Kubernetes CRD(ClusterPolicy / Policy) ConstraintTemplate(CRD)+ Constraint(CRD 实例)
Mutation 支持 原生支持(mutate 规则),无需额外配置 需要额外部署 Mutation Webhook 或使用 OPA 外部数据
背景扫描 内置支持,自动扫描现有资源并生成报告 需要额外配置 Audit 组件,报告格式为 Constraint 状态
策略生成 支持 generate 规则,自动创建关联资源 不支持原生生成,需结合其他工具
性能开销 较低,原生 Go 实现,直接处理 JSON 中等,Rego 编译和查询有一定开销
社区与生态 Nirmata 主导,CNCF 沙箱项目,增长迅速 CNCF 毕业项目,生态成熟,企业支持广泛
GitOps 友好度 极高,策略即 YAML,可直接存储在 Git 中 较高,但 ConstraintTemplate 需额外管理
选型建议: 如果团队以 YAML 工程师为主,追求低学习成本和 GitOps 原生集成,Kyverno 是更优选择。如果团队已有 Rego 经验,或需要跨平台(K8s + 非 K8s)统一策略引擎,OPA/Gatekeeper 更具优势。在 GitOps 架构中,Kyverno 的纯 YAML 策略定义和自动生成能力能显著降低运维复杂度。

3.3.1 策略语言对比示例

以下展示同一个策略(要求 Deployment 必须设置 resources.limits.cpu)在两种引擎中的定义差异。

Kyverno (YAML):

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-cpu-limits
spec:
  validationFailureAction: Enforce
  rules:
  - name: check-cpu-limits
    match:
      any:
      - resources:
          kinds:
          - Deployment
    validate:
      message: "Deployment 必须设置 CPU limits"
      pattern:
        spec:
          template:
            spec:
              containers:
              - resources:
                  limits:
                    cpu: "? *"

OPA / Gatekeeper (Rego):

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8srequiredlimits
spec:
  crd:
    spec:
      names:
        kind: K8sRequiredLimits
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8srequiredlimits
        violation[{"msg": msg}] {
          container := input.review.object.spec.template.spec.containers[_]
          not container.resources.limits.cpu
          msg := sprintf("容器 %v 必须设置 CPU limits", [container.name])
        }
---
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLimits
metadata:
  name: require-cpu-limits
spec:
  match:
    kinds:
      - apiGroups: ["apps"]
        kinds: ["Deployment"]
关键差异总结: Kyverno 的策略定义更接近 Kubernetes 原生资源描述,而 OPA/Gatekeeper 需要编写 Rego 逻辑并管理两层 CRD(Template + Constraint)。在 GitOps 场景下,Kyverno 的策略文件可以直接被 ArgoCD 识别为普通 Kubernetes 资源,无需额外处理 Rego 编译。