首页
/ etcd 上手与架构导读:从单节点运行到本地三节点集群的完整实践

etcd 上手与架构导读:从单节点运行到本地三节点集群的完整实践

2026-09-06 19:39:59作者:宗隆裙

本篇基于 etcd 仓库根目录的 README 展开,覆盖 etcd 的定位与设计目标(Simple / Secure / Fast / Reliable)、获取与启动方式、官方端口约定、使用 goreman 启动本地三节点集群、Go 客户端安装,并结合仓库源码补充默认端口配置、多模块 Go 工作区结构与 robustness 测试体系。读完本文,你可以独立完成 etcd 的单节点部署、KV 读写验证和多成员集群搭建,并理解仓库各目录与模块的对应关系。

etcd 是什么:面向分布式系统关键数据的可靠键值存储

README 对 etcd 的定位是:etcd 是一个面向分布式系统最关键数据的、分布式且可靠的键值存储(key-value store),并给出四个核心设计目标:

设计目标 含义
Simple 良好定义的用户 API,基于 gRPC
Secure 自动 TLS,可选客户端证书认证
Fast 基准测试达到 10,000 writes/sec(README 原文表述)
Reliable 基于 Raft 算法正确实现分布式复制

etcd 使用 Go 编写,通过 Raft 共识算法管理一个高可用的复制日志。README 同时指出,可靠性由仓库中严格的 robustness testing 体系进一步保障——这是理解 etcd "可靠"二字的关键入口,后文会专门展开。

在生产采用方面,ADOPTERS.md 记录了 etcd 的生产用户与使用场景,其中最典型的元用户(meta user)是 Kubernetes——所有 Kubernetes 集群都使用 etcd 作为主数据存储;此外 README 还提到 etcd 常与 locksmith、vulcand、Doorman 等应用配套使用。

仓库中的用户 API 入口

README 的 Documentation 一节列出了最常用 API 的文档入口,它们与仓库目录一一对应,也是深入 etcd 代码的起点:

API 模块 仓库对应目录
go.etcd.io/etcd/api/v3 api/
go.etcd.io/etcd/client/pkg/v3 client/pkg/
go.etcd.io/etcd/client/v3 client/v3/
go.etcd.io/etcd/etcdctl/v3 etcdctl/
go.etcd.io/etcd/pkg/v3 pkg/
go.etcd.io/etcd/server/v3 server/

其中 gRPC 服务定义(KV、Lease、Watcher、Auth、Cluster、Maintenance 等 RPC)集中在 api/etcdserverpb/etcdserver.protoapi/etcdserverpb/rpc.proto,客户端代码生成物为同目录下的 *.pb.gorpc_grpc.pb.go

获取 etcd

README 推荐的获取方式是使用预构建发布二进制,官方 release 页面提供 macOS(OSX)、Linux、Windows 与 Docker 版本。注意 README 的明确提醒:main 分支在开发期间可能处于不稳定甚至损坏状态,生产请使用稳定发布版本。

如果从源码构建,仓库根目录的 Makefile 提供了入口:

make build        # 等价于执行 ./scripts/build.sh,产出 bin/etcd 等二进制
make build-all    # 交叉编译 linux/darwin/windows 的 amd64/arm64 等平台

Makefilebuild-all 明确列出的目标平台为 linux-amd64 linux-386 linux-arm linux-arm64 linux-ppc64le linux-s390x darwin-amd64 darwin-arm64 windows-amd64 windows-arm64,与发布页提供的平台范围一致。

安装 etcd client v3

对于 Go 项目,README 给出的客户端安装命令是:

go get go.etcd.io/etcd/client/v3

当前仓库根 go.mod 声明模块为 go.etcd.io/etcd/v3(Go 1.26),并在 replace 指令中把 api/v3client/v3server/v3 等所有子模块指回本地目录。这说明 etcd 采用多 Go module 工作区结构:每个子模块(api、client/pkg、client/v3、etcdctl、etcdutl、pkg、server、tests)可独立发版,根目录 go.work 将它们组织为统一工作区。对使用方而言,client/v3 模块可独立以 go.etcd.io/etcd/client/v3 引入,不影响 etcd 服务端的版本演进。

运行 etcd:单成员集群

README 的最简运行路径是直接启动一个单成员集群。若使用预构建二进制:

/tmp/etcd-download-test/etcd

若将二进制移入系统 PATH:

mv /tmp/etcd-download-test/etcd /usr/local/bin/
etcd

启动后 etcd 默认在 2379 端口监听客户端通信,在 2380 端口监听成员间(server-to-server)通信。这两个默认值并非凭空约定,源码中可以直接验证——server/embed/config.go 中定义了:

DefaultListenPeerURLs   = "http://localhost:2380"
DefaultListenClientURLs = "http://localhost:2379"

同文件第 126–127 行还定义了对应的默认 advertise URL:

DefaultInitialAdvertisePeerURLs = "http://localhost:2380"
DefaultAdvertiseClientURLs      = "http://localhost:2379"

这说明"listen"与"advertise"是成对的两组配置:listen 是本机绑定的地址,advertise 是告知集群其他成员/客户端的地址,单机默认都是 localhost,组网部署时必须分别显式指定。

写入与读取第一个键

启动后,使用随仓库提供的命令行客户端 etcdctl 完成一次 put/get 验证:

etcdctl put mykey "this is awesome"
etcdctl get mykey

etcdctl 位于 etcdctl/ 目录,命令实现按功能拆分在 etcdctl/ctlv3/command/ 下(put/get/move-leader/member 等各为独立命令文件)。至此 etcd 已在对外提供客户端服务。

etcd 的 TCP 端口约定

README 专门用一节强调:官方 etcd 端口为 2379(客户端请求)与 2380(成员间 peer 通信),并指出这是 IANA 注册的官方端口。运维规划防火墙与安全组时应围绕这两个端口展开;若启用 TLS,则对应使用 --listen-client-secure-urls / --listen-peer-secure-urls 等安全 URL 选项(见 server/embed/config.go 中的相关默认值与校验逻辑)。

使用 goreman 运行本地三节点集群

README 提供了一个开箱即用的本地集群方案:先安装 goreman(go install github.com/mattn/goreman@latest,基于 Procfile 管理多进程应用),然后执行:

goreman start

这会启动 README 所述的三个成员 infra1infra2infra3(以及可选的 etcd grpc-proxy),每个成员与代理都接受 KV 读写。具体启动参数在 Procfile 中,三个成员的关键命令行如下(以 infra1 为例,去掉 pprof/日志参数):

bin/etcd \
  --name infra1 \
  --listen-client-urls http://127.0.0.1:2379 \
  --advertise-client-urls http://127.0.0.1:2379 \
  --listen-peer-urls http://127.0.0.1:12380 \
  --initial-advertise-peer-urls http://127.0.0.1:12380 \
  --initial-cluster-token etcd-cluster-1 \
  --initial-cluster 'infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' \
  --initial-cluster-state new \
  --logger=zap --log-outputs=stderr

infra2、infra3 使用错开的端口(客户端 22379/32379,peer 22380/32380),peer 端口错开是因为三个进程运行在同一台 127.0.0.1 上。从 Procfile 可归纳出组网的关键参数语义:

参数 作用
--name 成员名,必须与 --initial-cluster 中的键一致
--listen-client-urls / --advertise-client-urls 客户端监听地址 / 向客户端通告的地址
--listen-peer-urls / --initial-advertise-peer-urls 成员间通信的监听 / 通告地址
--initial-cluster-token 集群初始 token,同一集群所有成员必须一致(此处为 etcd-cluster-1
--initial-cluster 初始成员列表,格式为 名字=peer-url,...
--initial-cluster-state new 表示创建新集群;加入已有集群时为 existing

Procfile 第 7 行还保留了被注释的 grpc-proxy 启动行(bin/etcd grpc-proxy start --endpoints=127.0.0.1:2379,... --listen-addr=127.0.0.1:23790),即 README 提到的"可选 grpc-proxy",它聚合三个成员的客户端端点并以单端点形式对外服务;该功能的实现位于 server/proxy/grpcproxy/

添加 learner 节点

README 提示"跟随 Procfile 注释添加 learner 节点",Procfile 第 9–25 行给出了完整步骤:

  1. 先用 Procfile 启动三节点集群;

  2. 以 learner 身份加入新成员:

    etcdctl member add infra4 --peer-urls="http://127.0.0.1:42380" --learner=true
    
  3. 启动该节点(注意 --initial-cluster-state existing,因为集群已存在):

    bin/etcd --name infra4 \
      --listen-client-urls http://127.0.0.1:42379 --advertise-client-urls http://127.0.0.1:42379 \
      --listen-peer-urls http://127.0.0.1:42380 --initial-advertise-peer-urls http://127.0.0.1:42380 \
      --initial-cluster-token etcd-cluster-1 \
      --initial-cluster 'infra4=http://127.0.0.1:42380,infra1=http://127.0.0.1:12380,infra2=http://127.0.0.1:22380,infra3=http://127.0.0.1:32380' \
      --initial-cluster-state existing --logger=zap --log-outputs=stderr
    
  4. 数据同步完成后,通过命令将 learner 提升为投票成员:

    etcdctl member promote <memberid>
    

learner 机制正是 etcd 安全扩容的典型流程:新成员先只读复制日志、不参与 Raft 投票,避免网络带宽未就绪的大节点拖慢选举,就绪后再"转正"。

可靠性如何被工程化验证:robustness 测试

README 称"Reliability is further ensured by rigorous robustness testing",其实现与记录都在 tests/robustness/README.md。该框架的目的是在各种故障条件下严格验证 etcd 维持 KV API 与 Watch API 的保证;框架还支持在 Antithesis 的确定性模拟环境中运行(见 tests/antithesis/)。

更具说服力的是其中的 "Robustness track record" 表格,逐条记录了被该体系发现(或拦截)的一致性缺陷,例如:

  • 高负载下崩溃导致 revision 不一致(v3.5);
  • 单节点集群崩溃丢失写(v3.4 及更早);
  • 网络分区后 watch "回到过去"(v3.4 及更早);
  • 压缩(compaction)期间 watch 丢事件、TXN 读取已压缩 revision 不一致等。

每一行都带有引入版本、发现方式(Robustness / Antithesis / 用户)与复现命令(如 make test-robustness-issue15271)。在 Makefile 中可以找到对应的 test-robustness 目标:

PASSES="robustness" ./scripts/test.sh

除 robustness 外,Makefile 还组织了完整的测试分层:test-unittest-integrationtest-e2etest-releasetest-grpcproxy-integration 等,测试代码分别位于 tests/common/tests/integration/tests/e2e/。这套分层加上 robustness 故障注入,构成了 README 中"可靠"承诺背后的工程支撑。

后续步骤与仓库导航

README 的 "Next steps" 指向完整文档、FAQ、gRPC API、多机集群、配置格式/环境变量/Flag、语言绑定与安全调优等主题。在本仓库内,你可以按以下路径继续深入:

社区方面,README 记录 etcd 维护者与贡献者每周四(美西时间 11:00)召开例会,社区会议与 issue triage 会议交替进行,议题与轮值记录在共享文档中,会议录像发布在官方渠道;维护者职责详见 OWNERSDocumentation/contributor-guide/community-membership.md

最后,README 声明 etcd 采用 Apache 2.0 许可证,细节见 LICENSE

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