前 15 篇把 kube-apiserver 生产路径拆到可归因精度:HandlerChain → Auth → Admission → storage.Interface → cacher → APF,以及 CRD/aggregation 停损线与运维升级门。「该查 apiserver 还是 etcd」若再写成「都有可能看情况」,等于把机制丢掉。
本文是终章:用机制排除树收束排障判断,回收 etcd/13 与 etcd/16 写下的 apiserver 停损线,给出 Kine 与 events 分集群的边界,列出仍开放的问题,并以 ADR 可粘贴的语言关闭本系列续作边界。不做跨方案延迟排行榜。
本篇在系列中的位置
篇目 核心内容 第 15 篇 · 排障五轴 Storage/Watch/Admission/Auth/APF 口令表 第 16 篇 · 选型收束(终章) 排除树、开放问题、边界关闭 系列目录 全部篇目
版本锚定:kube-apiserver v1.30.3(tag
v1.30.3);etcd 后端对照 etcd v3.5.33。Kine 等兼容层只写机制边界,不写安装全书。
一、机制排除树
排除树每一叶必须回答一个可证伪的机制问题,不是「看场景」。
flowchart TD
symptom{"Kubernetes control plane\nfailure symptom?"}
symptom --> axis4{"401 / 403\nall requests?"}
axis4 -->|"Yes"| auth["Axis4 Auth\napiserver/15"]
axis4 -->|"No"| axis3{"Webhook 503\nor write deny?"}
axis3 -->|"Yes"| adm["Axis3 Admission\napiserver/15"]
axis3 -->|"No"| axis5{"APF queue full?\n429 / timeout?"}
axis5 -->|"Yes"| apf["Axis5 APF\napiserver/15"]
axis5 -->|"No"| etcd_lag{"etcd_request_duration\n_seconds elevated?"}
etcd_lag -->|"Yes"| pierce["Pierce to etcd/15\nAxis1-3 (Raft/WAL/MVCC)"]
etcd_lag -->|"No"| watch_err{"410 Gone\nor Watch broken?"}
watch_err -->|"Yes, ErrCompacted"| etcd_watch["Pierce to etcd/15\nAxis4 (Watch/compaction)"]
watch_err -->|"Yes, cacher bookmark"| axis2["Axis2 Watch/cache\napiserver/15"]
watch_err -->|"No"| storage_err{"storage.Interface\nerror / rv mismatch?"}
storage_err -->|"Yes"| axis1["Axis1 Storage\napiserver/15"]
storage_err -->|"No"| both["Check both:\napiserver + etcd joint"]
| 机制判据(问句) | 若「是」 | 落点 |
|---|---|---|
| 401 / 403 全请求? | Auth 问题 | apiserver 轴 4 |
| webhook 503 / admission 慢? | Admission 问题 | apiserver 轴 3 |
| APF queue 积压 / 429? | 流控问题 | apiserver 轴 5 |
etcd_request_duration_seconds 高位? |
etcd 侧根因 | 穿透 etcd/15 轴 1–3 |
ErrCompacted / Watch 断流且 etcd compaction
激进? |
etcd Watch 问题 | 穿透 etcd/15 轴 4 |
| 410 Gone 但 etcd 健康? | cacher bookmark 落后 | apiserver 轴 2 |
| storage.Interface 报错但 etcd 健康? | codec/encrypt/prefix | apiserver 轴 1 |
| 两层均无明显信号? | 联查 | apiserver 日志 + etcd 日志对齐时间戳 |
甜区(apiserver 五轴内):Admission webhook 超时;APF FlowSchema 配置不当;cacher 未命中引发 List 穿透;consistent list 风暴;Auth 配置变更后 401;audit webhook failurePolicy Block 阻塞写入。
苦区(混因高风险):etcd 写慢 → apiserver 请求挂起 → APF seats 耗尽 → 后续请求 504。此时 etcd 轴 1–2 与 apiserver 轴 5 同时亮,需按时间戳对齐两套日志,判定哪层先劣化。
二、回收 etcd/13 的 apiserver 停损线
etcd/13 · K8s 控制面耦合 §一注明「apiserver 分层缓存 / Admission / APF 实现全书不在此展开」,并将 apiserver 五轴排障指向本系列。本篇正式回收该停损线。
| etcd/13 原内容 | 本系列回收位置 | 关闭状态 |
|---|---|---|
| apiserver 唯一直连 etcd | 第 3 篇 storage.Interface | 已展开 |
| resourceVersion ↔︎ mod revision | 第 4 篇 | 已展开 |
| apiserver watch cache 概览 | 第 5 篇 | 已展开 |
| 504 归因「etcd 轴 vs apiserver 轴」 | 第 15 篇 §七;本篇排除树 | 已机制化 |
| 「apiserver 实现全书不在此展开」停损线 | 本系列 01–16 | 已覆盖 |
etcd/16 开放问题 §5.1「watch cache SLO + compaction 联合模型」已指向本系列第 5–7、15–16 篇——本篇在开放问题 §五.1 继续持有该问题,不做闭合(无实测)。
给读完 etcd 系列的读者口令: - 「etcd 五轴、Raft/WAL/MVCC/Watch/Lease」→ 仍看 etcd/ - 「apiserver 路径:storage/cacher/webhook/APF」→ 本系列 01–15 - 「该查哪层」→ 本篇排除树
三、Kine / SQL backend:Watch 语义差
Kine 是一个 etcd API 兼容层,允许用 SQLite / PostgreSQL / MySQL 替换 etcd 作为 Kubernetes 控制面存储后端(主要用于 K3s 等轻量发行版)。
3.1 Watch 语义差
etcd 的 Watch 基于 revision-ordered append-only
log(MVCC 轴),客户端从任意历史 revision
有序追赶,ErrCompacted 有明确定义。Kine 将
Watch 语义映射到 SQL
轮询或变更事件——两者在以下场景行为不同:
| 场景 | etcd v3.5.33 | Kine(工程判断) |
|---|---|---|
| 从历史 revision 追赶 | Revision 持久有序 | 依赖 SQL 实现;历史窗口可能有限 |
| ErrCompacted 语义 | 明确;客户端必须重 List | SQL 实现各异;可能 silent drop |
| Watch 背压 | gRPC stream;有明确 flow control | SQL 轮询间隔;背压语义不同 |
| Jepsen 覆盖 | etcd 有多轮 Jepsen 测试记录 | Kine 无等同 Jepsen 覆盖(工程判断;保持开放) |
3.2 选型边界
- K3s / 边缘 / 单节点开发:Kine + SQLite 是合理权衡(减少运维复杂度 vs Watch 语义差)。
- 生产多节点 Kubernetes:etcd 原生栈仍是主流;Kine 引入的 Watch 语义差在大规模 informer 负载下风险未被系统性测试(工程判断)。
本系列立场:不写 Kine 全书;不做 Kine vs etcd 延迟排名(无实测)。Kine Watch 语义差是开放问题(见 §五.二),不在此给出「可用」或「不可用」结论。
四、events
--etcd-servers-overrides 分集群
4.1 为什么分集群
Kubernetes Events
资源(events.k8s.io/v1)写入频率高,TTL
短(默认 1 小时)。与 Pod/Deployment 等核心资源共用同一 etcd
集群时,Events 的大量 churn 会:
- 加速 etcd MVCC revision 增长,提高 compaction 频率;
- 占用 etcd quota(backend db size);
- 在 Watch 轴引发更频繁的 ErrCompacted 风险(对依赖稳定 revision 窗口的 informer)。
通过 --etcd-servers-overrides 把 Events
路由到独立 etcd 集群,核心资源的 compaction 压力与 Events
churn 物理隔离。
4.2 运维要点
| 方面 | 说明 |
|---|---|
| 独立 etcd quota | Events etcd 可配置更激进的 compaction retention |
| 备份策略 | Events etcd 通常不需要与核心 etcd 同等严格的 snapshot 策略(数据可重建) |
| 升级 | 独立升级窗口;须与核心 etcd 版本保持兼容 |
| 排障分列 | Events 丢失 → 先查 Events etcd;核心资源排障不受 Events etcd 影响 |
标准配置形式(语义;实际 flag 见 第 14 篇 §二.二):
--etcd-servers-overrides=/events#<events-etcd-endpoint-list>
注意:/events 路径前缀匹配的是 apiserver 在
etcd 中的 key 前缀规则,具体以 v1.30.3 源码
pkg/kubeapiserver/ 中
--etcd-servers-overrides 解析逻辑为准——不同 K8s
版本的资源→前缀映射可能有变化,配置前须核对。
五、开放问题
关闭条件必须是测量、Jepsen 类验证或正式文档/源码变更,不是路线图口号。
5.1 watch cache SLO 与 compaction 联合模型
问题:apiserver watch cache 作为 etcd Watch 的缓冲层,其命中率 SLO 与 etcd compaction retention 如何定量关联?cacher bookmark 推进速度与 etcd compaction 窗口之间的 trade-off 缺乏公开的 formal 模型。
为何重要:List 风暴(轴 2)的根因往往是
cacher miss 率突增 + consistent list 穿透 etcd——能否用
apiserver_longrunning_requests +
etcd_request_duration_seconds + compaction
retention 三参数建立预警模型,是 SLO 工程化的关键。
检验:需在受控集群下测量不同 compaction retention 与对象规模组合时的 cacher miss 率与 apiserver → etcd list 频率——本站无同构 peer-reviewed 数字,保持开放。
入口:apiserver watch cache
实现(staging/src/k8s.io/apiserver/pkg/storage/cacher/,v1.30.3);etcd/16
§5.1 etcd 侧联合调参。
5.2 线性读期望:通过 apiserver 与直连 etcd ReadIndex 的差异
问题:K8s 文档要求通过 apiserver 读到的资源「足够新」,但不保证对每次读都是线性一致;etcd ReadIndex 提供每请求的线性一致读。两者在存在 apiserver cacher 时的实际一致性级别对应关系没有 formal spec。
为何重要:控制器逻辑依赖「读到最新状态」的假设——若 cacher 滞后,reconcile 会基于旧状态写入,导致短暂 oscillation。这是工程已知的 Watch 轴开放问题,但尚无被广泛引用的 formal model(etcd ReadIndex 见 etcd/08;apiserver 侧边界见第 4–5 篇)。
检验:构造 leader election + fast update 场景,测量 apiserver read 与 etcd direct read 的 rev 差——本站无同构实测,保持开放。
5.3 Lease + fencing 全链路 formal spec
问题:etcd/16 §5.2 已钉 Jepsen 证明 Lease 锁在部分故障下不安全;K8s Node Lease + controller 依赖 Lease 过期的全链路(apiserver → etcd → Node NotReady → 驱逐)的 formal spec 仍缺。apiserver 在此链路中的角色:写 Lease 对象(Storage 轴)、Watch Lease 变更(Watch 轴)——但其与 kubelet KeepAlive 的时序关系无官方 formal 模型。
为何重要:轴 1 + 轴 5 联动故障(etcd Leader 切换 + Lease 集体过期)是 K8s 大集群高影响事故的常见模式。
现状:distributed/53 已钉 KV/Txn vs Lease 边界;K8s 全链路 formal spec 仍开放。
给维护者:以上三个开放问题关闭依赖实测或上游正式文档,不应以路线图口号关闭。
六、边界关闭
| 题目 | 归属 | 关闭状态 |
|---|---|---|
| etcd Raft/WAL/MVCC/Watch/Lease 全书 | etcd/ 01–16 | 外链;本系列不重写 |
| apiserver→etcd K8s 耦合边界 | etcd/13 + 本系列 | 回收完毕 |
| storage.Interface + cacher + APF + Auth + Admission | 本系列 01–15 | 已覆盖 |
| CRD codegen / controller-runtime 全书 | 停损线外 | 明确划界 |
| scheduler / controller-manager / kubelet 内核 | 停损线外 | 明确划界 |
| Kine SQL backend 全书 | 边界 | 未关闭(§三一句指针) |
| Jepsen K8s 全链路 spec | distributed/53 + §五.三 | 未关闭(开放问题) |
| §五.一–五.三 开放项 | 上文 | 未关闭 |
| 未实测跨组件延迟排行榜 | — | 禁止 |
给读完本系列的人三条收束(ADR 友好)
排除树进 ADR:写清「504 卡在 APF 轴还是 etcd 轴」;附否证条件(etcd_request_duration_seconds baseline、APF queue 水位、Admission webhook p99)。示例句:
「若 etcd_request_duration_seconds p99 在 baseline 内但 APF 队列积压,则 504 根因在 apiserver 流控而非 etcd;禁止以『etcd 压力』为由绕过 APF FlowSchema 调优。」若故障定位到 apiserver 轴:第 15 篇五轴进 on-call runbook;第 12 篇 APF FlowSchema 进变更窗;第 9 篇 webhook failurePolicy 进 incident checklist;第 14 篇 graceful shutdown 进滚动升级 SOP。
若故障穿透到 etcd 轴:按 etcd/15 五轴处理;回来用本篇排除树确认 apiserver 层已无残留故障;两轴同时亮时以时间戳先劣化的轴为根因。
终章立场:kube-apiserver
值得写成独立系列,是因为失败可命名——401(AuthN)、403(AuthZ)、503/timeout(Admission
webhook)、504/429(APF)、410 Gone(cacher
bookmark)、etcd request failed(Storage
轴)。选型若离开这些名字,讨论退回「apiserver 是 etcd
的代理」。
参考资料
规范 / 官方文档(A)
核心论文
- Ongaro, D., & Ousterhout, J. (2014). In Search of an Understandable Consensus Algorithm. USENIX ATC.
- Li, X., et al. (2017). etcd: A Distributed Key-Value Store for Inspiring Reliable Distributed Systems. USENIX ;login:.
站内对照
实验台账
- 本篇无跨组件 benchmark;排除树依据为机制分析。开放问题关闭依赖测量或上游变更,不在此伪造时间线。
上一篇:排障五轴
下一篇:系列目录
读完这篇,下一步读什么
优先读同系列或同问题的下一篇,把单篇消费变成主题集群。
【kube-apiserver】控制面全景:缺口、五轴坐标系与 16 篇路线
相对 etcd/13、distributed/50、k8s-network 补齐 kube-apiserver 生产内核缺口;以 Storage/Watch/Admission/Auth/APF 五轴为坐标系定义 16 篇阅读路线;版本锚定 Kubernetes v1.30.3。
【kube-apiserver】resourceVersion 与 Revision 映射:mod revision、continue 与一致性读期望
钉 Kubernetes resourceVersion 字段与 etcd mod revision 的对应关系;分析 continue token 的分页语义与成本;说明不同 List 路径的一致性期望差异;以及 410 Gone 与 ErrCompacted 的分列。版本锚定 Kubernetes v1.30.3 / etcd v3.5.33。
【kube-apiserver】Watch cache / cacher:dispatch、bookmark 与穿透 etcd
钉 Kubernetes v1.30.3 cacher 对 storage.Interface 的包装:watchCache 滑动窗口与 Ready 门、bookmark 推送路径、cache miss 打穿 etcd 的触发条件,以及 List 风暴成因与 watch cache SLO 与 compaction 间隔之间的开放问题。
【kube-apiserver】运维与升级:HA、flags、graceful shutdown 与 etcd 联检
kube-apiserver 高可用模式:多实例共享 etcd、无需内部 leader election;核心 flag 语义(--etcd-servers、--etcd-servers-overrides、--shutdown-delay-duration、encryption-provider-config);与 etcd/14 的联合升级检查单;Kubernetes 版本偏差策略与 etcd 矩阵指针。