【etcd】Kubernetes 控制面耦合:apiserver、resourceVersion 与 Node Lease
内容提要
本文讨论Kubernetes控制面与etcd的耦合关系。kube-apiserver是唯一直接连接etcd的组件,通过watch cache合并客户端请求。resourceVersion对应etcd的mod revision,用于乐观并发控制。Node Lease通过etcd Lease机制实现心跳,减少写入放大。排障时需区分apiserver超时与etcd五轴问题,避免误判。
延伸解读
排障先分轴:apiserver 超时 ≠ etcd 故障
文章强调,apiserver 返回 504 时,不能直接归因于 etcd 故障。应先通过 apiserver 的 etcd_request_duration_seconds 指标判断是否穿透到 etcd。若指标正常,问题可能在 apiserver 的准入、缓存或序列化;若指标异常,再进一步定位到 Raft、MVCC、Watch 或 Lease 轴。避免将 Watch 背压误判为 Raft 选举问题。
resourceVersion 的语义边界
resourceVersion 对应 etcd 的 mod revision,用于同一对象的乐观并发控制,而非全局逻辑时钟。跨对象比较 resourceVersion 大小没有线性一致语义。当 controller 保存的 resourceVersion 因 compaction 被清除时,会收到 ErrCompacted,只能全量 List 重建缓存,这属于 Watch 轴问题,而非 Raft 问题。
Node Lease 与 etcd 写入放大
Kubernetes 1.14+ 使用 Lease 实现节点心跳,减少频繁更新 Node.status 带来的写入放大。每个节点对应一个 Lease 对象,持续续约形成写入 QPS 底噪。排障 NotReady 漂移时,应检查 Lease 轴(Lease 是否存在、TTL)和网络,而非默认归因于 Raft 无 Leader。etcd 3.4+ 的 checkpoint 机制可缓解 Leader 切换后的 TTL 重置。
Events 分片与备份注意
Kubernetes 1.22+ 支持通过 --etcd-servers-overrides 将 Events 路由到独立 etcd 集群,以减轻主 etcd 的写入压力。分片后,备份需分别对每个后端进行 snapshot,不能只备份主 etcd。这属于运维层面的重要考量,避免因 Events 高写入导致主 etcd 的 MVCC/quota 轴压力过大。
Q&A
在Kubernetes中,哪个组件是唯一直接连接etcd的?
kube-apiserver是唯一直接连接etcd的控制面组件,其他组件如scheduler、controller-manager、kubelet和kubectl都通过kube-apiserver的REST API访问etcd。
Kubernetes中的resourceVersion与etcd的Revision有什么关系?
resourceVersion对应etcd中对象的mod revision,即该key最后一次变更时的全局Revision。它用于乐观并发控制和Watch起点,但跨对象比较resourceVersion大小没有线性一致语义。
apiserver的watch cache如何影响etcd的负载?
apiserver的watch cache按资源类型合并多个客户端的Watch请求,并允许List请求走缓存,从而减少对etcd的直接访问,降低etcd的Watch连接数和读负载。
Kubernetes中Node Lease是如何通过etcd Lease机制实现心跳的?
从Kubernetes 1.14起,节点心跳默认通过coordination.k8s.io/v1 Lease实现。kubelet周期性续约Lease,在etcd层每个Node Lease对应一个Lease对象(走Lease轴)和一个绑定Lease ID的Lease key(走MVCC写入路径)。Lease过期后节点被标记为NotReady。
当kube-apiserver返回504 Gateway Timeout时,如何区分是etcd问题还是apiserver问题?
应首先检查apiserver的etcd_request_duration_seconds指标,判断etcd请求是否慢。如果etcd请求不慢,则问题可能在apiserver的准入、缓存或认证;如果etcd请求慢,则需进一步定位etcd五轴(Raft、WAL、MVCC、Watch、Lease)中的具体问题。
etcd的compaction保留窗口与controller断连时长如何影响Kubernetes的catch-up成本?
如果controller保存的resourceVersion已被auto-compaction清除,Watch无法从历史rev追赶,只能全量List重建本地缓存。因此,compaction保留窗口与controller断连时长共同决定catch-up成本,这是Watch轴问题,不是Raft选举问题。