4. 准入控制基础:Kubernetes Admission Controller 原理、Mutating 与 Validating Webhook 的区别、动态准入控制流程

4.1 什么是 Kubernetes 准入控制?

Kubernetes API Server 在处理任何资源请求(创建、更新、删除)时,会在请求被持久化到 etcd 之前,依次通过一系列称为 Admission Controller(准入控制器)的插件。这些插件可以拦截 API 请求,并根据预定义的策略对请求进行修改或验证。

准入控制是 Kubernetes 实现安全策略、资源配额、默认值注入等功能的最后一道防线。它位于认证(Authentication)和授权(Authorization)之后,确保只有符合集群规范的请求才能被持久化。

关键位置: 认证 → 授权 → 准入控制 → etcd

4.2 Admission Controller 的工作原理

Kubernetes 内置了多种 Admission Controller(如 NamespaceLifecycle、LimitRanger、PodSecurity 等),它们以插件形式注册在 API Server 中。当请求到达时,API Server 会按顺序执行以下步骤:

  1. 解析请求:将 HTTP 请求反序列化为内部对象。
  2. 执行 Mutating 准入控制器:允许修改请求对象(如注入 Sidecar、设置默认值)。
  3. 执行对象模式验证:对修改后的对象进行基本的 Schema 校验。
  4. 执行 Validating 准入控制器:验证对象是否符合业务策略(如禁止特权容器)。
  5. 持久化到 etcd:只有通过所有准入控制器的请求才会被写入存储。
Admission Controller 处理流程 用户请求 认证 授权 准入控制阶段 Mutating Webhooks Validating Webhooks etcd 持久化

4.3 Mutating 与 Validating Webhook 的区别

Kubernetes 允许通过 Dynamic Admission Control(动态准入控制) 注册外部 Webhook 服务。这些 Webhook 分为两类:

特性 MutatingAdmissionWebhook ValidatingAdmissionWebhook
核心功能 修改(Mutate)请求对象 验证(Validate)请求对象
执行顺序 先执行 后执行
典型场景 注入 Sidecar、设置默认标签、修改 Pod 安全上下文 检查镜像来源、禁止特权容器、验证资源配额
返回结果 allowed: true + 修改后的 JSON Patch allowed: true/false + 拒绝原因
幂等性要求 必须幂等(可能被多次调用) 无特殊要求
失败策略 Fail 或 Ignore Fail 或 Ignore
最佳实践: 对于同一个资源对象,建议先注册 Mutating Webhook 完成默认值注入和对象修改,再注册 Validating Webhook 进行策略校验。这样可以避免因缺少默认值而导致的误判。

4.4 动态准入控制流程详解

动态准入控制通过 MutatingWebhookConfiguration 和 ValidatingWebhookConfiguration 两种资源对象来配置。当 API Server 收到请求时,会执行以下详细流程:

  1. 匹配规则:API Server 根据 Webhook 配置中的 rules 字段(API 组、资源、操作)判断当前请求是否命中该 Webhook。
  2. 对象序列化:将请求对象序列化为 JSON,并通过 HTTPS 发送到 Webhook 服务。
  3. Webhook 处理:外部服务解析 AdmissionReview 请求,执行业务逻辑。
  4. 返回响应:Webhook 返回 AdmissionReview 响应,包含 allowed 字段和可选的 patch(仅 Mutating)。
  5. 合并结果:API Server 收集所有 Webhook 的响应,按顺序应用 Patch,并最终决定是否放行。
动态准入控制详细流程 API Server 接收请求 匹配 Webhook 规则 发送 AdmissionReview (HTTPS POST) Webhook 服务 解析请求 执行业务逻辑 返回响应 合并 Patch / 决策 etcd 持久化 拒绝请求

4.5 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: "pod-image-validator"
      path: "/validate"
    caBundle: "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t..."
  rules:
  - operations: ["CREATE", "UPDATE"]
    apiGroups: [""]
    apiVersions: ["v1"]
    resources: ["pods"]
    scope: "Namespaced"
  admissionReviewVersions: ["v1", "v1beta1"]
  sideEffects: None
  timeoutSeconds: 5
  failurePolicy: Fail
安全注意事项:
  • Webhook 服务必须使用 HTTPS,且证书由受信任的 CA 签发。
  • failurePolicy 设置为 Fail 时,如果 Webhook 服务不可用,整个集群的写入操作将被阻塞。
  • 建议为 Webhook 设置合理的 timeoutSeconds(通常 5-10 秒),避免长时间阻塞 API Server。
  • 使用 objectSelector 和 namespaceSelector 缩小 Webhook 的生效范围,减少不必要的调用。

4.6 与 Cilium 的协同点

在租户隔离场景中,Admission Controller 与 Cilium 的协同主要体现在以下方面:

协同层面 Admission Controller 职责 Cilium 职责
网络策略注入 通过 Mutating Webhook 为 Pod 自动注入网络策略标签 根据标签执行 CiliumNetworkPolicy 规则
安全基线校验 通过 Validating Webhook 禁止 Pod 使用 hostNetwork 或特权模式 通过 L7 策略限制应用层访问
租户标识绑定 在 Pod 创建时注入租户 ID 标签 基于标签实现租户间的网络隔离
策略冲突检测 在 Validating Webhook 中预检 CiliumNetworkPolicy 语法 执行最终的策略生效与冲突解决
架构建议: 将 Cilium 相关的策略校验逻辑封装为一个独立的 Validating Webhook 服务,部署在集群中。该 Webhook 可以预检 CiliumNetworkPolicy 的 CIDR 格式、标签选择器语法等,避免无效策略被提交到集群。