2. Kubernetes 准入控制基础:准入控制器的定义、工作流程与两种模式
2.1 准入控制器的定义与核心定位
准入控制器(Admission Controller)是 Kubernetes API Server 请求处理链中的一个关键拦截组件。它位于请求通过认证(Authentication)与鉴权(Authorization)之后、对象被持久化到 etcd 之前。其核心职责是拦截对 API Server 的请求,并根据预定义的逻辑对请求进行修改或验证。
关键定位:准入控制器是 Kubernetes 集群安全策略与资源治理的最后一道防线。只有通过所有准入控制器的请求,才能最终写入 etcd 并生效。
Kubernetes 内置了数十种准入控制器(如 NamespaceLifecycle、LimitRanger、ResourceQuota、PodSecurity 等),同时支持通过 Webhook 机制扩展自定义准入控制逻辑。
2.2 准入控制工作流程
一个完整的 API 请求在 Kubernetes API Server 中的处理流程如下:
- 认证(Authentication):验证请求发起者的身份(如 TLS 证书、、用户名/密码)。
- 鉴权(Authorization):判断请求者是否有权限执行该操作(基于 RBAC、ABAC 等)。
- 准入控制(Admission Control):请求进入准入控制链,依次经过所有配置的准入控制器。
- 对象验证与持久化:通过准入控制后,API Server 对对象进行 Schema 验证,然后写入 etcd。
注意:准入控制阶段是唯一可以在对象被持久化之前修改或拒绝请求的环节。认证与鉴权阶段只关注“谁”和“能否”,而准入控制关注“内容是否合规”。
2.3 Mutating 与 Validating 两种模式
准入控制器根据其行为模式分为两大类:Mutating(变更)和 Validating(验证)。两者在准入控制链中按固定顺序执行。
| 特性 | Mutating 准入控制器 | Validating 准入控制器 |
|---|---|---|
| 核心功能 | 修改(Patch)请求中的对象内容 | 验证(Validate)请求中的对象是否合规 |
| 执行顺序 | 先执行(在 Validating 之前) | 后执行(在 Mutating 之后) |
| 典型操作 | 注入 Sidecar、设置默认值、添加标签/注解 | 检查资源配额、验证安全策略、拒绝非法配置 |
| 返回结果 | 返回修改后的对象(AdmissionResponse 中带 Patch) | 返回允许(Allowed: true)或拒绝(Allowed: false + 原因) |
| 内置示例 | MutatingAdmissionWebhook、DefaultTolerationSeconds |
ValidatingAdmissionWebhook、PodSecurity、ResourceQuota |
2.4 两种模式的原理与执行顺序
Kubernetes 准入控制链的执行顺序遵循严格的规则:所有 Mutating 控制器先执行,所有 Validating 控制器后执行。这种设计确保 Validating 控制器看到的是经过所有修改之后的最终对象版本。
重要原则:如果多个 Mutating 控制器对同一字段进行修改,后执行的控制器可能覆盖先执行的控制器的修改。因此,Webhook 的配置顺序和对象选择器(objectSelector)需要仔细设计,避免冲突。
两种模式的工作原理对比如下:
- Mutating 模式:控制器接收 AdmissionReview 请求,解析其中的 Object(原始对象),根据业务逻辑生成 JSON Patch 操作(如
add、replace、remove),然后将 Patch 封装在 AdmissionResponse 中返回。API Server 应用 Patch 后得到修改后的对象。 - Validating 模式:控制器接收 AdmissionReview 请求,解析其中的 Object(此时已是经过所有 Mutating 控制器修改后的对象),执行验证逻辑(如检查字段值是否在允许范围内、是否满足安全约束等),然后返回 Allowed: true/false 以及可选的拒绝原因。
2.5 内置控制器与 Webhook 扩展
Kubernetes 提供了丰富的内置准入控制器,同时也支持通过 Webhook 机制进行自定义扩展:
| 类别 | 控制器名称 | 模式 | 功能描述 |
|---|---|---|---|
| 内置控制器 | NamespaceLifecycle |
Validating | 防止在正在终止的 Namespace 中创建新资源 |
LimitRanger |
Mutating + Validating | 为 Pod 设置默认资源请求/限制,并验证是否超出范围 | |
ResourceQuota |
Validating | 验证资源创建是否超出 Namespace 配额 | |
| Webhook 扩展 | MutatingAdmissionWebhook |
Mutating | 调用外部 HTTP 服务修改请求对象 |
ValidatingAdmissionWebhook |
Validating | 调用外部 HTTP 服务验证请求对象 |
实践建议:在实现自定义准入策略时,优先使用 Validating Webhook 进行纯验证逻辑,使用 Mutating Webhook 进行默认值注入或自动修复。避免在 Mutating Webhook 中执行复杂的验证逻辑,以免造成修改与验证的职责混淆。