kube-apiserver 处理
GET /apis/example.com/v1/foos 与处理
GET /api/v1/pods
的路径不一样长。前者可能被转发到集群外的
Extension Server,也可能在 apiserver 内部走 CRD 转换
webhook;后者则全程在 apiserver 进程里落
storage.Interface。两条扩展路径的失败模式、排障锚点与影响半径都不同,但故障现象却可能同样表现为
503 或超时。
本文是第 13 篇,专门钉这两条扩展路径的机制边界与失败模式,并写明停损线:哪些属于本系列范围,哪些属于 scheduler/controller/kubelet 或 CRD codegen 领域。
本篇在系列中的位置
篇目 核心内容 第 12 篇 · APF 与 max-in-flight 公平排队、504 与 etcd lag 分列 第 13 篇 · 扩展边界 CRD v1 存储路径、APIService 转发、停损线 第 14 篇 · 运维与升级 HA、flags、graceful shutdown、etcd 联检 系列目录 全部篇目
版本锚定:Kubernetes v1.30.3(源码 tag
v1.30.3)。etcd 后端对照 etcd v3.5.33。CRD v1 GA 状态以 v1.30.3 为准,不以/docs/live 版本冒充。
一、两条扩展路径
Kubernetes 扩展 API 分两类,内部路由完全不同:
flowchart TD
client["kubectl / client"]
apiserver["kube-apiserver"]
crd["CRD handler\n(internal)"]
etcd["etcd"]
conv["conversion webhook\n(optional)"]
agg["aggregation handler"]
ext["Extension API Server"]
client --> apiserver
apiserver -->|"/apis/example.com/v1/* (CRD)"| crd
crd -->|"storage.Interface"| etcd
crd -->|"hub version conversion"| conv
apiserver -->|"/apis/metrics.k8s.io/*"| agg
agg -->|"proxy"| ext
| 扩展类型 | 定义对象 | 请求落点 | 持久化 | 失败模式 |
|---|---|---|---|---|
| CRD v1 | CustomResourceDefinition 资源(存
etcd) |
apiserver 内部 CRD handler | etcd(与内置资源同后端) | conversion webhook 慢/503;schema 验证 |
| Aggregated API | APIService 资源(存 etcd) |
apiserver 转发 → Extension Server | Extension Server 自管 | Extension Server 不可用 → 503 |
两条路径共同点:定义对象(CustomResourceDefinition、APIService)自身都存在
etcd 里,其变更通过 apiserver Storage
轴落地。区别在于读写 CR/AA 资源时请求是否离开
apiserver 进程。
二、CRD v1:存储路径
2.1 CustomResourceDefinition 本身的存储
CustomResourceDefinition 是内置 API
资源,存储路径形如
/registry/apiextensions.k8s.io/customresourcedefinitions/<name>,走标准
storage.Interface + etcd3 store(Storage
轴)。CRD 变更由
apiextensions-apiserver(嵌套在 kube-apiserver
进程内,实现为 generic apiserver 委托链的一部分)处理。
当 CRD 定义落 etcd 后,kube-apiserver 动态注册该 GVR
路由(GroupVersionResource)。此后对 CR
对象的读写请求走同一个 etcd 后端。
2.2 CR 对象的存储 key
以 CRD 定义的
group=example.com、version=v1、plural=foos
为例,etcd key 形如:
/registry/example.com/foos/<namespace>/<name>
存储格式默认为 protobuf(如果 CRD 定义的 scheme 支持)或 JSON;encryption provider 配置会对这条路径生效(与内置资源统一)。
2.3 多版本与 conversion webhook
CRD
支持多存储版本(spec.versions[].storage: true)。当
CR 以旧版本存入 etcd、客户端请求新版本时,apiserver 调用
conversion
webhook(spec.conversion.strategy: Webhook)做版本转换。
失败模式:
| 场景 | 表象 | 轴 |
|---|---|---|
| conversion webhook 不可达 | GET/Watch CR 返回 500 或
503 |
Admission(webhook 子分类) |
conversion webhook 慢(超过
webhooks[].timeoutSeconds) |
请求超时;apiserver_request_duration_seconds
增大 |
Admission/Storage 轴边界 |
| 存储版本与 hub 版本不匹配 | 批量 migrate 时数据转换失败 | Storage 轴 |
| CRD 定义被删除(CR 仍存 etcd) | GVR 路由消失;客户端 404 | — |
conversion webhook 超时不等于 etcd 慢——排障时先查 webhook
端到端延迟,再查
etcd_request_duration_seconds。两者联动见第 15
篇。
2.4 CRD 验证 webhook(ValidatingAdmissionWebhook/MutatingAdmissionWebhook)
CRD 资源与内置资源一样走 Admission 链。自定义资源的 CEL
验证(spec.validation.openAPIV3Schema.x-kubernetes-validations,v1.25+
GA)在 apiserver 进程内执行,不需要 webhook roundtrip。外部
Validating/Mutating webhook 规则匹配 CRD GVR
时,失败模式与第 9 篇一致。
三、Aggregated API:请求离开 apiserver
3.1 APIService 对象
APIService
资源(apiregistration.k8s.io/v1)指定哪些
group/version 由外部 Extension API Server
处理。典型例子:
metrics-server(metrics.k8s.io/v1beta1)- 自定义 extension apiserver(custom admission 或 custom storage)
APIService 对象本身存 etcd,通过
kube-aggregator(嵌入
kube-apiserver)管理。
3.2 请求转发路径
sequenceDiagram
participant Client
participant kube-apiserver (aggregation handler)
participant Extension Server
Client->>kube-apiserver (aggregation handler): GET /apis/metrics.k8s.io/v1beta1/nodes
kube-apiserver (aggregation handler)->>Extension Server: proxy HTTP request (mTLS)
Extension Server-->>kube-apiserver (aggregation handler): response
kube-apiserver (aggregation handler)-->>Client: response
关键点:请求经 apiserver 认证/授权后,聚合层将原始请求(含 Authorization header 中的 impersonation 信息)代理到 Extension Server。Extension Server 自己管理存储——可以是独立 etcd、内存,也可以是任意后端。
3.3 失败模式
| 场景 | 表象 | 排障起点 |
|---|---|---|
| Extension Server 未运行 | APIService 状态
Available=False;请求 503 |
kubectl get apiservice;检查 Extension
Server Pod |
| Extension Server 响应慢 | 客户端超时;kube-apiserver 聚合超时(默认 60s) | Extension Server 自身日志;kube-apiserver audit log |
| Extension Server 证书过期 | mTLS 握手失败;503 | APIService 状态、证书有效期 |
| Extension Server 内 etcd 不可达 | 请求读写失败;语义由 Extension Server 决定 | Extension Server 日志;其后端 etcd(独立排障链) |
与 CRD 分列:CRD 失败时 kube-apiserver 进程内有确定的 Storage/Admission 报错;Aggregated API 失败时 kube-apiserver 只是代理,错误来自下游——不要把 Extension Server 不可用误判为 kube-apiserver etcd 连接问题。
四、停损线:不在本系列的三块
4.1 CRD codegen 与 controller-runtime 全书
CRD 开发侧:controller-gen 生成
deepcopy/CRD
YAML、controller-runtime Reconcile
框架、informer/cache
配置——这些是客户端库与开发者工具,不是
kube-apiserver 内核。本系列停在「CR 如何存 etcd、conversion
webhook 如何在 apiserver 侧失败」;CRD 开发全书见官方
controller-runtime 文档与 Kubebuilder book。
4.2 scheduler / controller-manager 内核
kube-scheduler 与
kube-controller-manager 是 apiserver
的客户端:通过 informer
监听资源变化,不持有 etcd
连接。它们的控制循环失败(reconcile 慢、queue
积压)属于控制面逻辑层,不是 apiserver
Storage/Watch/APF 五轴。排障时若发现 controller
停更,应先确认 apiserver Watch 轴是否正常,再进入 controller
日志分析。
4.3 kubelet 数据面
kubelet 运行在每个 Node,通过 apiserver 更新 Pod/Node
状态,但不直连 etcd。Node Lease 是 apiserver 经
storage.Interface 写 etcd 的操作(见 etcd/13
§四)。kubelet 内核(容器运行时、CNI
调用、设备插件)不在本系列范围;数据面见 k8s-network/。
五、边界汇总
| 问题 | 本系列范围 | 停损线外 |
|---|---|---|
| CRD 对象存 etcd 路径 | 是(Storage 轴) | — |
| CRD conversion webhook 超时 | 是(Admission/Storage 轴) | — |
| APIService 代理失败 503 | 是(聚合层) | Extension Server 后端细节 |
CRD codegen、controller-runtime |
否 | kubebuilder book |
| scheduler reconcile 逻辑 | 否 | kube-scheduler 内核 |
| kubelet 容器运行时 | 否 | k8s-network/ |
排障分列:CRD conversion webhook 慢 → 第 15 篇 Admission 轴;Extension Server 不可达 → 聚合层 503,不走 etcd 五轴;存储层写入 CRD CR → Storage 轴(与内置资源一致)。
参考资料
规范 / 官方文档(A)
- Kubernetes v1.30 · Custom Resource Definitions
- Kubernetes v1.30 · Extend the Kubernetes API with the aggregation layer
- Kubernetes v1.30 · Versions in CustomResourceDefinitions
源码(A)
kubernetes/kubernetestagv1.30.3:staging/src/k8s.io/apiextensions-apiserver/;staging/src/k8s.io/kube-aggregator/
站内
- 第 3 篇 · storage.Interface 与 etcd3
- 第 9 篇 · Mutating/Validating Webhook
- 第 12 篇 · APF 与 max-in-flight
- 第 15 篇 · 排障五轴
- etcd/13 · K8s 控制面耦合
实验台账
- CRD/APIService 行为:未在本环境执行;失败模式来自官方文档与源码路径分析。
下一篇:运维与升级
读完这篇,下一步读什么
优先读同系列或同问题的下一篇,把单篇消费变成主题集群。
【kube-apiserver】Admission 链概览:内置插件顺序与 webhook 边界
钉 Kubernetes v1.30.3 Admission 链的阶段位置、Mutating 与 Validating 两阶段顺序、内置插件注册路径与典型示例、webhook 边界与 timeout 语义,以及 fail-open vs fail-closed 的工程争议。
【kube-apiserver】Mutating / Validating Webhook:timeout、failurePolicy 与可用性门
钉 K8s v1.30.3 的 MutatingWebhookConfiguration / ValidatingWebhookConfiguration v1:timeoutSeconds、failurePolicy、sideEffects、reinvocationPolicy 字段语义;webhook 慢如何表现为写路径延迟而非 etcd lag;生产可用性门选取;CEL ValidatingAdmissionPolicy 作为内置替代路径;排障证据包。
【kube-apiserver】控制面全景:缺口、五轴坐标系与 16 篇路线
相对 etcd/13、distributed/50、k8s-network 补齐 kube-apiserver 生产内核缺口;以 Storage/Watch/Admission/Auth/APF 五轴为坐标系定义 16 篇阅读路线;版本锚定 Kubernetes v1.30.3。
【kube-apiserver】进程与请求路径:generic apiserver、HandlerChain 与 REST 路由
拆解 kube-apiserver 进程模型与 generic apiserver 框架;钉 HandlerChain 各插槽顺序与失败落点;说明 GVR 路由机制与请求在到达 storage 前可能被拦截的位置。版本锚定 Kubernetes v1.30.3。