2. Kubernetes API 请求生命周期:从用户到 etcd 的完整路径

理解 Kubernetes API 请求的完整生命周期,是掌握准入控制 Webhook 拦截时机与作用范围的前提。一个典型的 kubectl 请求从用户终端发出,到最终持久化至 etcd,需要依次经过 认证、授权、准入控制链 三大核心阶段。准入控制 Webhook 正是嵌入在准入控制链中的动态扩展点。

2.1 请求生命周期的五阶段模型

Kubernetes API 请求的处理可抽象为五个连续阶段,每个阶段承担不同的安全与校验职责:

阶段 组件/模块 核心职责 是否可拦截/修改
1. 客户端发起 kubectl / client-go / curl 构造 HTTP 请求,携带认证凭据 否(客户端侧)
2. 认证 API Server 认证模块 验证请求者身份(证书//基本认证) 否
3. 授权 API Server 授权模块 判断请求者是否有权限执行操作(RBAC/ABAC) 否
4. 准入控制链 MutatingWebhook → 对象校验 → ValidatingWebhook 拦截、修改、校验资源对象 是(Webhook 核心位置)
5. 持久化 etcd 存储最终资源对象 否
关键理解: 准入控制链是 API 请求从“安全校验”进入“业务逻辑校验”的分水岭。认证与授权只回答“你是谁”和“你能做什么”,而准入控制回答“你提交的内容是否合规”。

2.2 认证(Authentication)

认证阶段负责识别请求者的身份。Kubernetes 支持多种认证方式,按配置顺序依次尝试,直到有一个模块成功返回用户信息:

  • X.509 客户端证书:通过 TLS 客户端证书中的 CN 字段提取用户名。
  • Bearer :包括 Service Account 、OIDC 、Bootstrap 。
  • HTTP Basic Auth:静态密码文件(已弃用,仅用于测试)。
  • Webhook 认证:将 发送给外部认证服务验证。

认证通过后,API Server 会提取出 UserInfo 对象,包含 username、uid、groups 和 extra 字段,传递给后续阶段。

2.3 授权(Authorization)

授权阶段根据认证阶段提取的 UserInfo,判断请求者是否被允许执行当前操作。Kubernetes 默认使用 RBAC(基于角色的访问控制):

# 授权检查的核心逻辑(伪代码)
func Authorize(ctx context.Context, user UserInfo, resource Resource, verb Verb) bool {
    // 1. 查找用户绑定的所有 Role/ClusterRole
    roles := getRolesForUser(user)
    // 2. 检查是否有 Role 允许该 verb + resource 组合
    for _, role := range roles {
        if role.Allows(resource, verb) {
            return true
        }
    }
    // 3. 检查是否有 ClusterRoleBinding 允许
    clusterRoles := getClusterRolesForUser(user)
    for _, role := range clusterRoles {
        if role.Allows(resource, verb) {
            return true
        }
    }
    return false
}
注意: 授权阶段只做“允许/拒绝”判断,不会修改请求内容。即使授权通过,后续的准入控制链仍可能拒绝该请求。

2.4 准入控制链(Admission Control Chain)

这是整个生命周期中最复杂、也是本课程最关注的阶段。准入控制链由一系列 Admission Plugin 组成,按固定顺序执行。每个插件可以:

  • Mutating(变更):修改请求中的资源对象(如注入 Sidecar、设置默认值)。
  • Validating(校验):检查资源对象是否符合规范(如命名空间是否存在、资源配额是否超限)。

准入控制链的执行顺序为:

  1. MutatingAdmissionWebhook(外部变更 Webhook)
  2. 内置 Mutating 插件(如 NamespaceLifecycle、DefaultStorageClass)
  3. 对象模式校验(OpenAPI Schema Validation)
  4. ValidatingAdmissionWebhook(外部校验 Webhook)
  5. 内置 Validating 插件(如 ResourceQuota、PodSecurity)
存储版本漂移校准的关键位置: 本课程测试的 Webhook 通常部署在 MutatingAdmissionWebhook 阶段,因为只有变更 Webhook 可以在对象持久化之前修改其字段,从而校准因存储版本升级导致的字段漂移。

2.5 持久化至 etcd

准入控制链全部通过后,API Server 将最终资源对象序列化为 Protobuf 格式(默认)或 JSON 格式,通过 gRPC 接口写入 etcd。etcd 以 /registry/<resource>/<namespace>/<name> 的 Key 结构存储。

# etcd 中存储的 Deployment 对象示例路径
/registry/deployments/default/nginx-deployment

写入 etcd 后,API Server 返回 HTTP 201 Created 给客户端,整个请求生命周期结束。

2.6 完整路径 SVG 架构图

下图展示了从 kubectl 到 etcd 的完整请求路径,并突出标注了准入控制 Webhook 的拦截位置:

Kubernetes API 请求生命周期架构图 Kubernetes API 请求生命周期:从 kubectl 到 etcd kubectl / 客户端 认证 (Authn) 授权 (Authz) 准入控制链 MutatingWebhook 内置 Mutating 插件 Schema 校验 ValidatingWebhook etcd 持久化 📌 准入控制 Webhook 拦截位置说明: • MutatingWebhook 在对象持久化之前执行,可修改资源字段,是校准存储版本漂移的最佳拦截点。 • ValidatingWebhook 只能校验不能修改,用于拒绝不符合策略的请求。

2.7 各阶段数据流与关键字段

请求在生命周期各阶段传递的核心数据结构如下表所示,理解这些字段有助于编写精准的 Webhook 拦截逻辑:

阶段 传递的数据结构 关键字段
认证后 UserInfo username, groups, uid, extra
授权后 Attributes user, verb, resource, namespace, subresource
准入控制链 AdmissionRequest object, oldObject, operation, dryRun, options
持久化 runtime.Object (Protobuf) 最终资源对象的完整序列化表示
测试要点: 在编写 Webhook 接口测试时,应重点构造 AdmissionRequest 中的 object 和 oldObject 字段,模拟存储版本漂移场景(如字段类型变更、默认值缺失、枚举值超范围)。

2.8 请求生命周期中的关键时序

以下时序图展示了请求在 API Server 内部各模块间的调用顺序,以及 Webhook 的精确触发时机:

API 请求时序图 API 请求时序:Webhook 触发时机 kubectl API Server MutatingWebhook ValidatingWebhook etcd POST /api/v1/namespaces/default/pods AdmissionReview (Mutating) Patch 响应 (JSON Patch) AdmissionReview (Validating) Allowed: true PUT /v3/kv/put (Protobuf) 201 Created HTTP 201 Created MutatingWebhook 在对象持久化之前执行,可修改字段;ValidatingWebhook 在 Schema 校验之后执行,只能拒绝不能修改。

2.9 本章小结

  • Kubernetes API 请求生命周期包含 认证 → 授权 → 准入控制链 → 持久化 四个核心阶段。
  • 准入控制链是唯一可以 修改请求对象 的阶段,也是 Webhook 的部署位置。
  • MutatingWebhook 在 对象 Schema 校验之前 执行,适合修复存储版本漂移导致的字段异常。
  • ValidatingWebhook 在 Schema 校验之后 执行,用于强制合规性检查。
  • 理解 AdmissionRequest 中的 object 和 oldObject 字段,是编写 Webhook 接口测试的基础。