首页 / Kubernetes (k8s) 入门教程 / 准入控制(Webhook)

Kubernetes (k8s) 入门教程

准入控制(Webhook)

本教程共 65 篇 · 第 57 篇 · 更新于 2026-08-14 · 约 12 分钟阅读

Kubernetes准入控制WebhookAdmission安全

本节目标:理解准入控制在请求链路中的位置,掌握 Mutating 与 Validating 两类 Webhook 的区别,并知道怎么注册一个准入 Webhook。

你提交一个 YAML,kubectl 发出请求,Kubernetes 就立刻创建资源了吗?不是。请求在通过认证、鉴权之后,还要经过一道”准入控制”的检查关卡。很多安全策略、默认值注入,都是在这里完成的。

57-1 准入控制做什么

认证解决”你是谁”,鉴权解决”你能不能做”,而准入控制处理的是”你提交的内容合不合法、要不要补点东西”。

它只对创建、更新、删除、连接这类”写操作”生效,对读操作无效。而且 Kubernetes 可以同时开启多个准入插件,请求必须被所有插件放行,才算通过。

早期 Kubernetes 有一堆内建插件,比如限制资源配额的 ResourceQuota、自动加默认限制的 LimitRanger、自动建 ServiceAccount 的 ServiceAccount 插件。这些仍然在用,但灵活性有限。更灵活、可编程的是 Webhook。

Note

从 v1.25 起,PodSecurityPolicy(PSP)已被移除。替代它的是 Pod 安全标准(PSS)与 Pod 安全准入(PSA)。写新内容时不要再用 PSP 了。

57-2 两类 Webhook

可编程的准入控制主要靠两个插件:

  • MutatingAdmissionWebhook(变更性):在对象真正入库前,修改它的内容。比如自动给所有 Pod 注入一个 sidecar、自动补上安全上下文。多个变更 Webhook 按顺序依次执行。
  • ValidatingAdmissionWebhook(校验性):只检查、不修改。比如强制要求所有 Pod 都带某个标签、禁止用了 latest 镜像。多个校验 Webhook 并行调用,任意一个拒绝,请求就失败。

一个常见组合:先用 Mutating 注入默认值,再用 Validating 做最终合规检查。这样两道关卡配合,既友好又严格。

57-3 它是怎么工作的

Webhook 本质上是一个你自己的 HTTPS 服务。当 API 服务器收到符合条件的请求,会把对象内容打包成 AdmissionReview 发给你的服务,你的服务返回”放行”还是”拒绝”。

注册时,你要告诉 API 服务器:哪些资源、哪些操作要触发这个 Webhook。下面是一个校验 Webhook 的片段:

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: enforce-user-namespaces
webhooks:
- name: usernamespace.security.example.com
  admissionReviewVersions: ["v1"]
  rules:
  - operations: ["CREATE", "UPDATE"]
    apiGroups: [""]
    apiVersions: ["v1"]
    resources: ["pods"]
  clientConfig:
    service:
      name: usernamespace-webhook
      namespace: security-system
      path: "/validate"

rules 决定了拦截范围:这里只拦 Pod 的创建和更新。clientConfig 指向集群内一个 Service,Webhook 服务就跑在那后面。

Warning

Webhook 服务必须启用 TLS,并且要通过 caBundle 向 API 服务器证明身份。更关键的是:Webhook 一旦配置,它出问题会直接卡住整个集群的对应请求。所以 failurePolicy 要想清楚——设为 Fail 就是”连不上就拒绝”,设为 Ignore 则是”连不上就放行”。生产环境对关键校验通常选 Fail,但要保证 Webhook 高可用。

57-4 一个变更 Webhook 的例子

变更 Webhook 自动给符合条件的 Pod 开启某项能力,比如自动加上用户命名空间配置:

apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
  name: auto-usernamespace
webhooks:
- name: auto-usernamespace.security.example.com
  admissionReviewVersions: ["v1"]
  rules:
  - operations: ["CREATE"]
    apiGroups: [""]
    apiVersions: ["v1"]
    resources: ["pods"]
  namespaceSelector:
    matchLabels:
      tenant: "true"
  clientConfig:
    service:
      name: usernamespace-mutator
      namespace: security-system
      path: "/mutate"

注意这里的 namespaceSelector:只有打了 tenant: "true" 标签的命名空间里的 Pod 才会被处理。这就是用标签精确控制影响范围。

57-5 典型使用场景

Webhook 能做的事很多:

  • 安全加固:禁止特权容器、强制只读根文件系统、拦截 latest 镜像。
  • 合规检查:要求资源必须带成本中心标签、必须设资源限制。
  • 自动注入:给所有 Pod 加 sidecar、自动注入代理配置。
  • 默认填充:给没写资源的 Pod 补上默认 CPU/内存请求。
Tip

想快速体验,可以看看 cert-manager、Istio 这类项目:cert-manager 用准入 Webhook 做证书 CR 的校验与默认值注入,Istio 用变更 Webhook 自动注入 sidecar。看它们的配置比读文档更直观。

57-6 注意的事项

写准入 Webhook 有几个坑:

  • 性能:每个相关请求都要调你的服务,延迟要低,否则拖慢整个 API。
  • 可用性:Webhook 挂了,集群对应操作就卡住。务必做多副本和超时保护。
  • 环路:你的 Webhook 自身创建的资源,可能又触发自己,造成死循环。要用标签或注解跳过自身。
  • 幂等:请求可能重试,处理逻辑要能重复执行而不出错。

一句话记住:准入控制是”请求进门前最后一道安检”,Webhook 让你能把任意自定义规则接到这道门上。用好了是安全利器,用不好会拖垮整个集群。