3. Kubernetes 准入控制机制:Admission Webhook(Mutating & Validating)、内置准入控制器

Kubernetes 准入控制(Admission Control)是 API Server 请求处理链中的关键安全与策略执行环节。所有对集群资源的创建、更新、删除操作,在通过认证(Authentication)和授权(Authorization)之后、对象持久化到 etcd 之前,都必须经过准入控制器的拦截与校验。理解这一机制,是后续将 Kustomize 资源合并结果与策略引擎(OPA/Gatekeeper、Kyverno)对接的前提。

3.1 准入控制请求处理流程

一个完整的 API 请求在 Kubernetes 控制平面中的处理顺序如下:

  1. 认证(Authentication):验证请求发起者的身份(客户端证书、、Basic Auth 等)。
  2. 授权(Authorization):基于 RBAC、ABAC 或 Node 授权判断请求者是否有权执行操作。
  3. 准入控制(Admission Control):对请求对象进行拦截、修改或校验,决定是否允许请求继续。
  4. 对象持久化(etcd):通过准入控制后,对象被写入 etcd 存储。
关键概念:准入控制器分为两类——内置(Built-in)与动态(Dynamic)。动态准入控制器即 Admission Webhook,允许用户通过外部 Webhook 服务扩展准入逻辑。
Kubernetes API 请求准入控制流程 Kubernetes API 请求准入控制流程 客户端请求 认证 授权 准入控制 etcd 持久化 拒绝(403) 说明: 准入控制是认证/授权之后的最后一道防线, 只有通过所有准入控制器的请求才能写入 etcd。

3.2 内置准入控制器

Kubernetes 内置了数十个准入控制器,它们以插件形式编译在 kube-apiserver 中,通过 --enable-admission-plugins 和 --disable-admission-plugins 参数控制启停。以下是与资源合并和策略执行最相关的内置控制器:

控制器名称 类型 核心功能 与 Kustomize 策略适配的关联
NamespaceLifecycle Validating 确保命名空间存在且未被删除 Kustomize 合并后的资源必须引用存在的命名空间
MutatingAdmissionWebhook Mutating 调用外部 Webhook 修改请求对象 Kyverno 等策略引擎通过此入口注入默认值
ValidatingAdmissionWebhook Validating 调用外部 Webhook 校验请求对象 OPA/Gatekeeper 通过此入口执行策略校验
ResourceQuota Validating 校验资源配额是否超限 Kustomize 合并后的资源总量需满足配额约束
PodSecurity Mutating + Validating 实施 Pod 安全标准(PSS) Kustomize 生成的 Pod 模板需符合安全基线
实践提示:在启用动态 Webhook 之前,建议先利用内置控制器(如 PodSecurity、NamespaceLifecycle)建立基础安全防线。内置控制器性能开销低,且不依赖外部服务可用性。

3.3 Admission Webhook:Mutating 与 Validating

Admission Webhook 是 Kubernetes 1.9+ 引入的动态准入扩展机制,允许集群管理员注册外部 HTTP 回调服务来处理准入请求。根据处理阶段不同,分为两类:

  • MutatingAdmissionWebhook:在对象持久化之前,允许修改(Mutate)请求对象。常用于注入 sidecar、设置默认值、添加标签/注解等。多个 Mutating Webhook 按配置顺序链式执行。
  • ValidatingAdmissionWebhook:在对象持久化之前,仅允许校验(Validate)请求对象,不可修改。常用于执行合规策略、安全检查、资源约束校验等。

两类 Webhook 的执行顺序为:所有 Mutating Webhook 先执行 → 对象被修改后 → 所有 Validating Webhook 再执行。这一顺序对 Kustomize 资源合并后的策略适配至关重要——策略引擎(如 Kyverno)通常同时注册 Mutating 和 Validating 两种 Webhook,先通过 Mutating 注入默认值,再通过 Validating 校验最终状态。

Mutating 与 Validating Webhook 执行顺序 Mutating 与 Validating Webhook 执行顺序 原始请求对象 Mutating Webhook (修改对象) Validating Webhook (校验对象) etcd 持久化 校验失败 → 拒绝请求 关键顺序: Mutating Webhook 先执行(可修改对象)→ Validating Webhook 后执行(校验最终状态)。 Kyverno 同时注册两种 Webhook,先注入默认值再校验合规性。

3.4 Webhook 配置核心要素

注册一个 Admission Webhook 需要创建 MutatingWebhookConfiguration 或 ValidatingWebhookConfiguration 资源。以下是一个 Validating Webhook 的配置示例:

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: "pod-policy.example.com"
webhooks:
- name: "pod-policy.example.com"
  clientConfig:
    service:
      namespace: "gatekeeper-system"
      name: "gatekeeper-webhook-service"
      path: "/v1/admit"
    caBundle: "LS0tLS1CRUdJTiBDRV...=="
  rules:
  - operations: ["CREATE", "UPDATE"]
    apiGroups: [""]
    apiVersions: ["v1"]
    resources: ["pods"]
  admissionReviewVersions: ["v1"]
  sideEffects: None
  timeoutSeconds: 5
  failurePolicy: Fail
  matchPolicy: Equivalent
  namespaceSelector:
    matchLabels:
      admission.gatekeeper.sh/ignore: "no"
配置字段 说明 对 Kustomize 策略适配的影响
rules 定义 Webhook 拦截的资源类型、操作、API 组 需确保 Kustomize 合并后的资源类型在规则范围内
failurePolicy Webhook 不可用时的行为:Fail(拒绝请求)或 Ignore(允许请求) 生产环境建议 Fail,避免策略绕过
namespaceSelector 按命名空间标签过滤请求 可用于排除系统命名空间,减少 Kustomize 合并后的误拦截
timeoutSeconds Webhook 调用超时时间(默认 10s,最大 30s) Kustomize 合并复杂资源时需考虑 Webhook 处理延迟
sideEffects Webhook 是否产生副作用(None / NoneOnDryRun) 必须设置为 None,否则 dry-run 模式下会跳过
避坑指南:当 failurePolicy 设置为 Fail 时,如果 Webhook 服务不可用(如部署期间重启),整个集群的写入操作将被阻塞。建议在 Webhook 部署初期使用 Ignore,待服务稳定后再切换为 Fail。Kustomize 的 patches 和 replacements 操作可能生成大量临时资源,需确保 Webhook 的 timeoutSeconds 足够处理这些请求。

3.5 内置控制器与 Webhook 的协同关系

在实际集群中,内置控制器和动态 Webhook 共同构成多层准入防线。以下表格对比了两类控制器的典型分工:

维度 内置准入控制器 Admission Webhook
部署方式 kube-apiserver 启动参数 独立的 Webhook 服务(Pod + Service)
扩展性 固定功能,不可自定义 完全可编程,支持任意策略逻辑
性能开销 低(进程内调用) 中高(网络调用 + 序列化/反序列化)
典型场景 资源配额、命名空间管理、Pod 安全标准 合规策略、安全扫描、自定义默认值注入
与 Kustomize 的交互 对 Kustomize 合并结果透明 需关注 Webhook 对合并后资源的校验逻辑
架构建议:在 Kustomize 资源合并场景中,建议将内置控制器作为第一层防线(处理配额、命名空间等基础约束),将 OPA/Gatekeeper 或 Kyverno 作为第二层防线(处理业务合规策略)。这样既能保证基础安全,又能灵活扩展自定义策略。