Kubernetes 准入控制基础:Admission Controller 工作原理与 Webhook 模式
准入控制(Admission Control)是 Kubernetes API Server 请求处理链中的关键环节,位于认证(Authentication)与授权(Authorization)之后、对象持久化(etcd 存储)之前。它能够拦截、修改甚至拒绝 API 请求,是实现资源配额、安全策略、网络策略合规性检查的核心机制。
2.1 准入控制工作原理
Kubernetes API Server 在处理一个创建或更新资源的请求时,会依次经过以下三个阶段:
- 认证(Authentication):验证请求发起者的身份(如 TLS 证书、、用户名/密码)。
- 授权(Authorization):判断请求者是否拥有执行该操作的权限(RBAC、ABAC 等)。
- 准入控制(Admission Control):在对象被持久化之前,执行一系列预定义的插件或 Webhook 逻辑。
下图展示了 API 请求在 Kubernetes API Server 内部的完整处理流程,重点突出准入控制阶段的位置与作用:
2.2 Webhook 模式:Mutating 与 Validating
Kubernetes 从 1.9 版本开始引入了动态准入控制(Dynamic Admission Control),允许集群管理员通过 Webhook 方式注册自定义的准入控制器,而无需修改或重新编译 API Server。Webhook 模式分为两种类型:
| 特性 | MutatingAdmissionWebhook | ValidatingAdmissionWebhook |
|---|---|---|
| 执行顺序 | 先执行(在对象持久化之前) | 后执行(在 Mutating 之后) |
| 核心功能 | 修改(Mutate)请求对象,如注入 Sidecar、设置默认值、修正标签 | 验证(Validate)请求对象,如检查资源配额、安全上下文、网络策略合规性 |
| 返回结果 | 返回修改后的对象(JSON Patch)或拒绝请求 | 返回允许(Allowed: true)或拒绝(Allowed: false + 原因) |
| 典型场景 | Istio Sidecar 注入、资源限制默认值、Pod 标签标准化 | 禁止特权容器、检查镜像来源、验证 Ingress 域名唯一性 |
| 幂等性要求 | 必须幂等(多次执行结果一致) | 无强制要求,但建议幂等 |
2.3 Webhook 配置与通信流程
Webhook 的配置通过 MutatingWebhookConfiguration 和 ValidatingWebhookConfiguration 两种资源对象定义。API Server 在收到请求后,会根据配置中的规则(rules)匹配目标资源,然后向指定的 Webhook 服务发送 AdmissionReview 请求。
一个典型的 Webhook 配置包含以下关键字段:
- clientConfig:Webhook 服务的地址(URL 或 Service 引用)及 CA 证书。
- rules:匹配规则(API 组、版本、资源、操作类型)。
- failurePolicy:Webhook 不可用时的处理策略(Fail 或 Ignore)。
- sideEffects:Webhook 是否具有副作用(None 或 Some)。
- timeoutSeconds:超时时间(默认 10 秒,建议不超过 30 秒)。
下图展示了 Mutating 与 Validating Webhook 在请求处理链中的协作关系:
2.4 AdmissionReview 请求与响应格式
API Server 与 Webhook 服务之间通过 HTTPS 交换 AdmissionReview 对象。Webhook 服务需要解析请求并返回响应。以下是请求与响应的核心结构:
// 请求示例(API Server → Webhook)
{
"apiVersion": "admission.k8s.io/v1",
"kind": "AdmissionReview",
"request": {
"uid": "705ab4f5-6393-11e8-b7cc-42010a800002",
"kind": {"group":"","version":"v1","kind":"Pod"},
"resource": {"group":"","version":"v1","resource":"pods"},
"namespace": "default",
"operation": "CREATE",
"object": { ... }, // 完整的资源对象
"oldObject": null, // 仅 UPDATE/DELETE 时有值
"dryRun": false
}
}
// 响应示例(Webhook → API Server)
{
"apiVersion": "admission.k8s.io/v1",
"kind": "AdmissionReview",
"response": {
"uid": "705ab4f5-6393-11e8-b7cc-42010a800002",
"allowed": true,
"patch": "W3sib3AiOiAiYWRkIiwgInBhdGgiOiAiL3NwZWMvY29udGFpbmVycy8tIiwgInZhbHVlIjog...",
"patchType": "JSONPatch",
"status": {"code": 200}
}
}
- Webhook 超时设置不宜过长(建议 5-10 秒),避免阻塞 API Server 请求队列。
- 必须使用 TLS 证书加密通信,防止中间人攻击。
- Mutating Webhook 必须保证幂等性,避免多次注入导致对象膨胀。
- 合理使用
failurePolicy: Ignore避免 Webhook 故障导致集群不可用。
2.5 内置准入控制器与 Webhook 的协同
Kubernetes 内置了数十个准入控制器(如 NamespaceLifecycle、LimitRanger、ResourceQuota、PodSecurity 等),它们与 Webhook 模式共同构成完整的准入控制体系。下表对比了两者的适用场景:
| 维度 | 内置准入控制器 | Webhook 模式 |
|---|---|---|
| 部署方式 | API Server 启动参数中启用(静态编译) | 动态注册,无需重启 API Server |
| 灵活性 | 固定逻辑,不可自定义 | 完全自定义,支持任意业务逻辑 |
| 性能开销 | 低(进程内调用) | 中等(网络调用 + JSON 序列化) |
| 维护成本 | 低(Kubernetes 原生维护) | 高(需自行开发、部署、监控 Webhook 服务) |
| 典型用途 | 资源配额、命名空间管理、Pod 安全策略基础 | 自定义策略引擎、第三方集成(如 OPA/Gatekeeper、Kyverno) |