2. K8s API Server 架构:组件、请求处理流程与认证授权准入机制
Kubernetes API Server(kube-apiserver)是整个控制面的核心组件,所有对集群状态的查询、变更操作都必须经过它。理解 API Server 的内部架构与请求处理流程,是构建可靠中间件错误处理逻辑的前提——因为事务边界、幂等性、重试策略都直接受制于 API Server 的认证、授权、准入与存储机制。
2.1 API Server 组件架构
API Server 采用分层设计,从网络层到存储层依次为:
| 层级 | 组件 / 模块 | 职责 |
|---|---|---|
| 网络层 | HTTP(S) Server / TLS 终结 | 接收客户端请求,验证 TLS 证书,处理连接复用 |
| 认证层 | Authenticator 链 | 从请求中提取用户身份(证书、Token、BasicAuth、OIDC 等) |
| 授权层 | Authorizer 链 | 判断用户是否有权执行请求的操作(RBAC / ABAC / Webhook) |
| 准入层 | Admission 链(Mutating + Validating) | 拦截请求,修改或校验资源对象(如 Pod 注入、配额检查) |
| 请求处理层 | API 路由 / 版本转换 / 编解码 | 将请求路由到对应资源 handler,处理 API 版本转换与序列化 |
| 存储层 | etcd 客户端 / 缓存(watch cache) | 读写持久化数据,维护 watch 机制与缓存一致性 |
关键认知:API Server 本身是无状态的,所有持久化状态存储在 etcd 中。这意味着 API Server 可以水平扩展,但 etcd 的写入顺序与事务边界决定了整个集群的一致性模型。
2.2 请求处理全流程
一个典型的写请求(如 kubectl apply -f deployment.yaml)在 API Server 内部经历以下阶段:
- TLS 握手与连接建立——客户端证书验证,双向 TLS 可选。
- 认证——按顺序尝试所有认证插件,直到某个插件返回用户信息或全部失败。
- 授权——根据用户、资源、动词(get/list/create/update/delete)进行权限判定。
- 准入控制(Mutating)——先执行变更准入插件(如 PodNodeSelector、DefaultStorageClass)。
- 对象验证与默认值填充——API Server 对资源对象进行 schema 校验并设置默认字段。
- 准入控制(Validating)——执行校验准入插件(如 PodSecurity、ResourceQuota)。
- 存储写入——将最终对象序列化为 protobuf 或 JSON,写入 etcd(带乐观锁)。
- 响应返回——返回创建/更新后的对象给客户端,同时触发 watch 通知。
2.3 认证机制
API Server 支持多种认证方式,按配置顺序依次尝试:
| 认证方式 | 身份来源 | 典型场景 |
|---|---|---|
| X.509 客户端证书 | TLS 握手时提供的证书 CN / O | kubelet、kube-controller-manager 组件间通信 |
| 静态 Token 文件 | --token-auth-file 指定的 CSV 文件 |
测试环境或遗留系统 |
| ServiceAccount Token | Pod 挂载的 JWT Token(自动轮换) | Pod 内应用访问 API Server |
| OpenID Connect (OIDC) | 外部身份提供商(如 Dex、Keycloak) | 企业 SSO 集成 |
| Webhook Token 认证 | 外部认证服务返回的 UserInfo | 自定义认证逻辑 |
错误处理关注点:认证失败返回 401,客户端应检查响应头
WWW-Authenticate 以确定认证类型。对于 ServiceAccount Token,需注意 Token 过期与轮换导致的间歇性 401 错误。
2.4 授权机制
Kubernetes 默认使用 RBAC(Role-Based Access Control),授权决策基于:
- 用户 / 组 / ServiceAccount——认证阶段提取的身份
- 资源——如 pods、deployments、nodes
- 动词——get、list、create、update、patch、delete、watch
- 命名空间——集群作用域或命名空间作用域
授权链支持同时配置多个 Authorizer(如 RBAC + Webhook),按顺序执行,任一授权器返回 Allow 则通过,全部 Deny 则返回 403。
2.5 准入控制机制
准入控制是 API Server 请求处理中最关键的扩展点,也是中间件错误处理最容易出问题的环节。准入插件分为两类:
| 类型 | 执行顺序 | 能力 | 示例插件 |
|---|---|---|---|
| MutatingAdmissionWebhook | 先执行 | 修改请求对象(注入 sidecar、设置默认值) | Istio sidecar injector、PodNodeSelector |
| ValidatingAdmissionWebhook | 后执行 | 校验请求对象(拒绝不符合策略的请求) | PodSecurity、ResourceQuota、自定义策略引擎 |
事务边界影响:准入 Webhook 的超时(默认 30 秒)会导致整个 API 请求失败。如果中间件在 Mutating Webhook 中修改了对象但后续 Validating Webhook 拒绝,API Server 不会回滚已发生的副作用——因为 Webhook 调用是外部 HTTP 请求,API Server 无法感知外部系统的状态变更。这是设计事务补偿逻辑时必须考虑的关键点。
2.6 关键设计原则
- 无状态与水平扩展——API Server 实例之间不共享本地状态,所有状态在 etcd 中。这意味着中间件不能假设请求被同一实例处理。
- 乐观并发控制——etcd 写入依赖
resourceVersion,冲突时返回 409。中间件应实现重试逻辑,并注意指数退避。 - Watch 机制的一致性——API Server 保证 watch 事件的顺序与 etcd 写入顺序一致,但不保证客户端不丢失事件(断连重连后需重新 list + watch)。
- 准入 Webhook 的失败策略——
failurePolicy可设为Fail(默认)或Ignore。中间件应明确评估 Webhook 不可用时的集群行为。
实践建议:在构建中间件错误处理逻辑时,始终假设 API Server 可能在任何阶段返回错误(401、403、409、422、500、503)。将每个 API 调用视为一个可能部分执行的事务,并设计对应的重试、回滚或补偿策略。