Kubernetes 中的 Mutating 与 Validating Webhooks

发布: (2026年2月12日 GMT+8 15:00)
7 分钟阅读
原文: Dev.to

Source: Dev.to

准入控制器阶段

什么是 Admission Controllers?

Admission Controller 是一段代码,它会在 身份验证和授权 之后、对象写入 etcd 之前 拦截对 Kubernetes API Server 的请求。

通俗来说:它们是 Kubernetes API 的中间件。

如果你运行:

kubectl apply -f deployment.yaml

请求的流转过程如下:

请求 → Authentication → Authorization → Mutating Admission → Schema Validation → Validating Admission → etcd

Admission Controllers 正好位于这条流水线的中间。

两类主要的 Admission 控制器

变更(Mutating)Admission 控制器

这些可以在请求被存储之前修改传入的请求。

常见示例:

  • 添加默认标签
  • 注入 sidecar 容器(例如使用 Istio)
  • 添加默认资源限制
  • 覆盖缺失的字段

变更控制器首先运行。它们接收你的原始对象并被允许对其进行更改。

验证(Validating)Admission 控制器

这些不能修改请求;它们只做出以下决定:

  • 允许
  • 拒绝

示例:

  • 阻止特权容器
  • 强制执行镜像仓库策略
  • 验证必需标签
  • 强制执行命名标准

验证控制器在变更之后运行,这意味着它们看到的是对象的最终版本。此顺序非常重要。

静态 vs. 动态 Admission 控制器

静态(内置)

这些随 Kubernetes 一起提供,并通过 API 服务器标志启用:

--enable-admission-plugins

常见的内置插件:

  • NamespaceLifecycle
  • LimitRanger
  • ResourceQuota
  • ServiceAccount

例如,NamespaceLifecycle 会阻止你在正在终止的命名空间中创建新资源。许多人认为的“核心 Kubernetes 行为”实际上是通过这些内置 admission 控制器实现的。

动态(基于 Webhook)

这些更灵活,包括:

  • MutatingAdmissionWebhook
  • ValidatingAdmissionWebhook

Kubernetes 不再将逻辑直接嵌入 API 服务器,而是调用外部 HTTPS 服务(Webhook),并询问:

  • “这个请求可以吗?”
  • “你想要修改什么吗?”

你可以使用任何能够提供 HTTPS 的语言实现自定义逻辑(Go、Python、Node 等)。这就是它强大的地方。

Source:

为什么 Admission Controllers 很重要

在真实的集群中,大多数使用场景可以归为两类:安全治理

安全

Admission controller 可以在整个集群范围内强制执行安全基线。

示例:

  • 阻止以 root 身份运行的容器
  • 只允许来自可信仓库的镜像
  • 强制只读根文件系统
  • 防止使用 hostPath

例如,你可以拒绝任何包含以下内容的 Deployment:

securityContext:
  privileged: true

仅此一项就能防止严重的安全风险。

治理与合规

它们还帮助强制组织标准:

  • 命名约定
  • 必需的标签
  • 资源限制
  • 副本数限制

例如,你可以强制要求每个 Deployment 必须包含:

labels:
  environment: production

没有标签?不允许部署。简单而有效。

真实案例:Ingress 控制器

在安装像 F5 NGINX Ingress Controller 这样的 Ingress 控制器时,你会注意到它会创建:

  • MutatingWebhookConfiguration
  • ValidatingWebhookConfiguration

为什么?因为 Kubernetes 并不理解 NGINX 特有的配置逻辑。

该 Webhook:

  • 验证 Ingress 注解
  • 防止无效的配置
  • 阻止错误的 NGINX 重载
  • 保护生产流量

如果没有这一层,错误的 Ingress 定义可能会生成无效的 NGINX 配置,从而影响实时流量。Webhook 就是你的安全网。

Source:

变更(Mutating)和验证(Validating)如何协同工作

假设你创建了如下的 Deployment:

replicas: 1

可能会发生的情况:

  1. 变更(mutating) webhook 将 replicas 改为 3
  2. 验证(validating) webhook 检查 replicas 是否不大于 5
    • 若符合要求 → 对象被存入 etcd。

这种分层方式确保:

  • 应用默认值
  • 强制执行策略
  • 错误的配置永远不会进入集群状态

启用准入控制器

在 API 服务器上,使用以下方式启用它们:

--enable-admission-plugins=MutatingAdmissionWebhook,ValidatingAdmissionWebhook

验证 webhook 支持:

kubectl api-versions | grep admissionregistration.k8s.io

如果看到:

admissionregistration.k8s.io/v1

则表示可以继续。

编写自己的 Admission Controller

如果你想自己构建一个,以下是高级流程:

  1. 构建 HTTPS 服务
  2. 接受 AdmissionReview 对象
  3. 返回
    • allowed: true/false
    • 可选:JSON patch(用于变更)
  4. 使用以下方式注册
    • MutatingWebhookConfiguration
    • ValidatingWebhookConfiguration

你的 webhook 必须:

  • 使用 TLS
  • 在集群内部可达
  • 在配置中包含 CA 包

配置完成后,Kubernetes 将在每次创建、更新或删除匹配的资源时调用你的服务。

最后思考

Admission Controllers 是 Kubernetes 中最强大 — 且常被忽视 — 的功能之一。
它们在 API 服务器内部提供了一个可编程的控制层。

如果你在生产环境中运行 Kubernetes,却没有使用 Admission Controllers,那么你完全依赖开发者自行“做好事”。我们都知道这通常会怎样。

明智地使用它们 — 你的集群将变得更安全、更可预测。

0 浏览
Back to Blog

相关文章

阅读更多 »

KAIzen — AI 时代对敏捷的需求

一家游戏公司的小团队如何将流效率从 32% 提升到 85%——通过改变我们提供给 AI 的内容。我们的团队严格遵循 Scrum:两周的 s...