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 | 存储最终资源对象 | 否 |
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(校验):检查资源对象是否符合规范(如命名空间是否存在、资源配额是否超限)。
准入控制链的执行顺序为:
- MutatingAdmissionWebhook(外部变更 Webhook)
- 内置 Mutating 插件(如 NamespaceLifecycle、DefaultStorageClass)
- 对象模式校验(OpenAPI Schema Validation)
- ValidatingAdmissionWebhook(外部校验 Webhook)
- 内置 Validating 插件(如 ResourceQuota、PodSecurity)
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 的拦截位置:
2.7 各阶段数据流与关键字段
请求在生命周期各阶段传递的核心数据结构如下表所示,理解这些字段有助于编写精准的 Webhook 拦截逻辑:
| 阶段 | 传递的数据结构 | 关键字段 |
|---|---|---|
| 认证后 | UserInfo |
username, groups, uid, extra |
| 授权后 | Attributes |
user, verb, resource, namespace, subresource |
| 准入控制链 | AdmissionRequest |
object, oldObject, operation, dryRun, options |
| 持久化 | runtime.Object (Protobuf) |
最终资源对象的完整序列化表示 |
AdmissionRequest 中的 object 和 oldObject 字段,模拟存储版本漂移场景(如字段类型变更、默认值缺失、枚举值超范围)。
2.8 请求生命周期中的关键时序
以下时序图展示了请求在 API Server 内部各模块间的调用顺序,以及 Webhook 的精确触发时机:
2.9 本章小结
- Kubernetes API 请求生命周期包含 认证 → 授权 → 准入控制链 → 持久化 四个核心阶段。
- 准入控制链是唯一可以 修改请求对象 的阶段,也是 Webhook 的部署位置。
- MutatingWebhook 在 对象 Schema 校验之前 执行,适合修复存储版本漂移导致的字段异常。
- ValidatingWebhook 在 Schema 校验之后 执行,用于强制合规性检查。
- 理解
AdmissionRequest中的object和oldObject字段,是编写 Webhook 接口测试的基础。