etcd 读写压力并不直接由集群规模决定,真正决定压力的是规模增长带来的“动作频率”节点越多、工作负载越复杂,控制器、调度器、客户端对 etcd 的读写请求就越密集,这才是需要你关注的本质问题。
etcd 读写压力与集群规模:什么关系
三年前我维护过一个 80 节点的 Kubernetes 集群,工作负载不到 500 个,etcd 的 P99 延迟常年稳定在 3ms 以内,后来公司做大规模扩容,节点数翻到 200,工作负载涨到 2000 多,结果 etcd 的慢请求量直接翻了几倍,当时第一反应是“集群大了,自然扛不住”,但细看监控才发现,节点的增长只是表象,真正压垮 etcd 的是一连串由规模引发的连锁事件。
规模本身不是压力的直接来源
集群规模增大,意味着更多节点要维持心跳、更多 Pod 要调度、更多控制器要调谐,但 etcd 在物理层面感知到的,只有 API Server 转发过来的读写请求,节点数从 50 变成 200,etcd 的存储数据量确实在涨,但写入次数不会自动同步翻倍,因为 etcd 的写操作围绕的是资源对象的变更,而不是节点数量的线性伸缩。
举个例子:一个集群新增 100 个节点,最直接的影响是 100 条 Node 对象写入 etcd,加上 Lease 对象的持续续期,这本身不算大开销,但如果新增的节点上跑着数百个 Deployment,每个 Deployment 的 ReplicaSet 控制器都会持续调谐,不断读取和比较期望状态与当前状态,那 etcd 收到的读请求就会急剧增加,这中间的关键变量,是运行中的控制器数量,而不是节点数量。
哪些规模指标与 etcd 成本强相关
根据实际运维经验,以下几类规模指标和 etcd 压力关联最紧密:
| 规模指标 | 主要作用路径 | 压力体现 |
|---|---|---|
| 节点总数 | 节点心跳、Lease 续期、Node 状态广播 | 写请求平稳上升,watch 事件明显放大 |
| Pod 总数 | 资源对象存储、List 响应体大小 | 读延迟上升,etcd 内存占用随对象数量增大 |
| Deployment/StatefulSet 数量 | 控制器频繁调谐,反复 compare-and-swap | watch 事件压力剧增,穿越频率大幅提升 |
| 命名空间与 CRD 数量 | API 资源路由、多种资源类型存储 | 并发连接数升高,慢请求更容易出现 |
| 客户端数量 | 各类 Operator、Ingress Controller、自定义控制器 |
watch 连接数量上升,etcd 的 long-poll 连接数逼近上限 |
从表中能看出,规模对 etcd 压力的传导路径各不相同,有的走读路径,有的走写路径,有的则纯粹是连接数层面的消耗,单独看节点数没有意义,要综合评估整个控制面的资源配置和运行状态。
压力并非线性增长,存在临界点
行业共识认为,etcd 的读写压力与集群规模之间的关系更像一条先平缓后陡峭的曲线,规模在某一阈值以内时,压力增长平缓;一旦越过某个临界点watch 连接数接近上限,或者单次 List 请求返回的对象体积过大就会出现明显的性能拐点,大规模生产环境中的常见表现是:P99 延迟从个位数毫秒突然跳到几十毫秒,伴随少量“etcdserver: request timed out”报错。
集群规模多大时需要考虑 etcd 性能优化方案对比
这个问题没有标准答案,因为不同集群的资源对象复杂度差异巨大,有的集群 300 节点依然轻载,有的集群 50 节点就因为大量 CRD 和 Operator 把 etcd 拖垮,判断要不要做优化,先看几个数据面信号。
先看数据面信号,再谈拆分
- etcd 的 P99 延迟:持续超过 50ms,需要立刻排查,超过 500ms 意味着已经在影响业务调度。
- etcd 的慢请求数量:
etcd_request_duration_seconds_bucket中高延迟分桶的计数缓慢增长,说明问题在积聚。 - WAL fsync 耗时:
etcd_disk_wal_fsync_duration_seconds出现尖峰,说明磁盘能力开始跟不上写入频率。 - watch 连接总量:
etcd_network_client_grpc_received_bytes_total和连接数接近上限时,客户端重连风暴会放大问题。
如果以上指标都在健康范围,就无需过度依赖拆分方案,性能优化方案的选择,应该先做对比评估,最常见的三套方案是:
压缩 etcd 数据量
开启压缩和碎片整理,定期执行 etcdctl defrag、etcdctl compact,这套方案操作成本低,适合资源对象总量大但访问频率不高的集群,缺点是治标不治本,如果压力来自持续的高频请求,压缩只能缓解存储压力,对 QPS 没有本质帮助。
拆分 etcd 集群
把核心资源(Pod、Node、Deployment)与扩展资源(CRD 相关的自定义资源)分别落到不同 etcd 集群,通过修改 kube-apiserver 的启动参数:
--etcd-servers=http://etcd-a:2379 --etcd-servers-overrides=/custom.metrics.k8s.io#http://etcd-b:2379
拆分后,每个 etcd 集群的负载更专注,问题定位也更清晰。适合承担大量 CRD 和 Operator 的中大型集群,能有效阻断自定义资源对核心资源的冲击。
调整读写路径参数
改动 kube-apiserver 侧的 --max-requests-inflight、--watch-cache、--watch-cache-size,以及 etcd 侧的 --max-txn-ops 和 client 连接池配置,这套方案不改变架构,只调整行为,成本最低,适合规模还没到拆分程度、但性能已经出现波动的阶段。
拆分 etcd 集群的实操路径
业内专家指出,判断是否拆分,看一个核心指标即可:某个资源类型的控制器逻辑占用了 etcd 总请求量的一半以上,如果集群里某个自定义控制器频繁调谐,导致 CRD 的读写占比长期超过总请求量的一半,拆分就是值得做的事。
k8s 集群 etcd 延迟高怎么排查
很多团队遇到 etcd 延迟升高,第一反应是找存储节点的问题,换磁盘、加内存,但多数情况下,问题出在 API Server 与 etcd 之间的交互模式上。
先分清是读还是写
打开 etcd 的监控面板,先看 etcd_request_duration_seconds_sum 在两个维度上的分布:请求类型(range / txn / put)和资源类型(pod / deployment / custom resource)。
- 如果高延迟集中在
range(读请求),优先检查是否有大量全量 List 调用,比如某些控制器频繁执行未带字段选择器的 List 操作,每次返回全量对象。 - 如果高延迟集中在
txn(事务写请求),则优先检查控制器调谐是否过于频繁,以及 lease 续期是否在短时间内集中触发。
来看一个具体的排查路径:
# 查看 etcd 的慢请求日志(etcd 3.5+ 默认开启慢请求记录) journalctl -u etcd -n 200 | grep "slow" # 通过 etcdctl 查看各节点的延迟情况 etcdctl endpoint status --cluster -w table # 查看当前 watch 连接数量和客户端分布 etcdctl endpoint health --cluster
如果慢请求日志里大量出现类似 took too long (153.62ms) to execute request 的记录,说明 etcd 确实已经到达处理瓶颈,需要进一步分析请求来源。
容易忽略的“隐藏压力”
部分压力来自看似无关的系统组件。Ingress Controller,它默认会 watch 所有 Service 和 EndpointSlice 的变化,集群规模一大,这些 watch 事件本身就构成了持续的压力,同样的问题也会出现在

HPA(水平自动伸缩) 上,它需要周期性读取 Pod 的 metrics,频繁对 etcd 发起读请求。
你可以用命令验证哪些组件在持续产生请求压力:
# 在 API Server 侧开启审计日志,观察针对 etcd 的高频敏感操作 kubectl logs -n kube-system kube-apiserver-<pod> --v=4 | grep "etcd"
从日志里能看到具体是哪个组件在短时间密集发起 List 或 Watch 请求,这种“高频率 + 小对象”的请求模式往往是压垮 etcd 的最后一根稻草。
排除这类隐藏因素后,再回到集群规模本身,如果确认压力源集中在特定资源类型上,优先考虑利用 --etcd-servers-overrides 做轻量拆分,而不是直接把 etcd 迁移到更高配置的机器上。
etcd 读写压力的三个高频问题
Q1:etcd 读压力大有哪些常见原因?
读压力主要来自三方面:全量 List 请求密集、watch 客户端过多、单个资源对象体量过大,常见的触发场景包括:控制器频繁拉取全量 Deployment 列表、多个 Operator watch 同一类资源、ConfigMap 中存入大量配置数据导致响应体膨胀,排查时先看 etcd_request_duration_seconds_sum 中 range 请求的分位数,再结合 API Server 审计日志定位具体客户端。
Q2:控制面 etcd 压力与业务高峰有直接关系吗?
有一定关系,但并非决定性因素,业务高峰会带来 Pod 扩缩容、节点资源调度等操作,这些会间接增加 etcd 的读写量,但很多集群在业务低谷时 etcd 压力仍然很高,问题往往出在无业务相关的系统组件上,比如定期执行的备份任务、监控系统自带的资源发现机制、甚至某个配置不当的 CronJob 在持续刷新资源状态,业务高峰只是放大器,不是根源。
Q3:小规模集群有必要提前规划 etcd 扩容吗?
规模在 100 节点以内、CRD 使用较少的集群,做好数据压缩和常规监控即可,不必过早拆分,如果团队计划引入较多的 Operator 框架应用或大规模使用自定义资源,建议在引入之前评估 etcd 的负载基线,必要时提前规划拆分方案,还可以利用 etcdctl endpoint status --cluster -w table 定期检查各节点的空间使用量,把压力控制在萌芽阶段。
回到最初的问题:集群规模与 etcd 读写压力确实相关,但中间隔着“控制器活跃度”和“客户端请求模式”两道变量,把注意力放在规模数字上,不如放在请求模式的变化上前者只能解释现象,后者才能解决根因。

