4. Kubernetes 准入控制器:Admission Webhook 原理、Mutating vs Validating Webhook、Webhook 配置示例

4.1 什么是准入控制器?

准入控制器(Admission Controller)是 Kubernetes API Server 请求链中的一道关键拦截层。当用户通过 kubectl、客户端库或 Dashboard 向 API Server 发送资源创建、更新、删除请求时,请求在通过身份认证(Authentication)和授权(Authorization)之后、被持久化到 etcd 之前,会依次经过准入控制器的处理。

准入控制器可以拦截请求并执行以下操作:

  • 变更(Mutate):修改请求中的资源对象,例如注入 Sidecar 容器、设置默认标签、调整资源配额。
  • 验证(Validate):检查请求中的资源对象是否符合集群策略,例如禁止使用特权容器、检查镜像来源、验证资源配额是否超限。

Kubernetes 内置了多种准入控制器(如 NamespaceLifecycle、LimitRanger、ResourceQuota),但内置控制器的逻辑是固定的,无法满足自定义策略需求。因此,Kubernetes 提供了 Admission Webhook 机制,允许用户通过 HTTP 回调的方式接入自定义的准入逻辑。

核心要点:Admission Webhook 是 Kubernetes 准入控制器的扩展机制,它允许集群管理员将自定义的变更或验证逻辑以 Webhook 服务的形式注册到 API Server 的请求链中。

4.2 Admission Webhook 工作原理

Admission Webhook 的工作流程可以概括为:API Server 在收到资源请求后,将请求对象序列化为 AdmissionReview 请求,发送给用户部署的 Webhook 服务;Webhook 服务处理完毕后,将处理结果(允许/拒绝、是否修改)封装在 AdmissionReview 响应中返回给 API Server;API Server 根据响应决定是否继续执行请求。

Admission Webhook 请求处理流程 用户 / kubectl API Server Mutating Webhook (变更阶段) Validating Webhook (验证阶段) etcd 请求 AdmissionReview 响应 AdmissionReview 响应 持久化 流程说明: 1. 用户发起资源请求(如创建 Pod)。 2. API Server 完成认证与授权后,进入准入控制阶段。 3. 先调用 Mutating Webhook(可修改请求对象),再调用 Validating Webhook(检查对象合法性)。 4. 所有准入控制器均通过后,API Server 将对象持久化到 etcd。 5. 若任一 Webhook 拒绝请求,API Server 立即返回错误,不执行持久化。 6. 变更阶段先于验证阶段执行,确保验证时看到的是最终对象。

4.3 Mutating vs Validating Webhook

Admission Webhook 分为两种类型,它们在请求链中的执行顺序和职责不同:

对比维度 Mutating Webhook Validating Webhook
执行顺序 先执行(变更阶段) 后执行(验证阶段)
核心职责 修改请求中的资源对象 检查资源对象是否符合策略
响应方式 返回 JSON Patch 或 JSON Merge Patch 返回 allowed: true/false
典型场景 注入 Sidecar、设置默认标签、调整资源请求/限制 禁止特权容器、检查镜像仓库白名单、验证资源配额
幂等性要求 必须幂等,避免重复注入 无特殊要求
配置资源 MutatingWebhookConfiguration ValidatingWebhookConfiguration
设计建议:在 GitOps 灰度发布场景中,通常使用 Mutating Webhook 为灰度 Pod 注入灰度标签或调整资源配额,使用 Validating Webhook 检查灰度比例是否超过阈值、镜像标签是否符合规范。

4.4 Webhook 配置示例

以下是一个完整的 ValidatingWebhookConfiguration 示例,用于验证 Pod 是否使用了允许的镜像仓库:

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: "pod-image-validator.example.com"
webhooks:
- name: "pod-image-validator.example.com"
  clientConfig:
    service:
      namespace: "webhook-system"
      name: "webhook-service"
      path: "/validate"
      port: 443
    caBundle: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."
  rules:
  - operations: ["CREATE", "UPDATE"]
    apiGroups: [""]
    apiVersions: ["v1"]
    resources: ["pods"]
    scope: "Namespaced"
  admissionReviewVersions: ["v1"]
  sideEffects: None
  timeoutSeconds: 5
  failurePolicy: Fail
  matchPolicy: Equivalent
  namespaceSelector:
    matchExpressions:
    - key: "kubernetes.io/metadata.name"
      operator: NotIn
      values: ["kube-system"]
  objectSelector: {}
  reinvocationPolicy: Never

对应的 MutatingWebhookConfiguration 示例,用于为 Pod 注入灰度标签:

apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
  name: "pod-greylabel-injector.example.com"
webhooks:
- name: "pod-greylabel-injector.example.com"
  clientConfig:
    service:
      namespace: "webhook-system"
      name: "webhook-service"
      path: "/mutate"
      port: 443
    caBundle: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."
  rules:
  - operations: ["CREATE"]
    apiGroups: [""]
    apiVersions: ["v1"]
    resources: ["pods"]
    scope: "Namespaced"
  admissionReviewVersions: ["v1"]
  sideEffects: None
  timeoutSeconds: 5
  failurePolicy: Fail
  matchPolicy: Equivalent
  reinvocationPolicy: IfNeeded
  namespaceSelector:
    matchLabels:
      greyscale-enabled: "true"

4.5 配置关键字段解析

字段 说明 推荐值
clientConfig.service Webhook 服务的 Kubernetes Service 地址 与 Webhook 部署在同一集群
clientConfig.caBundle 用于验证 Webhook 服务端证书的 CA 证书(Base64 编码) 使用 cert-manager 自动签发
rules 定义哪些资源、操作、API 版本会触发 Webhook 尽量精确,避免拦截无关请求
failurePolicy Webhook 不可用时的处理策略:Fail(拒绝请求)或 Ignore(允许请求) 生产环境建议 Fail
sideEffects Webhook 是否产生副作用:None 或 Some 推荐 None
timeoutSeconds API Server 等待 Webhook 响应的超时时间 5-10 秒
reinvocationPolicy Mutating Webhook 是否允许被再次调用(用于处理其他 Webhook 的变更) IfNeeded
安全注意事项:
  • Webhook 服务必须使用 TLS,证书由集群信任的 CA 签发。
  • 避免将 failurePolicy 设置为 Ignore 用于关键策略,否则 Webhook 故障时策略将失效。
  • 使用 namespaceSelector 和 objectSelector 缩小 Webhook 的拦截范围,降低 API Server 负载。
  • Webhook 服务应部署多个副本,并使用 PDB(PodDisruptionBudget)保证高可用。

4.6 在 GitOps 灰度发布中的应用

在本课程 GitOps 灰度发布场景中,Admission Webhook 承担以下职责:

  • Mutating Webhook:在 Pod 创建时自动注入灰度版本标签(如 version: canary)、调整资源配额(如 CPU 限制)、注入日志采集 Sidecar。
  • Validating Webhook:验证灰度 Pod 的镜像标签是否来自允许的仓库、灰度比例是否超过集群配额、是否与现有生产 Pod 存在端口冲突。

通过 Webhook 的自动化和策略化处理,GitOps 工具(如 Argo CD、Flux)在同步应用时无需手动配置灰度参数,所有准入策略由 Webhook 统一管控,实现“配置即策略”的灰度发布治理。