首页
/ etcd v3.4 版本发布全史:从 Learner、Pre-Vote 到 v3.4.45 EOL 的变更解读与升级要点

etcd v3.4 版本发布全史:从 Learner、Pre-Vote 到 v3.4.45 EOL 的变更解读与升级要点

2026-09-05 22:30:59作者:凤尚柏Louis

本文基于仓库中的 CHANGELOG-3.4.md 完整梳理 etcd v3.4 系列(v3.4.0 ~ v3.4.45)的 45 个补丁版本发布记录,覆盖每个版本的服务端修复、clientv3 改进、安全漏洞响应与依赖升级。读完本文,你能掌握:v3.4 相对 v3.3 引入了哪些核心能力(Learner、Pre-Vote、watch 分片、lease checkpointing)、哪些行为属于破坏性变更(breaking changes)、哪些 CVE 修复必须跟进,以及如何依据 changelog 制定生产环境的版本选择与升级策略。

一、v3.4 变更日志的组织方式与 EOL 公告

仓库中每个 minor 版本对应一份独立变更日志(CHANGELOG/ 目录下有 CHANGELOG-3.3.md 至 CHANGELOG-4.0.md 等),阅读顺序由新到旧。CHANGELOG/CHANGELOG-3.4.md 记录 v3.4.0(2019-08-30)到 v3.4.45(2026-06-01)的全部发布,其组织规则在 CHANGELOG/README.md 中明确:

  • 每个补丁版本只记录相对上一个补丁版本的变更(例如 v3.5.5 只包含相对 v3.5.4 的新增项);
  • 每个 minor/major 的第一个版本(如 3.4.0)只记录相对上一 minor 版本(3.3.0)的新增内容。

v3.4.45(2026-06-01)是 v3.4 系列的最终版本,标志着该分支结束支持(EOL):changelog 明确声明“此后不再发布补丁”,仍在使用 v3.4 的环境应尽快升级到受支持的版本。这是阅读本 changelog 时最重要的一条信息——v3.4 的所有修复(包括下文多个 CVE 修复)只在 v3.4 分支内有效,长期策略上应规划升级到 v3.5+ 分支。

当前仓库主分支已经领先于 v3.4:api/version/version.goVersion = "3.8.0-alpha.0",且 AllVersions 版本列表包含 V3_4V3_5V4_0 等常量。因此文中若引用当前源码路径,均指主分支实现,用于印证 v3.4 引入的特性在代码中的落点,而不是 v3.4 分支本身。

二、v3.4.0:一次能力跃迁版本

v3.4.0(2019-08-30,含 rc.0~rc.4 共 6 个发布阶段)是 v3.4 的主版本,变更密度远高于后续补丁版本。以下按主题完整继承 changelog 的核心内容。

2.1 Raft Learner 与集群扩缩容

  • Add Raft learner:etcd 支持以 learner 身份添加成员。用户可通过 etcdctl member add --learner 添加 learner,再用 etcdctl member promote 提升为正式成员,API 层对应 MemberAddRequest/isLearner 字段与新增的 MemberPromote RPC。从当前仓库源码看,这套接口仍保留在 client/v3/cluster.goMemberAddAsLearner/MemberPromote)与服务端 RPC 定义 api/etcdserverpb/etcdserver.proto 中。
  • learner 配套的可观测性指标:etcd_server_is_learneretcd_server_learner_promote_failuresetcd_server_learner_promote_successes
  • raft 包层面:raftpb.ConfState.Nodes 更名为 raftpb.ConfState.Voters;新增 raftpb.ConfChangeV2 支持 joint quorum(联合仲裁);新增 raft/quorumraft/confchange 包处理成员变更;learner 可以投票但不计入 quorum(针对已提升但尚未感知的过渡态)。

2.2 客户端(clientv3)重大重构

  • 重写 client balancer:基于 gRPC 新的 balancer 接口(gRPC 升级到 v1.23.0),修复了“kube-apiserver 1.13.x 在首个 etcd-server 不可用时拒绝工作”与“多成员集群 failover 时 DNS 不一致导致证书校验失败”两类问题。新的 balancer 使用异步 resolver 把 endpoints 传给 gRPC dial 函数,如需阻塞直到底层连接建立,需要在 clientv3.Config.DialOptions 中传入 grpc.WithBlock()
  • watch 分片(fragmentation)etcdserverpb.WatchCreateRequest 新增 fragment 字段,当 watch 事件总量超过服务端 etcd --max-request-bytes(默认 embed.DefaultMaxRequestBytes 为 1.5 MiB)+ gRPC 开销 512 字节时,服务端将事件拆分为多个低于上限的 chunk 发送;clientv3 端通过 WithFragment OpOption 与自动合并逻辑对接。适用于客户端带宽受限的场景。
  • Watcher.RequestProgress 方法:手动触发向所有关联 watch 流广播 progress 事件(带最新 header 的空响应),可视为可手动触发的 WithProgressNotify
  • watch 重试在瞬态错误时加入 backoff;watch progress notify 加入 jitter,避免 etcd_network_client_grpc_sent_bytes_total 尖峰。
  • PermitWithoutStream 选项:允许客户端在没有活跃流的情况下发送 keepalive ping。
  • 修复 lease keepalive 在响应队列满时仍以 500ms 而非 TTL/3 频率发送的问题;修复 clientv3/concurrency 在取消时释放锁 key 的逻辑;修复 (*Client).Endpoints() 竞态。

2.3 自动压缩(Auto-Compaction)保留窗口调整

  • --auto-compaction-mode=revision --auto-compaction-retention=1000:每 5 分钟在 “latest revision − 1000” 处压缩。
  • periodic 模式行为变化:--auto-compaction-retention=24h 时,压缩从每 2.4 小时一次改为每小时一次(v3.3.3 之前是 2.4 小时);--auto-compaction-retention=30m 时从每 3 分钟一次改为每 30 分钟一次。压缩器在每个压缩周期(<1h 按周期,>1h 按 1h)记录最新 revision,用上一周期获取的 revision 丢弃历史数据,保留窗口随之逐周期移动。
  • 修复 revision 模式保留值解析 bug:此前 --auto-compaction-mode revision --auto-compaction-retention 1 会被错误解析为 3600000000000。

2.4 Raft 选举与重启行为

  • Pre-Vote 特性:新增 etcd --pre-vote 标志(v3.4 默认 false,v3.5 起默认 true)。故障/重加入的成员会发起选举并把 term 抬高,导致忽略低 term 消息、最终触发一次破坏性选举;Pre-Vote 阶段先探测能否获得足够选票,从而避免此类扰动。
  • initial election tick advance:新增 etcd --initial-election-tick-advance(默认 true)。默认情况下本地成员在启动时快进选举 tick 以加速首次选主——例如跨数据中心部署需要 10 秒选举超时时,tick 可快进到只剩 2 秒。若 leader 到重加入 follower 的网络拥塞、follower 没能在剩余 tick 内收到心跳,仍会发生破坏性选举,可设 false 关闭,代价是跨数据中心场景的初始 bootstrap 变慢;单节点集群无论该值如何都会快进。
  • 长读事务并发改进:backend 读事务做到全并发(此前长读会阻塞写与后续读),在有长读存在时写吞吐提升 70%、P99 写延迟降低 90%;周期性 commit 不再阻塞并发读事务。
  • index compaction 使用 copy-on-write clone,不再持锁遍历整个索引。
  • 新增 raft.ErrProposalDropped:内部 Raft proposal 被丢弃时(成员被移除、leadership transfer 期间收到 MsgProp 等)服务端向 v3/v2 applier 返回该错误。
  • raft.Config.MaxUncommittedEntriesSize 限制未提交 entry 总字节数,超限返回 ErrProposalDropped,防止 Raft 日志无界增长;Ready.CommittedEntries 支持按 MaxSizePerMsg 分页,避免日志极大时一次性 commit 导致 OOM。
  • 消息发送流控优化:leader 允许多个在途 append 消息;新增 raft/tracker 包单独承载 progress 跟踪。

2.5 Lease 相关

  • Lease checkpointing:新增 --experimental-enable-lease-checkpoint 实验标志,把剩余 TTL 周期性持久化到共识日志,使长寿命 lease 在 leader 切换与重启后仍按预期走向过期。
  • lease 过期/撤销操作性能改进;Lease.Lookup 在并发 Grant/Revoke 下变为非阻塞。
  • 防止 Grant 的超大 TTL 溢出:TTL 单位为秒,超过 9,000,000,000 秒(约 285 年)时服务端返回 rpctypes.ErrLeaseTTLTooLarge。etcd Lease 设计目标是秒/分钟级会话,而非小时/天级。

2.6 日志体系:zap 取代 capnslog

  • 新增 etcd --logger 标志支持结构化日志。--logger=capnslog --log-outputs=default 为默认(与旧格式一致);--logger=zap 输出 JSON 格式,--log-outputs 支持多个输出(stderrstdoutsystemd/journal、任意文件,可组合如 a.log,b.log,c.log,stdout/dev/null 丢弃日志)。注意 --logger=zap --log-outputs=default 组合不支持,需显式指定 stderr 等。
  • 动机是让 etcd “少打日志、多靠指标告警”,推动自动化监控而非回看日志排障。
  • 新增 --log-level 标志;--log-output 更名为 --log-outputs--log-output 在 v3.5 弃用);--debug 标志被弃用,改用 --log-level=debug
  • embed.Config.SetupLogging 被移除,日志器基于 embed.Config.LoggerLogOutputsDebug 字段自动建立。

2.7 安全与认证

  • TLS 密码套件白名单:新增 etcd --cipher-suitesembed.Config.CipherSuites,用于屏蔽弱密码套件;为空时由 Go 自动填充;embed.Config.ClientTLSInfo.CipherSuitesembed.Config.CipherSuites 不可同时非空。
  • Host 白名单:新增 etcd --host-whitelist(以及 etcdserver.Config.HostWhitelistembed.Config.HostWhitelist)防御 DNS Rebinding 攻击。策略:HTTPS 连接放行任意 hostname;非安全连接且白名单非空时,仅放行 Host 字段在白名单内的 HTTP 请求;默认 * 表示非安全服务器放行所有请求;回环地址不会自动加入,需要手动添加 localhost/127.0.0.1。该策略无论是否开启认证都会执行。当前源码中标志注册仍在 server/embed/config.gohost-whitelist,默认 *)。
  • 支持无密码用户(只能走 CommonName 认证),降低密码泄露风险。
  • 支持 etcd --cors 用于 gRPC gateway 的 v3 HTTP 请求;embed.Config.CorsInfo*cors.CORSInfo)改为 embed.Config.CORSmap[string]struct{})。
  • JWT 认证:token 支持 ttl 字段(如 --auth-token jwt,pub-key=...,priv-key=...,sign-method=...,ttl=5m),签名算法放开为任意支持的方法;etcdserver.ServerConfig.AuthToken 允许空的 token provider。
  • 修复证书 SAN 仅含 IP 时 TLS reload 不触发的问题:现在初始握手时 (*tls.Config).Certificates 置空以触发 GetCertificate,即使客户端 SNI 为空也能在线轮换过期证书。
  • 新增 --experimental-peer-skip-client-san-verification 跳过对 peer 客户端地址的校验。

2.8 破坏性变更(v3.4 升级必读)

以下为 changelog 明确列出的 breaking changes,从 v3.3 升级到 v3.4 时逐条核对:

  1. 导入路径迁移:模块从 "github.com/coreos/etcd" 迁移到 "github.com/etcd-io/etcd",导入路径统一改为 go.etcd.io/etcd/...(如 import "go.etcd.io/etcd/raft")。
  2. 依赖管理从 glide 迁移到 Go modules,要求 Go 1.12+;cmd/vendor 移到仓库根 vendor,移除 cmd 下递归软链;go get/install/build 强制使用 vendor 构建。
  3. etcdctl 默认 API=3etcdctl set foo bar 必须改为 ETCDCTL_API=2 etcdctl set foo baretcdctl put foo bar 不再需要 ETCDCTL_API=3 前缀。
  4. v2 store 默认关闭etcd --enable-v2=false 成为默认,embed.DefaultEnableV2 也改为 false。
  5. TLS 标志更名--ca-file 弃用改用 --trusted-ca-file--peer-ca-file 弃用改用 --peer-trusted-ca-filepkg/transport.TLSInfo.CAFile 字段弃用改用 TrustedCAFile
  6. 容器标签latest 与 minor 版本 tag 弃用——docker pull .../etcd:v3.4 不再可用,必须用精确补丁版本 tag(如 v3.4.x);ACI 产物停止提供。
  7. 空 host 的 advertise URL 直接退出:如 --advertise-client-urls=http://:2379 会报错退出。
  8. 影子环境变量退出:如 ETCD_NAME=abc etcd --name=defETCDCTL_ENDPOINTS=abc.com ETCDCTL_API=3 etcdctl endpoint health --endpoints=def.com 会报错退出。
  9. proto 字段类型变化AuthRoleRevokePermissionRequestkey/range_endstring 改为 bytes
  10. gRPC gateway 端点/v3beta/v3alpha 弃用,统一为 /v3(v3.4 中 /v3beta 仍作为 /v3 的 fallback 可用,v3.5 移除);lease 相关 HTTP 端点从 /v3/kv/lease/* 迁移到 /v3/lease/{leases,revoke,timetolive}
  11. snapshot 文件权限:Linux 下从 0644 收紧为 0600。
  12. etcdctl snapshot 退出码变化:出错统一退出码 1(不再有 5/6)。
  13. grpc.ErrClientConnClosing 弃用:clientv3 与 grpcproxy 不再返回它,改用 clientv3.IsConnCanceled(error)status.FromError(error)
  14. 字段与配置更名etcdserver.ServerConfig.SnapCount/embed.Config.SnapCount 更名 SnapshotCountembed.Config.LogOutput(string)更名 LogOutputs[]string),配置 YAML 中 log-outputs: default 必须改为 log-outputs: [default]
  15. wal 包函数签名变化Open/OpenForRead/Repair/Create 均增加 *zap.Logger 参数;pkg/cors 包移除;多个内部包(alarm、compactor、discovery、memberships 等)移入 etcdserver/api/*
  16. pkg/adt.IntervalTree 从 struct 改为 interface(并修复了红黑树删除操作破坏黑高性质的问题)。
  17. 发布分支版本号格式3.4.x-pre 替代 3.4.y+git(如 3.4.5-pre)。

2.9 新增 Prometheus 指标

v3.4.0 一次性引入大量指标(etcd_debugging_* 均为实验性,可能随时变化):

  • 网络/快照:etcd_network_active_peers(按 Local/Remote 标签记录每对 peer 连接状态)、etcd_network_disconnected_peers_totaletcd_network_server_stream_failures_total(如 {API="watch",Type="receive"} 1)、快照收发成功/失败/耗时/在途计数(etcd_network_snapshot_send/receive_*),etcd_snap_fsync_duration_secondsetcd_network_peer_round_trip_time_seconds 改为采样 leader 心跳并扩大直方图上限(0.8192s / 1.6384s / 3.2768s)。
  • 服务器:etcd_server_is_leaderetcd_server_idetcd_server_version(替代 Kubernetes etcd-version-monitor)、etcd_cluster_versionetcd_server_go_versionetcd_server_health_success/failuresetcd_server_read_indexes_failed_totaletcd_server_heartbeat_send_failures_totaletcd_server_slow_apply_totaletcd_server_slow_read_indexes_total
  • 存储:etcd_server_quota_backend_bytes(如 2.147483648e+09 表示 2GB 配额)、etcd_mvcc_db_total_size_in_use_in_bytes(defrag 后可达到的“在用水位”)、etcd_mvcc_db_open_read_transactionsetcd_mvcc_db_total_size_in_bytes − etcd_mvcc_db_total_size_in_use_in_bytes 即为 defrag 可回收的字节数etcd_disk_backend_defrag_duration_secondsetcd_mvcc_hash_duration_secondsetcd_mvcc_hash_rev_duration_seconds、backend commit 的 rebalance/spill/write 耗时。
  • Lease:etcd_debugging_lease_granted/revoked/renewed_totaletcd_debugging_lease_ttl_total
  • 弃用指标(v3.5 移除):etcd_debugging_mvcc_db_total_size_in_bytesetcd_mvcc_db_total_size_in_bytesetcd_debugging_mvcc_put/delete/range/txn_total → 去前缀版本。
  • 其他:etcd_debugging_mvcc_index_compaction_pause_duration_milliseconds 直方图上限扩大(1.024s / 2.048s / 4.096s);gRPC proxy 的 /metrics 改为暴露真实 etcd server 端点(此前暴露的是 proxy 自身指标)。

2.10 etcdctl 与其他工具

  • 新增 etcdctl member add --learneretcdctl member promote--password 标志(支持用户名含 :);user add --new-user-password
  • 新增 etcdctl check datascalecheck perf(均可选 --auto-compact--auto-defrag)、defrag --cluster
  • endpoint status 新增 “raft applied index” 与 “errors” 字段;endpoint health 支持 --write-out 并修复缺失换行。
  • watch --interactive 新增 progress 命令;修复 etcdctl watch [key] [range_end] -- [exec-command...] 解析 panic;修复 TLS 端点下的 move-leadersnapshot save 支持 --command-timeout;discovery 场景剥离不安全端点。
  • endpoint status 的 StatusResponse 同步新增 raftAppliedIndexerrors(如 "etcdserver: no leader""NOSPACE""CORRUPT")、dbSizeInUse 字段。
  • 新增 snapshot 包,便于以库形式实现 snapshot save/restore 工作流。
  • WAL 包新增 Verify 函数做 WAL 内容损坏检查——当前仓库中该函数仍位于 server/storage/wal/wal.go
  • 工具:etcd-dump-logs 新增 --entry-type(按 entry 类型过滤)与 --stream-decoder(自定义解码器);release assets 新增 SHA256SUMS(维护者团队分布全球,允许无签名密钥的校验发布)。
  • Dockerfile 基础镜像从 Alpine 换到 Debian(3.4.18 时又进一步升级 bullseye 基础镜像以修复多个高危 CVE)。

2.11 v3.4.0 依赖升级(摘选)

bbolt 从 github.com/coreos/bbolt v1.3.1-coreos.6 迁到 go.etcd.io/bbolt v1.3.3;gRPC 从 v1.7.5 升到 v1.23.0;ugorji/go/codec 迁到 json-iterator/goghodss/yaml 迁到 sigs.k8s.io/yaml;gogo/protobuf v1.2.1;cmux v0.1.4;google/btree v1.0.0;prometheus/client_golang v1.0.0;grpc-gateway v1.4.1 等。编译使用 Go 1.12.9(含 1.12.8 安全修复),要求 Go 1.12+。

三、补丁版本演进:v3.4.1 ~ v3.4.45 时间线

以下按 changelog 原文逐版本覆盖(自新至旧),保留每条的实质内容,作为生产排障与补丁跟进的检索索引。

3.1 v3.4.38 ~ v3.4.45(近年维护期)

  • v3.4.45(2026-06-01):EOL 版本,仅依赖变更——编译工具链升级到 go 1.25.10。
  • v3.4.44(2026-05-01):修复 RBAC 授权绕过——嵌套在事务中的 Put 请求可通过 PrevKv 或 lease 附加获得读访问(两个 PR 分别修复)。go 1.25.9。
  • v3.4.43(2026-04-01):允许非 admin 用户获取成员列表与 alarms;修复开启 auth 时 etcdctl endpoint --cluster 的回归。
  • v3.4.42(2026-03-20):修复 read index 与 leader 切换的竞态;修复进程暂停(pause)导致的陈旧读;针对两个 CVE 的授权加固——多 API 未认证端点授权绕过(CVE-2026-33413)与嵌套事务绕过 RBAC 检查(CVE-2026-33343);go 1.25.8;升级 golang.org/x/net 至 v0.51.0、gRPC 至 1.79.3 修复对应漏洞。
  • v3.4.41(2026-02-13):clientv3 移除对 grpc-go Metadata 字段的使用;go 1.24.13(同时解决三个 Go 标准库 CVE)。
  • v3.4.40(2025-12-17):日志中只打印 token 指纹而非原始 token;构建脚本使用 buildvcs=false,避免 go version 报告 pseudo-version;go 1.24.11;升级 golang.org/x/crypto 到 0.45.0 修复两个 CVE。
  • v3.4.39(2025-11-11):构建侧使用 buildvcs=false;go 1.24.10。
  • v3.4.38(2025-10-21):一批存储与 lease 修复——修复 watch close/cancel 竞态下 watcher gauge 双重递减;修复“watch 未来 revision 却收到旧事件”;改进 --quota-backend-bytes 帮助信息;修复 applySnapshot 与 defragment 并发时可能损坏数据;拒绝 -1 revision 的 watch 请求以防止未压缩 etcd 上的异常重同步;修复 lease 已吊销时 LeaseRenew 仍可能返回成功。go 1.24.9;bbolt 升至 v1.3.12。
  • v3.4.37(2025-04-15):仅依赖——golang.org/x/net v0.36.0(修复 CVE-2025-22870);go 1.23.8。
  • v3.4.36(2025-02-25):避免 bootstrap 期间调用 etcd.Close 的 deadlock;修复在“与压缩请求同一 revision 打开的 watch”丢失 delete 事件;clientv3 修复 KeepAlive 使用不可比较类型的 Context 引发的 panic。go 1.23.6;x/crypto v0.35.0、x/net v0.34.0 修复相关 CVE。
  • v3.4.35(2024-11-12):修复 watchserver 相关 goroutine 泄漏;修复 defragment 期间错误处理不当引发的 panic;defragment 出错时关闭临时文件。go 1.22.9。

3.2 v3.4.31 ~ v3.4.34(3.5 兼容性窗口)

  • v3.4.34(2024-09-11):修复 lease renew 中 ensureLeadership 引入的性能回归;压缩时若 tombstone 恰是压缩 revision 则保留;clientv3 用官方 go fmt 包保证 gRPC metadata 打印顺序;go 1.22.7;bbolt 1.3.11。
  • v3.4.33(2024-06-13):grpc-proxy 修复 proxy 节点下线后 memberlist 不更新;go 1.21.11;bbolt 1.3.10。
  • v3.4.32(2024-04-25):LeaseTimeToLive 在 leader 变更时不再报错;member id 不匹配时忽略 raft 消息;bootstrap 时更新 compaction 日志;新增 next-cluster-version-compatible=true 允许新 server 加入 3.5 集群、允许从 3.5 降级时更新集群版本;修复 compaction 期间 panic 后 revision 回退。clientv3 在收到 ErrGRPCLearnerNotSupported 且 endpoints > 1 时自动重试;go 1.21.9。
  • v3.4.31(2024-03-21):compaction 日志打印 backend 数据库大小与在用大小;忽略旧 leader 的 lease 撤销请求,修复 lease 被错误吊销;修复无事件 watch 不发送 progress 通知;修复 compaction 后的 watch 事件丢失;新增 next-cluster-version-compatible 标志支持从 3.5 降级;clientv3 增加 backoff 与 retry 配置选项;bbolt 1.3.9、protobuf v1.33.0(修复 CVE-2024-24786)、logrus v1.9.3;构建侧支持配置 CGO_ENABLED

这一窗口(v3.4.31/v3.4.32)是3.4 与 3.5 集群混布/回滚的关键版本:若曾升级到 3.5 需要回退,3.4 侧必须至少到这两个版本才能正常加入。

3.3 v3.4.25 ~ v3.4.30

  • v3.4.30(2024-01-31):修复因用错日志库导致的 nil 指针 panic;go 1.20.13;x/crypto v0.17+ 修复 CVE-2023-48795。
  • v3.4.29(2024-01-09):peer 通信禁用 HTTP 重定向跟随;新增 livez/readyz HTTP 端点be 被覆盖为 nil 时的 panic 防护;help 输出补上遗漏的 experimental-enable-lease-checkpoint-persist 标志;snapshot 文件不再被 flock;go 1.20.12。
  • v3.4.28(2023-11-23):auth 关闭时跳过从入站 context 读取 authInfo;golang.org/x/net v0.11.0 改用 round-robin 调度器后恢复默认写调度器;数据损坏检测加入集群 ID 检查防误报;Learner 支持 Snapshot RPC。clientv3:auth 被禁用时刷新失败会重置 auth token;简化 grpc dialer 用法;自研 balancer 替换为上游 gRPC 方案(消除 1.10 起弃用的自定义 balancer);修复 dial() 访问 cfg.Endpoints 的竞态、单端点场景的 authority 头错误。bbolt 1.3.8;gRPC 升级 1.58.3,注意:gRPC server 会拒绝携带 Connection 头的请求(这是有客户端兼容影响的依赖变更)。
  • v3.4.27(2023-07-11):修复刚做完 compaction 时 corruption check 报 ErrCompacted;auth 关闭或 admin 用户时 lease put 性能改进;stopServer nil 指针修复。etcdctl snapshot restore 新增可选 --bump-revision--mark-compacted 标志。go 1.19.10。
  • v3.4.26(2023-05-12):LeaseTimeToLive 不再向无读权限的客户端返回 key(越权读修复)。go 1.19.9。
  • v3.4.25(2023-04-14):本版引入两个新标志并修多个问题——
    • --tls-min-version / --tls-max-version:支持 TLS 1.3 的版本边界控制;
    • --listen-client-http-urls:把 HTTP(gRPC gateway)服务与 gRPC 服务分离监听,从根本上免疫高读负载下 watch 流被饿死(starvation)的问题;
    • http2 frame 调度改为随机算法;
    • 修复同地址同时启动安全/不安全 gRPC server 的数据竞争;auth 禁止创建空权限区间;wsproxy JSON 日志格式修复;
    • 修复 CVE-2021-28235(认证成功后清除密码内存);
    • 修复解析无 username/revision 的 JWT 时 panic;
    • 修复成员重连从 leader 下载 snapshot 时 watch 响应“回到过去”;修复 progress notify 与流的同步问题。
    • 推荐 Go 1.19+,编译用 1.19.8;Docker 镜像修复“所有 tag 都标记 amd64”的架构标注问题。

3.4 v3.4.20 ~ v3.4.24

  • v3.4.24(2023-02-16):修复非启动 learner 被错误提升;count-only range 开销降低;RangeOptions.limit 下推到索引树减少内存;多并发 readTx 共享一个 txReadBuffer;zap 时间戳精度从毫秒对齐到微秒(格式 2006-01-02T15:04:05.999999Z0700);IPv6 地址比较统一格式。clientv3 修复可能向 watch 客户端发送重复事件;bbolt v1.3.7;grpc-gateway v1.9.5→v1.11.0;Docker 基础镜像从 base-debian11 换 static-debian11 并移除 busybox。
  • v3.4.23(2022-12-21):corruption alarm 去掉 memberID;只读 txn nil 响应 panic 修复;依赖升级缓解多个高危漏洞(推荐 Go 1.17+,编译 1.17.13);clientv3 修复 CommonName 认证刷新 token 的段错误;Docker 镜像改用 distroless 基础镜像应对关键漏洞。
  • v3.4.22(2022-11-02):corruption alarm 中 memberID 为 0 的修复;auth 场景下 watch 的 invalid token/old revision 错误;避免错误关闭 ID 为 0 的 watch;auth 从 snapshot 恢复时的数据一致性问题。netutil 的 URLStringsEqual 加入无解析器的 URL 比较;clientv3 在 watch 流不可用时重试前加 backoff;grpc-proxy 新增 --listen-cipher-suites 可配置密码套件。
  • v3.4.21(2022-09-15):修复单节点集群的 durability API 保证;nil 日志对象 panic;成员启动时 auth 数据未加载;etcdctl move-leader 多端点失败。
  • v3.4.20(2022-08-06)
    • 新增 etcd --max-concurrent-streams:限制每个客户端并发打开的 stream 数,默认 math.MaxUint32(当前源码 server/embed/config.go 中该字段与默认值仍在,标志注册于 server/embed/config.go);
    • 新增 etcd --experimental-enable-lease-checkpoint-persist:lease checkpoint 持久化,配合修复“checkpoint 无法阻止 leader 变更后 TTL 重置”(注意:该实验特性在后续主分支中已被移除/演进,当前 main 分支源码中已搜索不到该标志,v3.4 分支行为以该版本为准);
    • rangePermCache 的读写锁使用修复;raft 层 MsgReadIndex 推迟到本 term 首次 commit 之后、空 apply 请求下重发 ReadIndex、Grant 负 ID 导致 db 失同步的防护、NOSPACE 时放行非变更请求。
    • clientv3 在 autosync 时过滤 learner 成员。

3.5 v3.4.10 ~ v3.4.19

  • v3.4.19(2022-07-12):排除同类型 alarm 被多个 peer 重复激活;Defrag 不再清空 backend 选项;从 snapshot 恢复 auth store 时 tokenProvider 未启用导致的 lease 泄漏;lease 撤销的 goroutine/channel 竞态与降 leader 后仍调度 checkpoint;clientv3 修复过期 token 不刷新;bbolt v1.3.3→v1.3.6;x/cryptoyaml.v2(v2.4.0,修复 CVE-2019-11254)安全升级;Go 要求提升到 1.16+,依赖跟踪从 vendor 目录切换为 go modules(这是 3.4 线内的重要构建体系变更)。
  • v3.4.18(2021-10-15):新增 etcd_disk_defrag_inflight 指标;Docker 基础镜像升级 debian:bullseye 修复四个关键 CVE(含 glibc 整数溢出 CVE-2021-35942 等)。
  • v3.4.17(2021-10-03)etcdctl check datascale 支持 https 端点;gRPC gateway 支持 MaxCallRecvMsgSize;JWT 库从 dgrijalva/jwt-go 替换为 golang-jwt/jwt;编译 Go 1.12.17。
  • v3.4.16(2021-05-11):新增 --experimental-warning-apply-duration 使 apply 耗时阈值可配置;--unsafe-no-fsync 修复为仍会写出数据(大多数情况下避免损坏);range 响应大小日志不再 marshal,内存分配降低约 30%;health check 可按条件排除 alarm。
  • v3.4.15(2021-02-26):服务端 health check 成功日志降为 debug 级;修复 64KB websocket 通知消息上限;fileutil 的 F_OFD_ 常量修复;gorilla/websocket v1.4.2。
  • v3.4.14(2020-11-25):clientv3 修复 watch 重连后 auth token 失效(clientConn ready 时自动获取 token);修复 force-new-cluster 与 learner 并存时的 server panic;netutil 移除 DropPort/RecoverPort/SetLatency/RemoveLatency(仅旧版功能测试使用,移除以消除任意 shell 调用面);tools/etcd-dump-metrics 加入输入校验防止任意 shell 执行。
  • v3.4.13(2020-08-24):安全加固——etcd 使用已有目录且权限不符合要求时(Linux 700 / Windows 777)打 warning 日志。
  • v3.4.12(2020-08-19):修复 slow writes 告警中的 server panic。
  • v3.4.11(2020-08-18)runtime.FDUsage 调用模式优化;新增 etcd --experimental-watch-progress-notify-interval 使 watch progress 通知间隔可配置;clientv3 去除过量 watch cancel 日志;新增 os_fd_used/os_fd_limit 指标监控文件描述符。
  • v3.4.10(2020-07-16)
    • 新增 --unsafe-no-fsync:禁用所有 fsync(会丢数据),用于测试/开发时避免文件系统压力;
    • 新增 --auth-token-ttl 定制 simple token 的 TTL;
    • raft logger 的 int64 转换 panic 修复;
    • 破坏性行为:已存在的数据/证书目录会检查权限(Linux 700 / Windows 777),此前不检查。
  • v3.4.9(2020-05-20):WAL validate 补上缺失的 CRC 校验(此前缺失会导致 panic)。
  • v3.4.8(2020-05-18):snapshot 保存的 checksum 完整性校验(etcdctl 与 clientv3);snapshot 收发日志改进;修复 WAL 与服务端 snapshot 不一致——此前 server 在持久化 raft hard state 之后、保存 snapshot 之前崩溃会导致 restore 失败;auth 包修复保存 consistent index 的数据损坏 bug;clientv3 侧新增 etcd_debugging_auth_revision 指标。

3.6 v3.4.1 ~ v3.4.7

  • v3.4.7(2020-04-01):latest index 超 100 万时的 compaction 性能改进;新增 etcd_wal_write_bytes_total 指标。
  • v3.4.6(2020-03-29):修复 follower 节点的 lease 内存泄漏。
  • v3.4.5(2020-03-18):服务端记录 [CLIENT-PORT]/health 检查日志;clientv3 修复 WithRequireLeader(ctx) 覆盖已有 context key 的元数据嵌入 bug;etcdctl member add 防超时;etcd_server_client_requests_total 指标新增 typeclient_api_version 标签;gRPC proxy 修复 metrics handler 的 error panic。
  • v3.4.4(2020-02-24)
    • 修复关闭时 purge 文件循环等待的严重问题:此前 shutdown 期间可能误删所需 WAL 文件,导致启动时 etcdserver: open wal error: wal: file not found.;现在 purge 循环先于 raft 节点停止信号退出。
    • 修复 defrag 损坏 bug;learner 提升时的 quorum 保护逻辑;peer corruption checker 在 peer mTLS 下可用。
    • 新增 etcd_debugging_mvcc_total_put_size_in_bytes 指标;修复 etcd_debugging_mvcc_db_compaction_keys_total 恒为 0 的 bug。
    • auth:GRPC gateway 添加用户时的 NoPassword 检查修复;部分 auth 日志级别纠正。
  • v3.4.3(2019-10-24)etcd_cluster_version 指标只保留 major.minor。
  • v3.4.2(2019-10-11)etcdctl member add 防超时;etcdserver 的 range/put/compact 请求加入 tracing;client balancer 对多端点的 failover 修复(含 kube-apiserver 多成员 failover 证书校验、成员加入时的 IPv6 端点解析两类 k8s 相关问题)。
  • v3.4.1(2019-09-17):新增 etcd_debugging_mvcc_current_revisionetcd_debugging_mvcc_compact_revision 指标;embed.Config.ZapLoggerBuilder 支持自定义 zap logger;gRPC v1.23.0→v1.23.1。

四、安全修复的演进脉络

从 changelog 可以提取出一条清晰的安全跟进线,生产环境可按“受影响组件 → 最低修复版本”建表跟进:

修复版本 内容
v3.4.25 CVE-2021-28235:认证成功后清除密码;无密码用户仅可 CommonName 认证(v3.4.0 引入)
v3.4.22 auth 从 snapshot 恢复的数据一致性;watch invalid token/old revision 错误
v3.4.19 yaml.v2 v2.4.0(CVE-2019-11254)、x/crypto 安全升级
v3.4.30 x/crypto v0.17+(CVE-2023-48795)
v3.4.37 x/net v0.36.0(CVE-2025-22870)
v3.4.40 x/crypto 0.45.0(两个 2025 年 CVE);日志仅打印 token 指纹
v3.4.42 gRPC 1.79.3、x/net v0.51.0;服务端授权加固(两个 CVE:未认证端点绕过、嵌套事务绕过 RBAC)
v3.4.44 事务内 Put 的 PrevKv/lease 路径 RBAC 绕过修复

与之呼应的是 v3.4.0 一次性引入的防御面:--cipher-suites 密码套件白名单、--host-whitelist 防 DNS Rebinding、--cors 精确控制、TLS 1.3 版本边界(v3.4.25 的 --tls-min/max-version)。这些配置项的当前实现位置可参考 server/embed/config.go 中的标志注册段(pre-votehost-whitelistinitial-election-tick-advancemax-concurrent-streams 等均在此注册并写入启动日志 server/embed/etcd.go)。

五、数据正确性类修复专题

changelog 中高频出现的一类修复直接关系数据正确性,值得单独索引(按主题归并):

  • Compaction / revision:compaction 期间 panic 后 revision 回退(v3.4.32)、tombstone 恰为压缩 revision 时保留(v3.4.34)、compaction 后 watch 事件丢失(v3.4.31)、ErrCompacted 误报(v3.4.27)、revision 保留值解析错误(v3.4.0)。
  • Watch:未来 revision 的 watch 收到旧事件(v3.4.38)、与压缩同 revision 打开的 watch 丢 delete 事件(v3.4.36)、重复事件(v3.4.24)、网络分区后 snapshot 恢复导致 watch 响应时间倒流(v3.4.25)、mvcc unsynced watcher restore 丢事件与 restore panic(v3.4.0)。
  • Lease:单节点集群 durability 保证(v3.4.21)、follower 内存泄漏(v3.4.6)、负 ID grant 致 db 失同步(v3.4.20)、TTL 溢出防护(v3.4.0)、已吊销 lease 的 Renew 误报成功(v3.4.38)、过期 lease 未删 key(v3.4.0)。
  • 存储 / 崩溃恢复:applySnapshot 与 defragment 并发损坏(v3.4.38)、defrag 损坏与临时文件未关(v3.4.4/v3.4.35)、WAL 与服务端 snapshot 不一致致 restore 失败(v3.4.8)、WAL validate 缺 CRC 校验(v3.4.9)、shutdown 误删 WAL(v3.4.4)。
  • WAL 损坏自检:v3.4.0 引入的 Verify 函数在 server/storage/wal/wal.go 中至今仍是 etcd-dump-logs 等工具做 WAL 损坏检查的入口,与 changelog 中 v3.4.9 补 CRC 校验、v3.4.28 集群 ID 检查形成一条完整的损坏检测演进链。

六、生产版本选择与升级建议

结合 CHANGELOG/README.md 与本文的逐版本梳理:

  1. 最低生产版本:README 明确建议生产环境至少使用 v3.4.22+(以及 v3.5.6+ 线)。低于 v3.4.22 的版本存在 auth 恢复一致性、watch 错误处理等未修复问题,不应作为生产基线。
  2. 已 EOL:v3.4.45 是 v3.4 最后一个补丁版本。仍在 v3.4 的集群,升级方向是 3.5/3.6 线;若因故需要 3.4 与 3.5 混布(例如从 3.5 回滚),确保 3.4 侧不低于 v3.4.31(next-cluster-version-compatible 标志可用)并按 v3.4.32 的集群版本更新逻辑操作。
  3. 跟进补丁的判断依据:对照本文第四节的 CVE 表与第五节的正确性修复表,凡涉及“授权绕过 / 数据损坏 / restore 失败”类修复的版本都应视为强制升级点;其余依赖升级版本(如各 Compile binaries using go 1.x 条目)可结合内部 Go 工具链策略合并跟进。
  4. 升级前阅读顺序:CHANGELOG 头部指引从 CHANGELOG-3.3.md 回溯上一代变更;v3.4.0 的 breaking changes(第二节 2.8 节)必须在升级窗口内逐条核对——尤其是 etcdctl 默认 API=3、v2 store 默认关闭、/v3beta 端点、TLS 标志更名、容器 tag 规则与 Go 1.12+ 要求。
  5. 验证手段:升级后可以用 changelog 中反复出现的可观测性手段自检——etcdctl endpoint status(含 raft applied index 与 errors 字段)、/livez/readyz(v3.4.29 起)、/metricsetcd_server_is_leaderetcd_cluster_versionetcd_mvcc_db_total_size_in_bytes/etcd_mvcc_db_total_size_in_use_in_bytes(差值即 defrag 可回收量)等指标,全部来自 v3.4.0 起新增的指标体系。

七、小结

CHANGELOG/CHANGELOG-3.4.md 完整记录了 etcd 3.4 线 45 个版本、跨越 2019-08 至 2026-06 的演进:v3.4.0 以 Learner、Pre-Vote、zap 日志、watch 分片、lease checkpointing 与大规模指标体系奠定架构;中间补丁版本持续修复 compaction/watch/lease/崩溃恢复等数据正确性问题,并跟进各依赖 CVE;v3.4.45 宣告 EOL。对运维者而言,这份 changelog 的价值在于:以版本号为锚点,能快速定位“我当前版本是否包含某修复/某 CVE 补丁”,并据此决定是打补丁还是直接升级主线分支。

登录后查看全文
热门项目推荐
相关项目推荐