2. etcd 安装与集群搭建:单节点安装、静态集群配置、动态发现、TLS 安全配置
etcd 的安装与集群搭建是分布式键值存储的基石。本章从单节点快速部署入手,逐步深入到静态集群配置、动态发现机制以及生产环境必需的 TLS 安全配置。掌握这些操作,你就能搭建一个可靠、安全的 etcd 集群,为后续的 Watch 机制优化和事务性能压测打下坚实基础。
2.1 单节点安装
单节点安装适用于开发测试环境或快速验证场景。etcd 官方提供多种安装方式,包括二进制包、源码编译和容器化部署。以下以 Linux 系统为例,展示二进制安装的完整步骤。
2.1.1 二进制安装步骤
- 下载 etcd 发布包:从 GitHub Releases 页面获取对应平台的最新稳定版本(如 v3.5.x)。
- 解压并移动二进制文件:将
etcd和etcdctl放入/usr/local/bin。 - 验证安装:运行
etcd --version确认版本信息。 - 启动单节点:直接执行
etcd命令,默认监听localhost:2379(客户端)和localhost:2380(集群通信)。
# 下载并解压
wget https://github.com/etcd-io/etcd/releases/download/v3.5.15/etcd-v3.5.15-linux-amd64.tar.gz
tar -xzf etcd-v3.5.15-linux-amd64.tar.gz
# 安装到系统路径
sudo mv etcd-v3.5.15-linux-amd64/etcd /usr/local/bin/
sudo mv etcd-v3.5.15-linux-amd64/etcdctl /usr/local/bin/
# 启动单节点
etcd --name node1 \
--initial-advertise-peer-urls http://localhost:2380 \
--listen-peer-urls http://localhost:2380 \
--listen-client-urls http://localhost:2379 \
--advertise-client-urls http://localhost:2379
--initial-cluster-state 默认为 new,无需显式指定。使用 etcdctl endpoint health 可快速验证集群健康状态。
2.2 静态集群配置
静态集群配置是最常用的生产部署方式,适用于节点 IP 和端口已知的场景。管理员在启动时通过命令行参数或配置文件指定所有集群成员信息,etcd 自动完成成员发现和 Leader 选举。
2.2.1 三节点集群示例
假设有三台服务器:192.168.1.10、192.168.1.11、192.168.1.12,每台节点启动命令如下:
# 节点 1
etcd --name infra0 \
--initial-advertise-peer-urls http://192.168.1.10:2380 \
--listen-peer-urls http://192.168.1.10:2380 \
--listen-client-urls http://192.168.1.10:2379 \
--advertise-client-urls http://192.168.1.10:2379 \
--initial-cluster- etcd-cluster-1 \
--initial-cluster infra0=http://192.168.1.10:2380,infra1=http://192.168.1.11:2380,infra2=http://192.168.1.12:2380 \
--initial-cluster-state new
# 节点 2
etcd --name infra1 \
--initial-advertise-peer-urls http://192.168.1.11:2380 \
--listen-peer-urls http://192.168.1.11:2380 \
--listen-client-urls http://192.168.1.11:2379 \
--advertise-client-urls http://192.168.1.11:2379 \
--initial-cluster- etcd-cluster-1 \
--initial-cluster infra0=http://192.168.1.10:2380,infra1=http://192.168.1.11:2380,infra2=http://192.168.1.12:2380 \
--initial-cluster-state new
# 节点 3
etcd --name infra2 \
--initial-advertise-peer-urls http://192.168.1.12:2380 \
--listen-peer-urls http://192.168.1.12:2380 \
--listen-client-urls http://192.168.1.12:2379 \
--advertise-client-urls http://192.168.1.12:2379 \
--initial-cluster- etcd-cluster-1 \
--initial-cluster infra0=http://192.168.1.10:2380,infra1=http://192.168.1.11:2380,infra2=http://192.168.1.12:2380 \
--initial-cluster-state new
--initial-cluster-:集群唯一标识,防止不同集群的节点误加入。--initial-cluster-state new:首次启动时使用new;重启已有集群时改为existing。--initial-advertise-peer-urls:节点间通信地址,必须能被其他节点访问。
2.2.2 静态配置参数对比
| 参数 | 作用 | 示例值 |
|---|---|---|
--name |
节点名称,集群内唯一 | infra0 |
--initial-advertise-peer-urls |
节点间通信的公告地址 | http://192.168.1.10:2380 |
--listen-peer-urls |
节点间通信的监听地址 | http://0.0.0.0:2380 |
--listen-client-urls |
客户端请求的监听地址 | http://0.0.0.0:2379 |
--initial-cluster |
初始集群成员列表 | infra0=http://192.168.1.10:2380,... |
2.3 动态发现
动态发现机制适用于节点 IP 不固定或需要自动扩缩容的场景。etcd 支持两种动态发现方式:etcd 发现服务和 DNS 发现。动态发现的核心思想是:先启动一个“发现端点”,其他节点通过该端点获取集群成员信息并加入。
2.3.1 使用 etcd 发现服务
首先在某个已知地址上启动一个发现服务(或使用公共发现端点),然后其他节点通过 --discovery 参数指定该端点。
# 步骤 1:在已知节点上生成发现 (仅首次)
curl https://discovery.etcd.io/new?size=3
# 返回:https://discovery.etcd.io/abc123def456
# 步骤 2:所有节点使用同一 discovery URL 启动
etcd --name node1 \
--initial-advertise-peer-urls http://192.168.1.10:2380 \
--listen-peer-urls http://0.0.0.0:2380 \
--listen-client-urls http://0.0.0.0:2379 \
--discovery https://discovery.etcd.io/abc123def456
2.3.2 DNS 发现
DNS 发现利用 SRV 记录自动解析集群成员。需要在 DNS 服务器中配置 _etcd-server._tcp.yourdomain.com 的 SRV 记录,指向各节点的 peer URL。
# DNS SRV 记录示例(BIND 格式)
_etcd-server._tcp.example.com. IN SRV 0 10 2380 node1.example.com.
_etcd-server._tcp.example.com. IN SRV 0 10 2380 node2.example.com.
_etcd-server._tcp.example.com. IN SRV 0 10 2380 node3.example.com.
# 节点启动命令(无需指定 --initial-cluster)
etcd --name node1 \
--discovery-srv example.com \
--initial-advertise-peer-urls http://node1.example.com:2380 \
--listen-peer-urls http://0.0.0.0:2380 \
--listen-client-urls http://0.0.0.0:2379
2.4 TLS 安全配置
生产环境必须启用 TLS 加密,防止中间人攻击和数据泄露。etcd 支持客户端到服务器(Client-to-Server)和节点间(Peer-to-Peer)的双向 TLS 认证。以下展示使用自签名证书的完整配置流程。
2.4.1 生成证书
使用 cfssl 或 openssl 生成 CA 证书、服务器证书和客户端证书。以 openssl 为例:
# 1. 生成 CA 私钥和证书
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -subj "/CN=etcd-ca" -days 3650 -out ca.crt
# 2. 生成服务器私钥和证书请求
openssl genrsa -out server.key 2048
openssl req -new -key server.key -subj "/CN=etcd-server" -out server.csr
# 3. 使用 CA 签发服务器证书(需配置 SAN)
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-out server.crt -days 365 -extensions v3_req \
-extfile <(printf "[v3_req]\nsubjectAltName=IP:192.168.1.10,IP:127.0.0.1")
# 4. 生成客户端证书(用于 etcdctl 连接)
openssl genrsa -out client.key 2048
openssl req -new -key client.key -subj "/CN=etcd-client" -out client.csr
openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial \
-out client.crt -days 365
2.4.2 启动 TLS 集群
将证书文件分发到各节点,启动时指定 TLS 相关参数:
etcd --name infra0 \
--initial-advertise-peer-urls https://192.168.1.10:2380 \
--listen-peer-urls https://0.0.0.0:2380 \
--listen-client-urls https://0.0.0.0:2379 \
--advertise-client-urls https://192.168.1.10:2379 \
--initial-cluster infra0=https://192.168.1.10:2380,infra1=https://192.168.1.11:2380,infra2=https://192.168.1.12:2380 \
--initial-cluster-state new \
--cert-file /etc/etcd/ssl/server.crt \
--key-file /etc/etcd/ssl/server.key \
--client-cert-auth \
--trusted-ca-file /etc/etcd/ssl/ca.crt \
--peer-cert-file /etc/etcd/ssl/server.crt \
--peer-key-file /etc/etcd/ssl/server.key \
--peer-client-cert-auth \
--peer-trusted-ca-file /etc/etcd/ssl/ca.crt
| 参数 | 用途 | 必需性 |
|---|---|---|
--cert-file |
服务器证书(客户端连接用) | 启用 HTTPS 时必需 |
--key-file |
服务器私钥 | 启用 HTTPS 时必需 |
--client-cert-auth |
启用客户端证书验证 | 推荐生产环境开启 |
--trusted-ca-file |
CA 证书,用于验证客户端 | --client-cert-auth 开启时必需 |
--peer-cert-file |
节点间通信证书 | 启用 Peer TLS 时必需 |
--peer-key-file |
节点间通信私钥 | 启用 Peer TLS 时必需 |
--peer-client-cert-auth |
节点间双向认证 | 推荐生产环境开启 |
--peer-trusted-ca-file |
节点间 CA 证书 | --peer-client-cert-auth 开启时必需 |
2.5 集群搭建流程总览
下图展示了从单节点到生产级 TLS 集群的完整搭建流程,涵盖静态配置和动态发现两种模式:
2.6 集群验证与常见问题
2.6.1 验证集群健康
集群启动后,使用 etcdctl 进行基本验证:
# 检查集群成员
etcdctl --endpoints=https://192.168.1.10:2379 \
--cacert=/etc/etcd/ssl/ca.crt \
--cert=/etc/etcd/ssl/client.crt \
--key=/etc/etcd/ssl/client.key \
member list
# 检查端点健康
etcdctl --endpoints=https://192.168.1.10:2379,https://192.168.1.11:2379,https://192.168.1.12:2379 \
--cacert=/etc/etcd/ssl/ca.crt \
--cert=/etc/etcd/ssl/client.crt \
--key=/etc/etcd/ssl/client.key \
endpoint health --cluster
# 写入和读取测试
etcdctl put /test/key "hello etcd"
etcdctl get /test/key
2.6.2 常见问题排查
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 节点无法加入集群 | --initial-cluster 配置不一致 |
确保所有节点的 --initial-cluster 参数完全一致 |
| TLS 握手失败 | 证书 CN 与 IP 不匹配 | 在证书中添加 Subject Alternative Name (SAN) |
| Leader 选举超时 | 节点间网络延迟过高 | 检查防火墙规则,确保 2380 端口互通 |
| 客户端连接被拒绝 | 客户端证书未受信任 | 将 CA 证书添加到客户端信任链 |
| 动态发现失败 | 发现服务不可达或 过期 | 检查网络连通性,重新生成 discovery |
- 始终使用 5 节点奇数集群(容忍 2 节点故障),避免脑裂风险。
- TLS 证书有效期建议不超过 1 年,并建立自动续期机制。
- 将 etcd 数据目录放在高性能 SSD 上,并定期备份
/var/lib/etcd/member/snap目录。 - 监控关键指标:Leader 变更次数、Raft 提案延迟、磁盘 fsync 耗时。