3. K8s 准入控制机制:Admission Controller 工作原理,Mutating 与 Validating Webhook 的区别
Kubernetes 的准入控制(Admission Control)是 API Server 请求链中一道关键的“安全门”。任何对集群资源进行创建、更新、删除的请求,在通过认证(Authentication)和授权(Authorization)之后,但在资源被持久化到 etcd 之前,都必须经过准入控制器的检查与处理。本章将深入剖析其工作原理,并重点对比两种 Webhook 准入控制器的核心差异。
3.1 准入控制请求处理流程
一个完整的 API 请求在 Kubernetes 中的处理顺序如下:
- 认证(Authentication):验证请求发起者的身份(如 TLS 证书、、用户名/密码)。
- 授权(Authorization):判断该身份是否拥有执行请求操作的权限(如 RBAC 检查)。
- 准入控制(Admission Control):在资源被持久化前,执行一系列内置或动态的准入插件。
- 资源持久化:将最终的对象数据写入 etcd。
准入控制阶段又细分为两个子阶段:Mutating(变更) 和 Validating(验证)。所有 Mutating 控制器先执行,所有 Validating 控制器后执行。如果任一阶段失败,请求将被拒绝。
3.2 Admission Controller 工作原理
Admission Controller 本质上是一段代码(插件),它拦截 API 请求并执行特定的逻辑。Kubernetes 内置了多种控制器(如 NamespaceLifecycle、LimitRanger、ResourceQuota、PodSecurity 等),同时也支持通过 Webhook 机制动态扩展自定义的准入控制逻辑。
Webhook 准入控制器将决策权委托给集群外部的 HTTP 回调服务。当 API Server 收到请求时,它会构造一个 AdmissionReview 对象,发送给 Webhook 服务器,并根据服务器返回的响应决定是否允许请求继续。
核心概念: AdmissionReview 是 API Server 与 Webhook 服务器之间的标准通信协议。请求中包含 object(目标资源)、oldObject(更新前的资源)、userInfo(请求用户信息)等字段。
3.3 Mutating 与 Validating Webhook 的对比
两种 Webhook 的核心区别在于执行时机与职责:
| 对比维度 | Mutating Webhook | Validating Webhook |
|---|---|---|
| 执行顺序 | 先执行(在 Validating 之前) | 后执行(在 Mutating 之后) |
| 主要职责 | 修改/注入资源对象的字段(如设置默认值、注入 Sidecar) | 校验资源对象的合法性(如检查命名规范、配额限制) |
| 对请求的影响 | 可以修改请求中的对象内容 | 只能允许或拒绝请求,不能修改对象 |
| 典型场景 | 自动注入 Istio Sidecar、设置 Pod 默认资源限制 | 校验 Pod 是否使用了禁止的镜像仓库、检查 Deployment 副本数是否在允许范围内 |
| 失败策略 | 可配置 failurePolicy: Fail 或 Ignore |
可配置 failurePolicy: Fail 或 Ignore |
| 配置资源 | MutatingWebhookConfiguration |
ValidatingWebhookConfiguration |
3.4 两种 Webhook 的协同工作流程
在同一个资源请求中,Mutating 和 Validating Webhook 可以协同工作,形成“先修改、后校验”的流水线。这种设计确保了校验逻辑能够基于最终的对象状态进行判断。
3.5 配置示例:MutatingWebhookConfiguration
以下是一个典型的 MutatingWebhookConfiguration 配置片段,用于注入默认资源限制:
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: "resource-limits-injector.example.com"
webhooks:
- name: "resource-limits.injector.example.com"
clientConfig:
service:
namespace: "webhook-system"
name: "resource-limits-webhook"
path: "/mutate"
caBundle: "LS0tLS1CRUdJTiBDRV...=="
rules:
- operations: ["CREATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
admissionReviewVersions: ["v1", "v1beta1"]
sideEffects: None
timeoutSeconds: 5
failurePolicy: Fail
reinvocationPolicy: IfNeeded
objectSelector:
matchLabels:
inject-resource-limits: "true"
3.6 配置示例:ValidatingWebhookConfiguration
以下是一个典型的 ValidatingWebhookConfiguration 配置片段,用于校验 Pod 是否使用了禁止的镜像仓库:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: "image-registry-validator.example.com"
webhooks:
- name: "image-registry.validator.example.com"
clientConfig:
url: "https://validator.example.com/validate"
caBundle: "LS0tLS1CRUdJTiBDRV...=="
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
admissionReviewVersions: ["v1", "v1beta1"]
sideEffects: None
timeoutSeconds: 3
failurePolicy: Fail
namespaceSelector:
matchExpressions:
- key: "kubernetes.io/metadata.name"
operator: NotIn
values: ["kube-system", "webhook-system"]
重要注意事项:
- 循环依赖风险:Webhook 服务本身不能触发自身的准入控制,否则会导致死锁。建议将 Webhook 部署在排除 Webhook 检查的命名空间中。
- 超时设置:Webhook 的
timeoutSeconds建议设置在 5 秒以内,避免阻塞 API Server 的请求处理。 - 失败策略:生产环境建议将关键校验的
failurePolicy设置为Fail,防止 Webhook 服务不可用时绕过安全策略。 - 幂等性:Mutating Webhook 应保证幂等性,因为同一对象可能被多次调用(如
reinvocationPolicy: IfNeeded)。
3.7 容量规划视角下的准入控制影响
从容量规划的角度,准入控制机制会引入额外的延迟和资源消耗:
- API Server 负载:每个准入 Webhook 调用都会增加 API Server 的 CPU 和内存开销,尤其是在高并发创建 Pod 的场景下。
- 网络延迟:Webhook 服务与 API Server 之间的网络往返时间(RTT)会直接影响请求处理延迟。
- Webhook 服务容量:Webhook 服务本身需要足够的副本数和资源配额,以应对突发流量。
容量规划建议:
- 监控 API Server 的
admission_webhook_request_duration_seconds指标,识别慢 Webhook。 - 为 Webhook 服务设置
HorizontalPodAutoscaler,根据请求量自动扩缩容。 - 在集群规模较大时,考虑将非关键 Webhook 的
failurePolicy设置为Ignore,避免级联故障。 - 使用
objectSelector和namespaceSelector缩小 Webhook 的生效范围,减少不必要的调用。