土法炼钢 · 系统与基础设施

【kube-apiserver】选型收束与开放问题:排除树、Kine 与 events 分集群

文章导航

分类入口
kubernetesdistributed
标签入口
#kubernetes#apiserver#selection#open-questions#kine#events#exclusion-tree#watch-cache#etcd#v1.30.3

目录

前 15 篇把 kube-apiserver 生产路径拆到可归因精度:HandlerChain → Auth → Admission → storage.Interface → cacher → APF,以及 CRD/aggregation 停损线与运维升级门。「该查 apiserver 还是 etcd」若再写成「都有可能看情况」,等于把机制丢掉。

本文是终章:用机制排除树收束排障判断,回收 etcd/13etcd/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 选型边界

本系列立场:不写 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-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 友好)

  1. 排除树进 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 调优。」

  2. 若故障定位到 apiserver 轴:第 15 篇五轴进 on-call runbook;第 12 篇 APF FlowSchema 进变更窗;第 9 篇 webhook failurePolicy 进 incident checklist;第 14 篇 graceful shutdown 进滚动升级 SOP。

  3. 若故障穿透到 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)

核心论文

  1. Ongaro, D., & Ousterhout, J. (2014). In Search of an Understandable Consensus Algorithm. USENIX ATC.
  2. Li, X., et al. (2017). etcd: A Distributed Key-Value Store for Inspiring Reliable Distributed Systems. USENIX ;login:.

站内对照

实验台账


上一篇排障五轴

下一篇系列目录

读完这篇,下一步读什么

优先读同系列或同问题的下一篇,把单篇消费变成主题集群。

2026-08-28 · kubernetes / distributed

【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 矩阵指针。


By .