3. 准入控制概念:Admission Controller 的定义、作用、工作流程

准入控制(Admission Control)是 Kubernetes API Server 请求链路上的最后一个内置拦截层。当请求通过认证(Authentication)与鉴权(Authorization)之后,在对象被持久化到 etcd 之前,Admission Controller 会介入检查或修改请求内容。对于 Deployment 滚动更新场景,准入控制策略决定了哪些更新操作可以被接受、哪些需要被拒绝,以及是否需要自动注入 Sidecar、资源配额或安全策略。

3.1 定义与核心定位

Admission Controller 是一段编译进 kube-apiserver 的插件代码,或通过 Webhook 动态注册的外部服务。它拦截对 Kubernetes API 资源的 创建(CREATE)、更新(UPDATE) 和 删除(DELETE) 操作,但不处理读请求(GET/LIST/WATCH)。

特性 说明
拦截时机 认证 → 鉴权 → 准入控制 → etcd 持久化
操作类型 CREATE、UPDATE、DELETE(不拦截读操作)
执行模式 Mutating(修改请求)→ Validating(验证请求)
插件形式 内置插件(如 NamespaceLifecycle)或 Webhook(动态扩展)
关键区分:认证解决“你是谁”,鉴权解决“你能不能做”,准入控制解决“这个操作是否合规以及是否需要被修改”。

3.2 作用:为什么需要准入控制

在 Deployment 滚动更新中,准入控制承担以下四类核心职责:

  • 安全加固:强制 Pod 必须运行非 root 用户、禁止特权容器、限制 hostPath 挂载。
  • 资源治理:自动注入资源 requests/limits 默认值,防止更新后的 Pod 因未设置资源限制而影响集群稳定性。
  • 策略执行:确保 Deployment 的 strategy.rollingUpdate.maxSurge 和 maxUnavailable 不超过集群管理员设定的阈值。
  • 自动化注入:在滚动更新时自动为 Pod 注入日志采集 Sidecar、服务网格代理(如 Istio sidecar)或监控探针。
滚动更新场景示例: 当用户提交 kubectl set image deployment/nginx nginx=nginx:1.25 时,准入控制器可以检查新镜像是否来自受信任的镜像仓库,并自动添加 readinessProbe 默认配置。

3.3 工作流程:从请求到持久化的完整路径

一个完整的准入控制工作流程包含以下 7 个步骤,其中步骤 3 和步骤 4 是准入控制的核心阶段:

  1. 客户端发起请求:用户或控制器通过 kubectl、API 或 client-go 向 kube-apiserver 发送请求。
  2. 认证与鉴权:验证请求者身份和权限。
  3. Mutating Admission(变更准入):按顺序执行所有 Mutating 插件或 Webhook,允许修改请求对象(如注入默认值、添加标签)。
  4. 对象验证:对修改后的对象执行 schema 校验(如必填字段检查)。
  5. Validating Admission(验证准入):按顺序执行所有 Validating 插件或 Webhook,拒绝不合规的请求。
  6. 持久化:通过验证的对象被写入 etcd。
  7. 响应返回:apiserver 将结果返回给客户端。
准入控制工作流程(从请求到持久化) ① 客户端请求 ② 认证 + 鉴权 ③ Mutating Admission (修改请求对象) ④ Schema 验证 (字段格式检查) ⑤ Validating Admission (拒绝不合规请求) ⑥ 持久化到 etcd ⑦ 响应返回 Mutating 先执行 Validating 后执行

3.4 Mutating 与 Validating 的对比

两种准入控制器在滚动更新场景中扮演不同角色,理解其差异有助于设计正确的策略链:

维度 Mutating Admission Controller Validating Admission Controller
执行顺序 先执行 后执行
核心能力 修改请求对象(注入、替换、补全) 验证请求对象(拒绝、告警、审计)
滚动更新场景 自动注入 securityContext、资源默认值 校验 maxSurge 是否超过 25% 阈值
失败影响 修改失败 → 请求被拒绝 验证失败 → 请求被拒绝
典型内置插件 MutatingAdmissionWebhook、DefaultTolerationSeconds ValidatingAdmissionWebhook、PodSecurity
重要顺序约束:如果 Mutating 控制器修改了对象,Validating 控制器看到的是修改后的版本。因此,在滚动更新策略中,默认值注入必须在策略校验之前完成,否则校验逻辑可能因缺少字段而误判。

3.5 内置插件与 Webhook 的架构关系

Kubernetes 提供两种方式启用准入控制:内置插件(In-tree Plugins) 和 动态 Webhook。内置插件编译在 kube-apiserver 中,通过 --enable-admission-plugins 启动;Webhook 则通过外部 HTTP 回调实现,支持热更新。

内置插件 vs Webhook 架构 内置插件(In-tree) kube-apiserver 进程内 编译时注册,不可热更新 性能高,无网络延迟 示例:NamespaceLifecycle、PodSecurity 动态 Webhook(Out-of-tree) 外部 HTTP 服务 运行时注册,支持热更新 增加网络延迟与故障点 示例:OPA Gatekeeper、Kyverno 对比

3.6 滚动更新中的典型准入控制链

在 Deployment 滚动更新场景中,一个典型的准入控制链按以下顺序执行:

  1. MutatingAdmissionWebhook(策略注入器):自动为 Pod 添加 securityContext.runAsNonRoot: true 和资源 requests 默认值。
  2. DefaultTolerationSeconds:为未设置 tolerationSeconds 的 Pod 注入默认容忍时间。
  3. ResourceQuota:验证更新后的 Deployment 是否超出命名空间资源配额。
  4. ValidatingAdmissionWebhook(策略校验器):检查 maxSurge 和 maxUnavailable 是否在管理员定义的范围内。
  5. PodSecurity:确保更新后的 Pod 不违反 Pod 安全标准(Privileged/Baseline/Restricted)。
实践建议:在部署滚动更新策略时,优先使用 Kyverno 或 OPA Gatekeeper 作为 Validating Webhook,因为它们支持声明式策略编写,且无需重启 kube-apiserver 即可更新规则。