etcd 3.5 版本变更全景解析:从 v3.5.0 破坏性变更到 3.5.x 补丁系列的安全与稳定性演进
本文以仓库中的 CHANGELOG/CHANGELOG-3.5.md 为核心素材,系统梳理 etcd 3.5 分支从 v3.5.0 正式版到 v3.5.34 的完整变更脉络:v3.5.0 的破坏性变更(Go 模块迁移、日志体系切换、V2 API 废弃、存储格式变化)、各补丁版本新增的关键配置项与命令(如 --listen-client-http-urls、--max-concurrent-streams、etcdutl snapshot restore 新标志、etcdutl check v2store 等),以及贯穿整个 3.5 系列的安全加固与稳定性修复。读完本文,你可以据此完成从 3.4 到 3.5 的升级评估,并在生产环境中正确选择、验证 3.5.x 的具体补丁版本。
一、变更日志的组织方式与版本时间线
CHANGELOG/CHANGELOG-3.5.md 按版本倒序排列,每条记录标注发布日期、所属组件(etcd server / clientv3 / etcdctl / etcdutl / grpc-proxy / Dependencies)以及对应 PR。3.5 系列自 2021 年 6 月 v3.5.0 GA 起,到本文档记录的 v3.5.34(TBC),覆盖了约五年、30+ 个补丁版本,是 etcd 生命周期最长的稳定分支之一。更早的版本记录见 CHANGELOG/CHANGELOG-3.4.md。
3.5 系列各版本的关键节点(日期均出自变更日志原文):
| 版本 | 日期 | 标志性变更 |
|---|---|---|
| v3.5.0 | 2021-06 | GA:Go modules 迁移、zap 日志默认化、V2 API 废弃、arm64 官方支持 |
| v3.5.8 | 2023-04-13 | --tls-min-version/--tls-max-version、--listen-client-http-urls 独立 HTTP 监听 |
| v3.5.10 | 2023-10-27 | snapshot restore 支持 --bump-revision/--mark-compacted |
| v3.5.11 | 2023-12-07 | livez/readyz HTTP 健康端点 |
| v3.5.16 | 2024-09-10 | --experimental-compaction-sleep-interval 新增 |
| v3.5.18 | 2025-01-24 | etcdutl check v2store 离线检查命令 |
| v3.5.28 | 2026-03-20 | 两个 RBAC 绕过型 CVE 的修复 |
| v3.5.33 | 2026-07-23 | watch 权限泄漏安全修复、client http.Server 设置 ReadHeaderTimeout |
排查升级问题时,建议先用 etcd --version 或 /version 端点确认当前小版本,再对照上表定位需要覆盖的修复。
二、v3.5.0 破坏性变更:升级前必读
v3.5.0 是 3.x 系列中破坏性变更最集中的一次,变更日志用独立的 "Breaking Changes" 小节列出。以下要点在从 3.4 升级时必须逐一核对。
Go 包路径迁移到模块惯例
go.etcd.io/etcd 下的 Go 包迁移到带 /v3 后缀的路径:go.etcd.io/etcd/{api,pkg,raft,client,etcdctl,server,raft,tests}/v3,以符合 Go modules 惯例。其中:
go.etcd.io/clientv3/snapshot的 SnapshotManager 类移入go.etcd.io/clientv3/etcdctl,下载远端快照的snapshot.Save方法保留在go.etcd.io/clientv3/snapshot;go.etcd.io/client包迁移到go.etcd.io/client/v2。
在当前仓库中可以直观看到这一布局:api、client/v3、server、pkg 均为独立 module,见 api/go.mod、client/v3/go.mod、server/go.mod、pkg/go.mod,工作区由 go.work 统一管理。
客户端行为变更
MemberListAPI 改为线性化读取:以前直接返回服务端本地(可能过期)数据,现在带线性化保证;如果服务器与 quorum 失联,调用会失败(PR 11639)。- ClientV3 支持 gRPC resolver API,端点管理改用
endpoints.Manager,原先的 GRPCResolver 已下线;端点自我标识格式变为etcd-endpoints://{id}/{authority}(例如etcd-endpoints://0xc0009d8540/localhost:2079)。 - 客户端错误中
context cancelled/context deadline exceeded现在映射为codes.Canceled和codes.DeadlineExceeded,而不是codes.Unknown——依赖旧行为做错误判断的应用代码需要调整。 ETCD_CLIENT_DEBUG环境变量现在支持日志级别(debug, info, warn, error, dpanic, panic, fatal),仅在显式设置时覆盖应用全局的 gRPC 日志配置。- 内嵌使用方(embed):
Etcd.Close()必须恰好调用一次;embed.Config不再覆盖全局 gRPC 日志器,如需旧行为须显式调用SetupGlobalLoggers()。
废弃的命令行标志与默认值变化
| 旧标志/行为 | v3.5 处理方式 |
|---|---|
--debug |
废弃,改用 --log-level=debug |
--log-output |
废弃,改用 --log-outputs |
--logger=capnslog |
废弃;--logger=zap --log-outputs=stderr 成为默认 |
--log-outputs=default |
不再支持;journal 输出须显式写 --log-outputs=systemd/journal |
/config/local/log 端点 |
废弃,无法再运行时调整日志级别 |
--experimental-backend-bbolt-freelist-type |
废弃,稳定版 --backend-bbolt-freelist-type 取代,默认 hashmap |
--enable-v2 / --experimental-enable-v2v3 |
废弃;etcd 3.5 是最后一个支持 V2 API 的版本 |
gRPC gateway /v3beta 端点 |
仅支持 /v3;curl -L http://localhost:2379/v3beta/kv/put ... 不再可用,改用 /v3/kv/put |
日志方面的变更值得单独说明:以前 etcd 父进程 PID 为 1(systemd 运行)时默认写 journal,写失败再回退 stderr;由于回退路径低效,v3.5 改为默认 --logger=zap --log-outputs=stderr,需要 journal 时显式配置 --log-outputs=systemd/journal。
Prometheus 指标同步更新:etcd_debugging_mvcc_db_total_size_in_bytes、etcd_debugging_mvcc_put_total、etcd_debugging_mvcc_delete_total、etcd_debugging_mvcc_txn_total、etcd_debugging_mvcc_range_total 均被废弃,分别改用 etcd_mvcc_* 对应指标;新增 etcd_debugging_mvcc_current_revision、etcd_debugging_mvcc_compact_revision、etcd_wal_write_bytes_total、os_fd_used/os_fd_limit、etcd_disk_defrag_inflight 等。注意任何 etcd_debugging_* 指标都是实验性的,可能变化。
存储格式变化(影响快照与降级)
- WAL 日志快照持久化
raftpb.ConfState; - backend 在
metabucket 的confStatekey 持久化raftpb.ConfState; - backend 在
metabucket 持久化 applied term; - backend 在
clusterbucket 持久化downgrade信息。
这意味着 3.5 的快照无法直接用于 3.4 节点,而 v3.5 同时提供了 downgrade API(cluster bucket 中的 downgrade 标记即为其存储基础),支持 3.5 集群回退到 3.4——仓库中 server/etcdserver/snapshot_merge.go 即处理这类快照合并逻辑的实现所在。
三、v3.5.0 引入的新功能与新标志
分布式追踪(OpenTelemetry)
v3.5.0 首次引入实验性分布式追踪,四个配套标志(后续 v3.5.11 修复了采样率配置):
--experimental-enable-distributed-tracing:启用追踪的布尔开关;--experimental-distributed-tracing-address:OpenTelemetry collector 地址;--experimental-distributed-tracing-service-name:服务名(默认 "etcd");--experimental-distributed-tracing-instance-id:每实例必须唯一的 ID。
embed 侧对应 embed.Config.ExperimentalEnableDistributedTracing 等字段,定义见 server/embed/config.go。
运维与可靠性类标志
--unsafe-no-fsync:禁用所有 fsync,会丢数据,仅用于测试/开发环境降低文件系统压力;--auth-token-ttl:自定义 simple token 的 TTL;--self-signed-cert-validity:指定 auto-tls 生成的自签证书有效期(默认 1 年);--experimental-warning-apply-duration:apply 耗时告警阈值可配置;--experimental-memory-mlock:防止 etcd 内存页被换出;--socket-reuse-port:启用SO_REUSEPORT,允许绑定已占用的端口,变更日志特别提醒需自行保证 flock 语义正确;--socket-reuse-address:启用SO_REUSEADDR,允许绑定处于TIME_WAIT的地址,加快重启速度;--enable-log-rotation与--log-rotation-config-json:启用日志轮转并向 file sink 透传 JSON 轮转配置;--bootstrap-defrag-threshold-megabytes:bootstrap 时数据库未用空间超过阈值自动 defrag,值 0 表示禁用。
源码中可以看到这些标志在 server/embed/config.go 中注册,例如 socket-reuse-port 的注册与说明("Enable to set socket option SO_REUSEPORT on listeners allowing rebinding of a port already in use.")。
客户端与工具侧
clientv3/concurrency.Mutex新增非阻塞的TryLock方法;etcdctl新增:watch --progress-notify、auth status(检查认证是否启用,对应/v3/auth/status端点)、get --count-only(fields 输出)、member list -w=json --hex;etcdctl lock改为返回被锁命令的退出码;- 新工具
etcdutl诞生:吸收etcdctl snapshot status|restore、etcdctl backup、etcdctl defrag --data-dir ...的功能;ETCDCTL_API=3 etcdctl migrate同时下线,恢复 v2 存储需用 etcd <= 3.4。仓库中 etcdutl/ 目录即其实现,快照命令在 etcdutl/snapshot/v3_snapshot.go。 - gRPC gateway 通过配置文件使用时,需显式设置
enable-grpc-gateway为 true 以与命令行默认行为保持一致。 - 平台:官方支持 arm64,并新增 s390x 构建。
四、3.5.x 补丁系列的能力演进(按版本梳理)
v3.5 补丁系列几乎每月一个小版本,以下按"对运维者最有操作价值"的条目归纳,完整细节以 CHANGELOG/CHANGELOG-3.5.md 原文为准。
v3.5.5 / v3.5.8:连接与传输层控制
--max-concurrent-streams(v3.5.5):限制每个客户端同时打开的 gRPC 流数量,默认math.MaxUint32。在 server/embed/config.go 中可看到其定义与帮助文案 "Maximum concurrent streams that each client can open at a time."--tls-min-version/--tls-max-version(v3.5.8):支持 TLS 1.3。server/embed/config.go 中默认最小版本为 TLS1.2,可取TLS1.2、TLS1.3。--listen-client-http-urls(v3.5.8):把 HTTP 服务端从 gRPC server 上分离出来单独监听,彻底规避高读负载下 watch 流饥饿问题。源码约束见 server/embed/etcd.go:--listen-client-urls与--listen-client-http-urls不允许绑定同一 URL。--cipher-suites增加 ChaCha20-Poly1305 两个套件(v3.5.0)。- v3.5.8 还将 zap 时间戳精度对齐到微秒(
2006-01-02T15:04:05.999999Z0700),并修复了 JWT token 缺少 username/revision 时的 panic、CVE-2021-28235(认证后清除内存中的密码)。
v3.5.10 ~ v3.5.12:快照恢复与健康检查
- v3.5.10:
etcdctl snapshot restore与etcdutl snapshot restore新增可选--bump-revision和--mark-compacted标志,用于恢复场景中的 revision 处理;同版修复--socket-reuse-port/--socket-reuse-address无法在配置文件中设置的问题。 - v3.5.11:新增 livez/readyz HTTP 端点(对以 Kubernetes pod 方式运行 etcd 的场景尤为重要);修复
--experimental-distributed-tracing-sampling-rate不可用的问题。 - v3.5.12:在帮助文档中补记
--experimental-enable-lease-checkpoint-persist标志(该标志自 v3.5.2 引入,用于启用租约 checkpoint 持久化,防止 leader 切换时 TTL 被重置)。
v3.5.16 / v3.5.18 / v3.5.25:compaction 与离线检查
- v3.5.16:新增
--experimental-compaction-sleep-interval控制每批 compaction 之间的休眠间隔(v3.5.19 又修复了该机制带来的性能回退);同时把etcd_disk_wal_write_duration_seconds指标补齐了注册。 - v3.5.18:新增
etcdutl check v2store命令,离线检查 v2store 中是否含有自定义内容(配合 v2 存储退役流程);该命令在 v3.5.25 增加--wal-dir支持独立 WAL 目录,v3.5.32 进一步增强为同时检查 v2 snapshot 与 WAL 记录。命令实现位于 etcdutl/etcdutl/snapshot_command.go 相关的 etcdutl 命令目录 etcdutl/etcdutl/。 - v3.5.19:
readyz端点加入 learner 状态检查(backport)。 - v3.5.32:
--v2-deprecation新增write-only-skip-check选项,可跳过 v2 内容检查。 - v3.5.16 同时新增
--experimental-stop-grpc-service-on-defrag:defrag 期间暂停 gRPC 服务以触发客户端 failover。
贯穿性主题:安全修复密集
3.5 系列后半段(2025 下半年起)安全修复显著加密,升级决策时应对号入座:
- v3.5.28:修复多个 API 的认证绕过(CVE-2026-33413)与嵌套事务绕过 RBAC(CVE-2026-33343);
- v3.5.30:修复 RBAC 可通过嵌套在事务内的 Put 请求借
PrevKv或 lease 附加读取绕过的授权漏洞;修复 quorum 满足但有一节点宕机时无法添加新成员的问题; - v3.5.32:修复配置了
--listen-client-http-urls时 gRPC 监听上 CRL 强制被绕过的问题(GHSA-3wh4-j44w-pg92); - v3.5.33:修复"用户对某 key 有读权限却能收到以该 key 为起点的所有后续 key 的 watch 响应"的越权问题,并为 client http.Server 设置 ReadHeaderTimeout、为 peer lease HTTP handler 的 body 读取加上界、为 tlsListener 设置 tlsHandshakeTimeout;
- v3.5.24:拒绝 revision 为 -1 的 watch 请求,防止未 compact 集群上的非法 resync。
依赖层面,每个补丁版本都会同步升级 Go 工具链(从 v3.5.8 的 go 1.19.8 一路到 v3.5.34 的 go 1.25.13)并跟进 CVE 修复(golang.org/x/crypto、x/net、grpc、protobuf、jwt 等),因此"升到最新 3.5.x"本身也是安全实践。
五、稳定性与数据正确性修复速览
除安全外,3.5 系列中值得运维关注的正确性修复包括:
- compaction/watch 相关:v3.5.13 修复 compaction 后的 watch 事件丢失与无进度通知问题;v3.5.22 修复"watch 未来 revision 却返回旧事件";v3.5.18 修复 watch 打开在与 compaction 请求相同 revision 时缺 delete 事件的问题。
- defrag 相关:v3.5.6 修复 defrag 期间崩溃导致 revision 不一致;v3.5.17 修复 defrag 错误处理 panic 与临时文件未关闭;v3.5.23 修复 applySnapshot 与 defragment 并发时的数据损坏风险。
- 成员管理:v3.5.31 修复 MemberUpdate 隐式且意外地提升 learner;v3.5.24/v3.5.20 修复 learner 提升未持久化到 v3store 的问题;v3.5.28 修复开启 auth 时无法从 follower 提升成员的问题。
- 租约:v3.5.13 修复旧 leader 的撤销请求误删新 leader 租约;v3.5.23 修复租约已吊销却返回 leaseRenew 成功的问题。
- 读取正确性:v3.5.28 修复 read index 与 leader 切换的竞态、进程暂停导致的过期读(stale reads)。
六、如何核对与验证(结合仓库)
- 核对版本条目:CHANGELOG/CHANGELOG-3.5.md 按版本倒序组织,直接搜索版本号即可定位;3.4 之前的记录在 CHANGELOG/CHANGELOG-3.4.md,索引见 CHANGELOG/README.md。
- 验证标志是否可用:本文引用的服务器标志集中在 server/embed/config.go(flag 注册)与 server/etcdmain/ 目录(命令行入口与 help 文案,如 server/etcdmain/help.go 中的默认值展示),可用
etcd --help与实际二进制输出比对。 - 验证工具命令:etcdutl 各子命令(snapshot、check、defrag、migrate 等)实现在 etcdutl/etcdutl/,例如 etcdutl/etcdutl/snapshot_command.go、etcdutl/etcdutl/defrag_command.go。
- 注意适用前提:本仓库处于活跃演进状态,部分 3.5 条目在主干上的实现可能已进一步变化;v3.5.34 标注 TBC(待发布),文中所有条目以该 changelog 文件的记录为准,实际部署前请以对应 release 的官方说明再次确认。
小结
etcd 3.5 系列的意义在于:v3.5.0 一次性完成 Go modules 迁移、zap 日志默认化、V2 API 废弃与 V2 API 的最终告别,并留下官方 arm64 支持与 etcdutl 新工具;此后两年多的补丁系列则以每月节奏持续交付 TLS、独立 HTTP 监听、流并发控制、快照恢复增强等运维能力,并在后期集中清除了多个 RBAC/认证绕过类漏洞。对仍运行 3.5 的集群,升级到 v3.5.33 及以上可以同时覆盖 watch 权限泄漏、CRL 绕过与无界读取等一批安全修复。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00