etcd 3.7 放出 RangeStream,Kubernetes 升级先查存量接口

etcd 3.7 的变化挺像一次控制面体检。RangeStream 让大范围读取可以分块返回,keys-only 查询少碰后端存储,租约路径和 watch 指标也补了不少细节。听起来都是好消息,真放到 Kubernetes 集群里,升级前还是要把旧接口和旧镜像用法摸一遍。

大范围读取终于少占内存

etcd 3.6 及更早版本处理大结果集时,会先把结果攒起来再返回。调用方查一个很大的前缀,服务端和客户端都可能被内存占用拖住。RangeStream 的思路更朴素,按块往外发,调用方边收边处理,延迟和内存曲线都更容易预估。

这对 Kubernetes 控制面很实用。控制器、审计工具、备份脚本、巡检程序经常会扫一段 key 空间。以前一条范围查询卡住,监控里只能看到 etcd 抖了一下。分块读取不能替代限流和分页设计,但至少把单次请求的峰值压低了。

keys-only 优化适合巡检类任务

很多脚本只想知道有哪些 key,并不关心 value。etcd 3.7 对 keys-only Range 做了优化,常规情况下只读内存索引,不再把所有序列化 value 从 bbolt 里拖出来。对于命名空间扫描、对象数量统计、异常前缀排查,这个差别很直接。

优易云做集群巡检时,会把这类任务拆开。先用 keys-only 拿范围和数量,再对少量目标做精读。全量拿 value 再过滤,写起来省事,跑到生产环境就容易把控制面拖慢。etcd 这次把底层成本降下来,但调用方也要改掉粗放习惯。

v2 旧包清理会撞到老客户端

这次升级真正要紧的地方在兼容性。etcd 3.7 移除了 v2 discovery、v2 request 和 v2 client 相关组件,服务启动也转向 v3store。官方提醒,没有先更新到较新的 3.6 补丁版本,可能会遇到升级阻塞。

集群管理员不要只看 kubeadm 或托管平台说明。自研控制器、备份工具、灾备脚本、老监控插件、离线恢复工具,都可能直接依赖 etcd Go 模块或旧命令行为。升级前把依赖树扫出来,比维护窗口里临时找人要靠谱得多。

镜像标签也要查一遍

etcd 3.7 的官方容器镜像只提供多架构镜像,不再提供按架构拆开的标签。大多数标准部署不会受影响,但一些企业内网镜像仓库会把上游镜像拆开缓存,或者在脚本里写死架构标签。这里很容易踩空。

运维团队可以先在测试仓库拉取同一 tag,确认 amd64、arm64 节点都能解析到正确镜像。边缘节点、离线环境和私有云交付项目更要查。镜像问题看着小,一旦 kubelet 拉不到镜像,维护窗口就会被这种小事耗掉。

滚动升级别省健康检查

etcd 升级还是老规矩,一个成员一个成员滚。每换一个节点,确认 endpoint health、leader、raft index、db size、watch 延迟和磁盘写入,再动下一台。快不得。

我更建议把升级前后的指标截图留下。CPU、内存、backend commit 延迟、fsync 延迟、lease 续租延迟、watch 事件发送耗时,都要看。etcd 3.7 增加了 watch send-loop 相关指标,正好可以补上以前看不清的 watch 路径。

优易云的落地建议

生产集群准备上 etcd 3.7,可以先做一张很普通的检查表。列出 etcd 客户端版本、是否使用 v2 API、是否依赖 grpc WithBlock、镜像仓库同步方式、备份和恢复命令、维护窗口回滚方案。

升级后再改调用方式。把大范围读取改成 RangeStream,把只查 key 的巡检改成 keys-only,把 watch 指标接进监控告警。别指望一次升级顺手解决所有问题,先把控制面稳住,再慢慢把收益吃回来。