1. Webhook 基础:概念、准入控制机制与类型

Webhook 是 Kubernetes 动态准入控制的核心扩展机制。它允许集群管理员在 API 请求持久化之前,通过外部 HTTP 回调对资源进行修改或校验。理解 Webhook 的工作原理、准入控制链以及 Mutating 与 Validating 的职责差异,是后续并发处理与容量优化的前提。

1.1 Webhook 概念与工作原理

Webhook 本质上是一种“反向 API 回调”:Kubernetes API Server 在收到资源请求后,不直接写入 etcd,而是先向注册的外部服务发送 AdmissionReview 请求,等待该服务返回准入决策。整个过程对客户端透明,但引入了一次额外的网络调用和序列化开销。

核心流程: 客户端发起请求 → API Server 认证/授权 → 准入控制链(含 Webhook)→ 对象验证/修改 → 持久化到 etcd。

Webhook 的通信协议固定使用 HTTPS,且必须由 API Server 验证服务端证书。AdmissionReview 请求体包含 apiVersion、kind、request(用户信息、操作类型、目标对象等)和 object(旧对象/新对象)。响应体必须返回 allowed 布尔值,并可附带 patch(仅 Mutating)或 status 消息。

1.2 Kubernetes 准入控制机制

Kubernetes 的准入控制分为两个阶段:验证(Validating) 和 变更(Mutating)。所有内置和动态准入插件按顺序组成一条链,请求依次经过每个插件。Webhook 作为动态插件,被插入到这条链的指定位置。

阶段 执行顺序 典型插件 作用
变更(Mutating) 先执行 MutatingAdmissionWebhook、PodNodeSelector 修改请求对象(注入 sidecar、设置默认值)
验证(Validating) 后执行 ValidatingAdmissionWebhook、PodSecurity 校验对象是否满足策略(禁止特权容器、检查标签)
设计原则: 变更阶段先于验证阶段,确保验证时看到的是最终对象。如果 Mutating Webhook 修改了对象,Validating Webhook 必须基于修改后的版本做校验。

整个准入控制链的失败模式分为“忽略失败”和“失败关闭”。Webhook 可以通过 failurePolicy 字段控制:Fail 表示 Webhook 不可用时拒绝请求;Ignore 表示跳过该 Webhook 继续处理。生产环境建议对关键策略使用 Fail,对辅助校验使用 Ignore。

1.3 Admission Webhook 类型:Mutating 与 Validating

Kubernetes 支持两种动态准入 Webhook,分别对应变更和验证职责。它们通过不同的 API 资源注册:MutatingWebhookConfiguration 和 ValidatingWebhookConfiguration。

  • MutatingAdmissionWebhook:接收 AdmissionReview,返回 JSON Patch(RFC 6902)来修改对象。典型场景:注入 Istio sidecar、设置资源默认 requests/limits、添加标签或注解。
  • ValidatingAdmissionWebhook:接收 AdmissionReview,返回 allowed 布尔值。典型场景:校验镜像仓库白名单、禁止 hostNetwork 模式、检查资源配额。

两种 Webhook 可以同时作用于同一资源类型。Kubernetes 保证所有 Mutating Webhook 执行完毕后,再执行 Validating Webhook。如果多个 Mutating Webhook 修改同一字段,后执行的 Webhook 会覆盖前一个的修改,因此 reinvocationPolicy 字段允许在验证阶段后再次调用 Mutating Webhook 以修复不一致。

常见陷阱: 如果 Mutating Webhook 修改了对象但未正确返回 patch,API Server 会使用修改后的对象继续处理,但不会通知其他 Webhook。务必在 Webhook 响应中明确返回 patchType: "JSONPatch" 和完整的 patch 内容。

1.4 Webhook 注册配置示例

以下是一个典型的 MutatingWebhookConfiguration 片段,展示了关键字段:

apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
  name: example-mutating-webhook
webhooks:
- name: mutate.example.com
  clientConfig:
    service:
      name: webhook-service
      namespace: webhook-system
      path: /mutate
    caBundle: <base64-encoded-ca-cert>
  rules:
  - operations: ["CREATE", "UPDATE"]
    apiGroups: [""]
    apiVersions: ["v1"]
    resources: ["pods"]
  failurePolicy: Fail
  sideEffects: None
  admissionReviewVersions: ["v1"]
  timeoutSeconds: 10
  reinvocationPolicy: IfNeeded

ValidatingWebhookConfiguration 的结构完全相同,只是 kind 不同,且不需要 reinvocationPolicy 字段。

1.5 准入控制链与 Webhook 交互流程

下图展示了 API Server 内部准入控制链与外部 Webhook 服务的交互过程:

Kubernetes 准入控制链与 Webhook 交互流程 客户端 API Server 准入控制链 认证/授权 Mutating 插件 ↓ Validating 插件 ↓ 对象持久化 Webhook 服务 Mutating Validating 请求 AdmissionReview 响应 写入 etcd

1.6 两种 Webhook 的对比总结

对比维度 MutatingAdmissionWebhook ValidatingAdmissionWebhook
核心职责 修改请求对象 校验对象是否合规
响应内容 allowed: true + patch allowed: true/false
执行顺序 在 Validating 之前 在 Mutating 之后
失败策略 Fail / Ignore Fail / Ignore
重调用支持 reinvocationPolicy 不支持
典型场景 注入 sidecar、设置默认值 安全策略、资源配额校验
最佳实践: 将变更逻辑放在 Mutating Webhook 中,将校验逻辑放在 Validating Webhook 中,保持职责单一。避免在 Validating Webhook 中修改对象,或在 Mutating Webhook 中拒绝请求。