3. Kubernetes 准入控制机制:Admission Webhook、Mutating 与 Validating 的区别

Kubernetes API Server 在处理任何资源请求(创建、更新、删除)时,都会经过一个可插拔的准入控制(Admission Control)阶段。该阶段位于请求通过认证(Authentication)与鉴权(Authorization)之后、对象持久化到 etcd 之前。准入控制是集群安全策略、资源配额、配置注入的最后一道防线。

在 Calico 的准入策略场景中,我们主要与 Admission Webhook 打交道。Webhook 是一种特殊的准入控制器,它允许集群管理员通过 HTTP 回调将决策逻辑外置到自定义服务中。根据 Webhook 对请求对象的修改能力与执行顺序,Kubernetes 将其分为两类:MutatingAdmissionWebhook 与 ValidatingAdmissionWebhook。

Kubernetes API 请求处理流水线(准入控制阶段) 认证 Authentication 鉴权 Authorization 准入控制 Mutating Webhook 对象模式校验 Validating Webhook etcd 关键顺序: Mutating Webhook 先执行 → 对象模式校验 → Validating Webhook 后执行。Mutating 可以修改请求对象,Validating 只能读取。 Calico 准入策略中的 Webhook 调用流程 创建/更新 Pod Mutating: 注入 Sidecar 校验 Pod 规范 Validating: 策略检查 • Mutating Webhook 负责注入 Calico 网络 Sidecar 容器、设置网络注解。 • Validating Webhook 负责验证网络策略合规性、安全上下文、端口冲突。 • 两个 Webhook 共享同一个后端服务,但通过不同的路径(/mutate 与 /validate)区分。

3.1 MutatingAdmissionWebhook:修改请求对象

Mutating Webhook 在准入控制链中最先执行。它接收 API Server 发来的 AdmissionReview 请求,可以读取并修改(Patch)即将被持久化的对象。修改完成后,API Server 会使用修改后的对象继续后续的准入检查。

核心能力:修改 Pod 的 Labels、Annotations、InitContainers、Containers、Volumes、SecurityContext 等字段。

Calico 中的典型用途:

  • Sidecar 注入:自动为 Pod 添加 Calico 网络代理容器(如 envoy、felix 相关 sidecar)。
  • 网络注解注入:根据命名空间或 Pod 标签,自动设置 cni.projectcalico.org/ipAddrs 或 cni.projectcalico.org/ipv4pools 注解。
  • 安全上下文修正:为不符合策略的 Pod 自动添加 seccomp 或 AppArmor 配置。

3.2 ValidatingAdmissionWebhook:验证请求对象

Validating Webhook 在 Mutating Webhook 和对象模式校验之后执行。它只能读取 AdmissionReview 中的对象,不允许修改。如果 Validating Webhook 返回拒绝(deny),API Server 会立即终止请求,不会将对象写入 etcd。

重要:Validating Webhook 看到的是经过 Mutating Webhook 修改后的最终对象。因此,验证逻辑必须基于最终状态,而非用户原始提交的状态。

Calico 中的典型用途:

  • 网络策略合规性检查:验证 Pod 的标签是否匹配已定义的 NetworkPolicy,防止未授权访问。
  • 安全上下文验证:检查 Pod 是否以 root 运行、是否允许特权模式、是否挂载了敏感主机路径。
  • 端口冲突检测:验证同一命名空间内是否存在端口映射冲突。
  • 资源配额验证:检查 Pod 请求的资源是否超出命名空间限制。

3.3 Mutating 与 Validating 的核心区别

对比维度 MutatingAdmissionWebhook ValidatingAdmissionWebhook
执行顺序 先执行(位于准入控制链前端) 后执行(位于 Mutating 和模式校验之后)
修改能力 可以修改请求对象(JSON Patch) 只能读取,不能修改
主要职责 注入、修正、默认值填充 策略验证、合规检查、拒绝非法请求
失败行为 失败则请求被拒绝,对象不写入 etcd 失败则请求被拒绝,对象不写入 etcd
Calico 典型场景 Sidecar 注入、网络注解注入 网络策略合规、安全上下文验证
配置资源 MutatingWebhookConfiguration ValidatingWebhookConfiguration

3.4 Webhook 配置的关键字段

无论是 Mutating 还是 Validating Webhook,都需要通过对应的 Kubernetes 资源进行注册。以下是配置中的关键字段及其作用:

字段 说明 调优建议
clientConfig.service Webhook 后端服务的地址(命名空间 + 服务名 + 端口 + 路径) 使用 ClusterIP 服务,避免 DNS 解析延迟
clientConfig.caBundle 用于验证 Webhook 服务端 TLS 证书的 CA 证书 使用 cert-manager 自动轮换,避免证书过期导致 Webhook 失效
rules 定义哪些资源(apiGroups、apiVersions、resources、operations)触发 Webhook 精确限定 scope,避免不必要的 Webhook 调用
failurePolicy Webhook 不可用时的行为:Fail 或 Ignore 生产环境建议 Fail,避免策略绕过;调试阶段可用 Ignore
timeoutSeconds Webhook 调用的超时时间(1-30 秒) 默认 10 秒;高并发场景建议降低到 3-5 秒,避免 API Server 阻塞
reinvocationPolicy (仅 Mutating)是否允许后续 Mutating Webhook 再次修改已被当前 Webhook 修改过的对象 默认 Never;若需链式修改,可设为 IfNeeded
matchPolicy 匹配规则使用 Exact 还是 Equivalent 版本 建议 Equivalent,避免因 API 版本差异导致 Webhook 未触发

3.5 Webhook 调用的性能影响

Admission Webhook 是同步调用的,意味着 API Server 在收到 Webhook 响应之前会阻塞整个请求处理流程。因此,Webhook 的延迟会直接影响集群的 API 响应时间。

性能调优要点:

  • 减少 Webhook 调用次数:通过精确的 rules 和 namespaceSelector / objectSelector 过滤,只对必要的资源触发 Webhook。
  • 降低超时时间:将 timeoutSeconds 设置为 3-5 秒,避免慢 Webhook 拖垮 API Server。
  • 使用对象缓存:Webhook 服务内部缓存策略规则,避免每次调用都查询 etcd 或数据库。
  • 水平扩展:Webhook 后端服务应支持多副本,并通过 Service 负载均衡。
  • 异步处理:对于非关键验证,考虑使用 failurePolicy: Ignore 或审计日志替代同步拒绝。

3.6 Calico 中的 Webhook 配置示例

以下是一个 Calico 用于验证网络策略的 ValidatingWebhookConfiguration 示例:

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: calico-policy-validator
webhooks:
- name: policy-validator.calico.cloud
  clientConfig:
    service:
      namespace: calico-system
      name: calico-validating-webhook
      path: /validate
    caBundle: <base64-encoded-ca-cert>
  rules:
  - operations: ["CREATE", "UPDATE"]
    apiGroups: [""]
    apiVersions: ["v1"]
    resources: ["pods"]
  failurePolicy: Fail
  timeoutSeconds: 5
  matchPolicy: Equivalent
  namespaceSelector:
    matchExpressions:
    - key: kubernetes.io/metadata.name
      operator: NotIn
      values:
      - kube-system
      - calico-system
  objectSelector:
    matchLabels:
      calico-policy: "enforced"

对应的 MutatingWebhookConfiguration 结构类似,但 path 通常为 /mutate,且可以包含 reinvocationPolicy 字段。

3.7 常见问题与避坑指南

  • Webhook 死循环:Webhook 后端服务本身创建 Pod 时,如果触发了同一个 Webhook,会导致递归调用。解决方案:在 namespaceSelector 或 objectSelector 中排除 Webhook 所在的命名空间。
  • 证书过期:Webhook 使用 TLS 通信,证书过期会导致 API Server 无法调用 Webhook。建议使用 cert-manager 自动管理证书轮换。
  • 超时设置过短:如果 Webhook 处理逻辑复杂(如查询外部数据库),timeoutSeconds 设置过短会导致请求被频繁拒绝。需要根据实际处理时间合理设置。
  • Mutating 与 Validating 顺序依赖:如果 Validating Webhook 依赖 Mutating Webhook 注入的字段,必须确保 Mutating Webhook 先执行。Kubernetes 保证同一组内的 Mutating 先于 Validating 执行,但不同组之间的顺序需要显式配置 webhooks[].rules[].scope 或依赖默认顺序。