searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

使用 Docker 部署 etcd(单节点与生产集群)

2026-07-13 17:03:56
1
0

etcd 是一个强一致、分布式的键值存储系统,常用于保存分布式系统的关键配置数据与服务发现信息(Kubernetes 即以其作为唯一的状态存储)。完成本教程后,您将能够:

  • 在任意一台 Linux 主机上以容器方式运行单节点 etcd 并完成读写验证;
  • 在三台主机上引导一个具备容错能力的 etcd 生产集群;
  • 对集群进行健康检查、数据持久化、快照备份与故障排查。

重要 **本教程中的命令以 etcd **v3.6.12 为例(撰写时的最新稳定版)。生产环境请务必固定到具体的版本标签(如 v3.6.12),​不要使用 latest 标签​——latest 可能指向非预期版本。


目录

  1. 先决条件
  2. 安装 Docker 引擎
  3. 准备 etcd 镜像
  4. 单节点快速入门
  5. 部署三节点生产集群
  6. 安全加固(TLS 与鉴权)
  7. 数据持久化与快照备份
  8. 故障排除
  9. 清理资源
  10. 后续步骤

1. 先决条件

在开始之前,请确认您的环境满足以下条件。

1.1 操作系统与硬件

资源 最低要求 推荐(生产)
操作系统 Ubuntu 20.04+ / CentOS 7+(含 Stream、Rocky、Alma)/ CTyunOS 同左
vCPU 2 4 及以上
内存 2 GB 8 GB 及以上
磁盘 20 GB(SSD) 50 GB 及以上(SSD/NVMe)
节点数(集群) 3(或 3 的奇数倍,如 5)

注意etcd 对磁盘 I/O 延迟非常敏感。生产环境强烈建议使用本地 SSD 或 NVMe 盘,避免使用网络存储,否则会显著拖慢写入与领导者选举。

1.2 网络与端口

端口 用途 访问范围
2379/TCP 客户端访问(client API) 仅对应用与运维网段开放
2380/TCP 集群节点间通信(peer) 仅对 etcd 集群成员开放

​请确保安全组(云平台)与主机防火墙(​ufw / firewalld)已放行上述端口,且节点间可双向通信。例如:

# Ubuntu (ufw)
sudo ufw allow 2379/tcp
sudo ufw allow 2380/tcp
​
# CentOS / CTyunOS (firewalld)
sudo firewall-cmd --permanent --add-port=2379/tcp
sudo firewall-cmd --permanent --add-port=2380/tcp
sudo firewall-cmd --reload

1.3 账户与工具

  • **拥有 **sudoroot 权限的账户;
  • 节点间时间同步(NTP/chrony),etcd 依赖一致的系统时间;
  • 三台主机之间可通过主机名或 IP 互通(部署集群时)。

2. 安装 Docker 引擎

etcd 的容器运行依赖 Docker 引擎。请根据您的操作系统选择对应章节。

2.1 Ubuntu

# 1. 更新包索引并安装依赖
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg lsb-release
​
# 2. 添加 Docker 官方 GPG 密钥
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
​
# 3. 添加 Docker 软件源
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \
  | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
​
# 4. 安装 Docker 引擎及相关组件
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io \
     docker-buildx-plugin docker-compose-plugin
​
# 5. 将当前用户加入 docker 组(免 sudo 运行 docker,需重新登录生效)
sudo usermod -aG docker $USER

2.2 CentOS / RHEL

适用于 CentOS 7/8、CentOS Stream、Rocky Linux、AlmaLinux 等 RHEL 系发行版。

# 1. 卸载可能冲突的旧版本
sudo yum remove -y docker \
    docker-client docker-client-latest \
    docker-common docker-latest docker-latest-logrotate \
    docker-logrotate docker-engine
​
# 2. 安装 yum-utils 并添加 Docker 源
sudo yum install -y yum-utils
sudo yum-config-manager \
    --add-repo https://download.docker.com/linux/centos/docker-ce.repo
​
# 3. 安装 Docker 引擎
sudo yum install -y docker-ce docker-ce-cli containerd.io \
     docker-buildx-plugin docker-compose-plugin
​
# 4. 启动并设置开机自启
sudo systemctl enable --now docker

2.3 CTyunOS

**CTyunOS(天翼云云操作系统)基于 openEuler,使用 **dnf 作为包管理器。openEuler 官方源自带 docker-engine 包,可一键安装;若需要较新的 Docker CE,则需额外配置 CentOS 8 兼容源。

方式 A:使用系统自带 docker-engine(最简单)

sudo dnf install -y docker
sudo systemctl enable --now docker

注意 **openEuler/CTyunOS 官方源提供的 **docker-engine 版本相对较旧(如 18.09)。如对功能或兼容性有更高要求,请使用方式 B。

方式 B:安装最新版 Docker CE

# 1. 若已安装 docker-engine,先卸载以避免包冲突
sudo dnf remove -y docker docker-engine
​
# 2. 安装 Docker CE
sudo dnf install -y docker-ce docker-ce-cli containerd.io \
     docker-buildx-plugin docker-compose-plugin
​
# 3. 启动并设置开机自启
sudo systemctl enable --now docker

2.4 验证安装

无论使用哪种操作系统,安装完成后均执行以下命令验证:

docker --version
docker run hello-world

**若终端出现 **Hello from Docker! 的提示信息,说明 Docker 引擎已正确安装并运行。

2.5(可选)配置镜像加速

国内从 Docker Hub 拉取镜像可能较慢,可配置镜像加速器:

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json > /dev/null <<'EOF'
{
  "registry-mirrors": ["https://<您的镜像加速器地址>"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

注意registry-mirrors 仅对 Docker Hub 生效。gcr.ioquay.io 上的 etcd 镜像若拉取缓慢或失败,可:(1) 自建 pull-through 缓存代理;(2) 使用可访问的第三方镜像源预先拉取后通过 docker save/load 传入节点;(3) 在网络可达的跳板机上拉取后传输。


3. 准备 etcd 镜像

拉取固定版本的 etcd 镜像:

docker pull quay.io/coreos/etcd:v3.6.12

注意etcd 官方提供两个内容一致的镜像仓库:

  • ​首选:​gcr.io/etcd-development/etcd
  • ​备选:​quay.io/coreos/etcd(本教程统一使用此仓库)

**二者可任选其一。请始终固定到具体的版本标签(如 **v3.6.12)。

验证镜像与内置工具:

docker run --rm quay.io/coreos/etcd:v3.6.12 /usr/local/bin/etcd --version
docker run --rm quay.io/coreos/etcd:v3.6.12 /usr/local/bin/etcdctl version

4. 单节点快速入门

本节在一台主机上部署单节点 etcd,适合学习、开发与测试。

4.1 启动容器

docker run -d \
  --name etcd \
  --restart=always \
  -p 2379:2379 \
  -p 2380:2380 \
  -v etcd-data:/etcd-data \
  quay.io/coreos/etcd:v3.6.12 \
  /usr/local/bin/etcd \
  --name etcd-single \
  --data-dir /etcd-data \
  --listen-client-urls http://0.0.0.0:2379 \
  --advertise-client-urls http://127.0.0.1:2379 \
  --listen-peer-urls http://0.0.0.0:2380 \
  --initial-advertise-peer-urls http://127.0.0.1:2380 \
  --initial-cluster etcd-single=http://127.0.0.1:2380 \
  --initial-cluster-state new \
  --initial-cluster-token etcd-single-token

参数说明:

参数 含义
--name 当前节点名称,集群内需唯一
--data-dir 数据目录(已挂载到命名卷etcd-data
--listen-client-urls 监听客户端请求的地址
--advertise-client-urls 对外通告的客户端地址(客户端据此连接)
--listen-peer-urls 监听集群伙伴请求的地址
--initial-advertise-peer-urls 对外通告的伙伴地址(其他节点据此连接)
--initial-cluster 初始集群成员列表
--initial-cluster-state new表示全新集群,existing表示加入已有集群
--initial-cluster-token 集群令牌,用于区分不同集群

4.2 验证读写

# 查看容器状态与日志
docker ps
docker logs etcd

# 查看集群成员
docker exec etcd /usr/local/bin/etcdctl \
  --endpoints=http://127.0.0.1:2379 member list

# 写入与读取一个键值
docker exec etcd /usr/local/bin/etcdctl \
  --endpoints=http://127.0.0.1:2379 put foo bar

docker exec etcd /usr/local/bin/etcdctl \
  --endpoints=http://127.0.0.1:2379 get foo

​预期输出:​put 返回 OKget 返回 foobar 两行,表示 etcd 已可正常读写。

注意​自 etcd v3.4 起,​etcdctl 默认使用 v3 API,无需再显式设置 ETCDCTL_API=3


5. 部署三节点生产集群

**生产环境应部署多节点集群以保证高可用。etcd 采用 Raft 协议,建议使用 **​3 个节点​(可容忍 1 个节点故障)或 5 个节点(可容忍 2 个故障)。本节部署一个三节点集群。

5.1 节点规划

准备三台主机,规划如下(请将 IP 替换为您的实际地址):

节点名 主机 IP 客户端端口 对等端口
etcd-1 10.0.0.11 2379 2380
etcd-2 10.0.0.12 2379 2380
etcd-3 10.0.0.13 2379 2380

重要​​多节点集群中,--advertise-client-urls--initial-advertise-peer-urls必须使用其他节点可访问的真实 IP​,不能使用 127.0.0.1,否则节点间无法建立连接。

5.2 启动节点

提示 **本节使用 **--network host 模式:容器直接使用宿主机网络栈,容器内监听地址即为宿主机地址,无需端口映射,最适合跨主机的 etcd 集群。

在节点 1(10.0.0.11)上执行:

docker run -d \
  --name etcd \
  --restart=always \
  --network host \
  -v /var/lib/etcd:/etcd-data \
  quay.io/coreos/etcd:v3.6.12 \
  /usr/local/bin/etcd \
  --name etcd-1 \
  --data-dir /etcd-data \
  --listen-client-urls http://0.0.0.0:2379 \
  --advertise-client-urls http://10.0.0.11:2379 \
  --listen-peer-urls http://0.0.0.0:2380 \
  --initial-advertise-peer-urls http://10.0.0.11:2380 \
  --initial-cluster etcd-1=http://10.0.0.11:2380,etcd-2=http://10.0.0.12:2380,etcd-3=http://10.0.0.13:2380 \
  --initial-cluster-state new \
  --initial-cluster-token etcd-prod-cluster

在节点 2(10.0.0.12)上执行:

docker run -d \
  --name etcd \
  --restart=always \
  --network host \
  -v /var/lib/etcd:/etcd-data \
  quay.io/coreos/etcd:v3.6.12 \
  /usr/local/bin/etcd \
  --name etcd-2 \
  --data-dir /etcd-data \
  --listen-client-urls http://0.0.0.0:2379 \
  --advertise-client-urls http://10.0.0.12:2379 \
  --listen-peer-urls http://0.0.0.0:2380 \
  --initial-advertise-peer-urls http://10.0.0.12:2380 \
  --initial-cluster etcd-1=http://10.0.0.11:2380,etcd-2=http://10.0.0.12:2380,etcd-3=http://10.0.0.13:2380 \
  --initial-cluster-state new \
  --initial-cluster-token etcd-prod-cluster

在节点 3(10.0.0.13)上执行:

docker run -d \
  --name etcd \
  --restart=always \
  --network host \
  -v /var/lib/etcd:/etcd-data \
  quay.io/coreos/etcd:v3.6.12 \
  /usr/local/bin/etcd \
  --name etcd-3 \
  --data-dir /etcd-data \
  --listen-client-urls http://0.0.0.0:2379 \
  --advertise-client-urls http://10.0.0.13:2379 \
  --listen-peer-urls http://0.0.0.0:2380 \
  --initial-advertise-peer-urls http://10.0.0.13:2380 \
  --initial-cluster etcd-1=http://10.0.0.11:2380,etcd-2=http://10.0.0.12:2380,etcd-3=http://10.0.0.13:2380 \
  --initial-cluster-state new \
  --initial-cluster-token etcd-prod-cluster

重要​​三台节点上的 --initial-cluster--initial-cluster-token--initial-cluster-state 必须完全一致,仅 --name 与各 advertise 地址随节点变化。三台节点需同时启动​(或在彼此 --initial-cluster-state=new 的引导窗口内启动),集群才能成功组建。

5.3 验证集群

在任意一台节点上执行:

# 查看成员列表
docker exec etcd /usr/local/bin/etcdctl \
  --endpoints=http://10.0.0.11:2379,http://10.0.0.12:2379,http://10.0.0.13:2379 \
  member list --write-out=table

# 检查各端点健康状态(应为 3 个 healthy)
docker exec etcd /usr/local/bin/etcdctl \
  --endpoints=http://10.0.0.11:2379,http://10.0.0.12:2379,http://10.0.0.13:2379 \
  endpoint health --write-out=table

# 查看端点状态(含 leader、raft term、DB 大小)
docker exec etcd /usr/local/bin/etcdctl \
  --endpoints=http://10.0.0.11:2379,http://10.0.0.12:2379,http://10.0.0.13:2379 \
  endpoint status --write-out=table

**预期 **member list 列出 3 个成员,endpoint health 全部显示 healthyendpoint status 中有且仅有一个节点标记为 true(即 leader)。

5.4 容错验证

停止某一节点(例如节点 3),观察集群是否仍可正常读写:

# 在节点 3 上停止容器
docker stop etcd

# 在节点 1 上读写,集群应仍可正常工作(容忍 1 节点故障)
docker exec etcd /usr/local/bin/etcdctl \
  --endpoints=http://10.0.0.11:2379 put ha-test ok

docker exec etcd /usr/local/bin/etcdctl \
  --endpoints=http://10.0.0.11:2379 get ha-test

验证完成后恢复节点 3:

# 在节点 3 上重新启动
docker start etcd

6. 安全加固(TLS 与鉴权)

重要默认配置下 etcd 的客户端与伙伴通信均为明文,且无鉴权。生产环境****必须启用 TLS 与访问控制,否则任何可达 2379 端口的主机都可读写您的数据。

6.1 启用 TLS

**为客户端(client)与节点间(peer)通信分别启用 TLS,需准备 CA 证书与各节点证书(证书生成属独立主题,可使用 **cfsslopenssl,本节假定证书已就绪并放置于宿主机 /etc/etcd/ssl)。

**在原有 **docker run 命令中追加挂载与以下参数:

-v /etc/etcd/ssl:/etc/etcd/ssl:ro \
  ... \
  # 客户端 TLS
  --client-cert-auth \
  --trusted-ca-file /etc/etcd/ssl/ca.pem \
  --cert-file /etc/etcd/ssl/server.pem \
  --key-file /etc/etcd/ssl/server-key.pem \
  # 节点间 TLS
  --peer-client-cert-auth \
  --peer-trusted-ca-file /etc/etcd/ssl/ca.pem \
  --peer-cert-file /etc/etcd/ssl/peer.pem \
  --peer-key-file /etc/etcd/ssl/peer-key.pem

​启用后,​etcdctl 也需携带证书:

docker exec etcd /usr/local/bin/etcdctl \
  --endpoints=https://10.0.0.11:2379 \
  --cacert /etc/etcd/ssl/ca.pem \
  --cert /etc/etcd/ssl/client.pem \
  --key /etc/etcd/ssl/client-key.pem \
  member list

6.2 启用鉴权

启用基于角色的访问控制(RBAC),创建 root 用户与角色:

# 创建 root 用户
docker exec etcd /usr/local/bin/etcdctl --endpoints=http://127.0.0.1:2379 \
  user add root

# 授予 root 角色
docker exec etcd /usr/local/bin/etcdctl --endpoints=http://127.0.0.1:2379 \
  user grant-role root root

# 启用鉴权
docker exec etcd /usr/local/bin/etcdctl --endpoints=http://127.0.0.1:2379 \
  auth enable

警告 **启用鉴权后,所有后续操作都必须携带 **--user root:<密码> 参数。请妥善保管 root 密码,丢失将导致无法管理集群。


7. 数据持久化与快照备份

7.1 持久化

  • **单节点示例已通过命名卷 **etcd-data 持久化;
  • **集群示例已将宿主机 **/var/lib/etcd 挂载到容器内,数据直接落盘宿主机。

容器删除重建后,只要挂载路径不变,数据即可恢复。

7.2 快照备份

定期对 etcd 做快照是灾难恢复的关键。在任意健康节点上执行:

# 1. 生成快照(保存到挂载目录内)
docker exec etcd /usr/local/bin/etcdctl \
  --endpoints=http://10.0.0.11:2379 \
  snapshot save /etcd-data/snapshot.db

# 2. 将快照拷贝到宿主机(建议进一步转存到对象存储)
docker cp etcd:/etcd-data/snapshot.db ./etcd-snapshot.db

# 3. 验证快照完整性
docker exec etcd /usr/local/bin/etcdctl \
  snapshot status /etcd-data/snapshot.db --write-out=table

提示 **建议将快照备份纳入定时任务(如 cron),并异地保存。从快照恢复属于独立的运维流程,可参考 etcd 官方文档的 **disaster recovery 章节。


8. 故障排除

现象 可能原因与处理
节点启动后集群一直无法选主 三节点的--initial-cluster/--initial-cluster-token不一致;或 advertise 地址不可达。请逐项核对,并确认使用的是真实可达 IP 而非127.0.0.1
节点重启后无法重新加入 首次引导后再次启动时--initial-cluster-state仍设为new。集群组建后,节点重启应使用existing
拉取镜像超时 / TLS handshake timeout gcr.io/quay.io在部分网络不可达。参见第 2.5 节「配置镜像加速」,或通过跳板机docker save/load离线传入镜像。
etcdctl报版本不匹配 宿主机安装的etcdctl与集群大版本差异过大。建议统一使用容器内自带的etcdctl(版本与集群一致)。
connection refused/ 无法访问 2379 安全组或防火墙未放行端口;或--listen-client-urls未包含0.0.0.0
写入延迟很高、频繁切主 磁盘 I/O 抖动(常见于共享/网络存储)。改用本地 SSD,并检查是否有其他 I/O 密集进程争用。

查看实时日志以辅助排查:

docker logs -f etcd

9. 清理资源

完成测试后,可按需清理。

9.1 单节点

docker rm -f etcd
docker volume rm etcd-data

9.2 集群(在三台节点上分别执行)

docker rm -f etcd
sudo rm -rf /var/lib/etcd

警告rm -rf /var/lib/etcd 会永久删除该节点的所有 etcd 数据,操作前请确认无需保留或已完成快照备份。


10. 后续步骤

  • 监控​:etcd 在 /metrics 暴露 Prometheus 指标,可接入 Prometheus + Grafana 监控领导者变更、提交延迟、DB 大小等关键指标。
  • 压缩与碎片整理​:定期执行 etcdctl compactetcdctl defrag,控制历史版本与磁盘占用。
  • 成员管理​:学习使用 member add / member remove 在线扩缩容集群。
  • 灾难恢复​:熟悉从快照恢复集群的完整流程,制定灾备预案。
  • 生产加固​:参见 etcd 官方文档的 ​hardware​、securitytuning 章节进行生产调优。

参考

0条评论
0 / 1000
Maxwell
11文章数
0粉丝数
Maxwell
11 文章 | 0 粉丝
原创

使用 Docker 部署 etcd(单节点与生产集群)

2026-07-13 17:03:56
1
0

etcd 是一个强一致、分布式的键值存储系统,常用于保存分布式系统的关键配置数据与服务发现信息(Kubernetes 即以其作为唯一的状态存储)。完成本教程后,您将能够:

  • 在任意一台 Linux 主机上以容器方式运行单节点 etcd 并完成读写验证;
  • 在三台主机上引导一个具备容错能力的 etcd 生产集群;
  • 对集群进行健康检查、数据持久化、快照备份与故障排查。

重要 **本教程中的命令以 etcd **v3.6.12 为例(撰写时的最新稳定版)。生产环境请务必固定到具体的版本标签(如 v3.6.12),​不要使用 latest 标签​——latest 可能指向非预期版本。


目录

  1. 先决条件
  2. 安装 Docker 引擎
  3. 准备 etcd 镜像
  4. 单节点快速入门
  5. 部署三节点生产集群
  6. 安全加固(TLS 与鉴权)
  7. 数据持久化与快照备份
  8. 故障排除
  9. 清理资源
  10. 后续步骤

1. 先决条件

在开始之前,请确认您的环境满足以下条件。

1.1 操作系统与硬件

资源 最低要求 推荐(生产)
操作系统 Ubuntu 20.04+ / CentOS 7+(含 Stream、Rocky、Alma)/ CTyunOS 同左
vCPU 2 4 及以上
内存 2 GB 8 GB 及以上
磁盘 20 GB(SSD) 50 GB 及以上(SSD/NVMe)
节点数(集群) 3(或 3 的奇数倍,如 5)

注意etcd 对磁盘 I/O 延迟非常敏感。生产环境强烈建议使用本地 SSD 或 NVMe 盘,避免使用网络存储,否则会显著拖慢写入与领导者选举。

1.2 网络与端口

端口 用途 访问范围
2379/TCP 客户端访问(client API) 仅对应用与运维网段开放
2380/TCP 集群节点间通信(peer) 仅对 etcd 集群成员开放

​请确保安全组(云平台)与主机防火墙(​ufw / firewalld)已放行上述端口,且节点间可双向通信。例如:

# Ubuntu (ufw)
sudo ufw allow 2379/tcp
sudo ufw allow 2380/tcp
​
# CentOS / CTyunOS (firewalld)
sudo firewall-cmd --permanent --add-port=2379/tcp
sudo firewall-cmd --permanent --add-port=2380/tcp
sudo firewall-cmd --reload

1.3 账户与工具

  • **拥有 **sudoroot 权限的账户;
  • 节点间时间同步(NTP/chrony),etcd 依赖一致的系统时间;
  • 三台主机之间可通过主机名或 IP 互通(部署集群时)。

2. 安装 Docker 引擎

etcd 的容器运行依赖 Docker 引擎。请根据您的操作系统选择对应章节。

2.1 Ubuntu

# 1. 更新包索引并安装依赖
sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg lsb-release
​
# 2. 添加 Docker 官方 GPG 密钥
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
​
# 3. 添加 Docker 软件源
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \
  | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
​
# 4. 安装 Docker 引擎及相关组件
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io \
     docker-buildx-plugin docker-compose-plugin
​
# 5. 将当前用户加入 docker 组(免 sudo 运行 docker,需重新登录生效)
sudo usermod -aG docker $USER

2.2 CentOS / RHEL

适用于 CentOS 7/8、CentOS Stream、Rocky Linux、AlmaLinux 等 RHEL 系发行版。

# 1. 卸载可能冲突的旧版本
sudo yum remove -y docker \
    docker-client docker-client-latest \
    docker-common docker-latest docker-latest-logrotate \
    docker-logrotate docker-engine
​
# 2. 安装 yum-utils 并添加 Docker 源
sudo yum install -y yum-utils
sudo yum-config-manager \
    --add-repo https://download.docker.com/linux/centos/docker-ce.repo
​
# 3. 安装 Docker 引擎
sudo yum install -y docker-ce docker-ce-cli containerd.io \
     docker-buildx-plugin docker-compose-plugin
​
# 4. 启动并设置开机自启
sudo systemctl enable --now docker

2.3 CTyunOS

**CTyunOS(天翼云云操作系统)基于 openEuler,使用 **dnf 作为包管理器。openEuler 官方源自带 docker-engine 包,可一键安装;若需要较新的 Docker CE,则需额外配置 CentOS 8 兼容源。

方式 A:使用系统自带 docker-engine(最简单)

sudo dnf install -y docker
sudo systemctl enable --now docker

注意 **openEuler/CTyunOS 官方源提供的 **docker-engine 版本相对较旧(如 18.09)。如对功能或兼容性有更高要求,请使用方式 B。

方式 B:安装最新版 Docker CE

# 1. 若已安装 docker-engine,先卸载以避免包冲突
sudo dnf remove -y docker docker-engine
​
# 2. 安装 Docker CE
sudo dnf install -y docker-ce docker-ce-cli containerd.io \
     docker-buildx-plugin docker-compose-plugin
​
# 3. 启动并设置开机自启
sudo systemctl enable --now docker

2.4 验证安装

无论使用哪种操作系统,安装完成后均执行以下命令验证:

docker --version
docker run hello-world

**若终端出现 **Hello from Docker! 的提示信息,说明 Docker 引擎已正确安装并运行。

2.5(可选)配置镜像加速

国内从 Docker Hub 拉取镜像可能较慢,可配置镜像加速器:

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json > /dev/null <<'EOF'
{
  "registry-mirrors": ["https://<您的镜像加速器地址>"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

注意registry-mirrors 仅对 Docker Hub 生效。gcr.ioquay.io 上的 etcd 镜像若拉取缓慢或失败,可:(1) 自建 pull-through 缓存代理;(2) 使用可访问的第三方镜像源预先拉取后通过 docker save/load 传入节点;(3) 在网络可达的跳板机上拉取后传输。


3. 准备 etcd 镜像

拉取固定版本的 etcd 镜像:

docker pull quay.io/coreos/etcd:v3.6.12

注意etcd 官方提供两个内容一致的镜像仓库:

  • ​首选:​gcr.io/etcd-development/etcd
  • ​备选:​quay.io/coreos/etcd(本教程统一使用此仓库)

**二者可任选其一。请始终固定到具体的版本标签(如 **v3.6.12)。

验证镜像与内置工具:

docker run --rm quay.io/coreos/etcd:v3.6.12 /usr/local/bin/etcd --version
docker run --rm quay.io/coreos/etcd:v3.6.12 /usr/local/bin/etcdctl version

4. 单节点快速入门

本节在一台主机上部署单节点 etcd,适合学习、开发与测试。

4.1 启动容器

docker run -d \
  --name etcd \
  --restart=always \
  -p 2379:2379 \
  -p 2380:2380 \
  -v etcd-data:/etcd-data \
  quay.io/coreos/etcd:v3.6.12 \
  /usr/local/bin/etcd \
  --name etcd-single \
  --data-dir /etcd-data \
  --listen-client-urls http://0.0.0.0:2379 \
  --advertise-client-urls http://127.0.0.1:2379 \
  --listen-peer-urls http://0.0.0.0:2380 \
  --initial-advertise-peer-urls http://127.0.0.1:2380 \
  --initial-cluster etcd-single=http://127.0.0.1:2380 \
  --initial-cluster-state new \
  --initial-cluster-token etcd-single-token

参数说明:

参数 含义
--name 当前节点名称,集群内需唯一
--data-dir 数据目录(已挂载到命名卷etcd-data
--listen-client-urls 监听客户端请求的地址
--advertise-client-urls 对外通告的客户端地址(客户端据此连接)
--listen-peer-urls 监听集群伙伴请求的地址
--initial-advertise-peer-urls 对外通告的伙伴地址(其他节点据此连接)
--initial-cluster 初始集群成员列表
--initial-cluster-state new表示全新集群,existing表示加入已有集群
--initial-cluster-token 集群令牌,用于区分不同集群

4.2 验证读写

# 查看容器状态与日志
docker ps
docker logs etcd

# 查看集群成员
docker exec etcd /usr/local/bin/etcdctl \
  --endpoints=http://127.0.0.1:2379 member list

# 写入与读取一个键值
docker exec etcd /usr/local/bin/etcdctl \
  --endpoints=http://127.0.0.1:2379 put foo bar

docker exec etcd /usr/local/bin/etcdctl \
  --endpoints=http://127.0.0.1:2379 get foo

​预期输出:​put 返回 OKget 返回 foobar 两行,表示 etcd 已可正常读写。

注意​自 etcd v3.4 起,​etcdctl 默认使用 v3 API,无需再显式设置 ETCDCTL_API=3


5. 部署三节点生产集群

**生产环境应部署多节点集群以保证高可用。etcd 采用 Raft 协议,建议使用 **​3 个节点​(可容忍 1 个节点故障)或 5 个节点(可容忍 2 个故障)。本节部署一个三节点集群。

5.1 节点规划

准备三台主机,规划如下(请将 IP 替换为您的实际地址):

节点名 主机 IP 客户端端口 对等端口
etcd-1 10.0.0.11 2379 2380
etcd-2 10.0.0.12 2379 2380
etcd-3 10.0.0.13 2379 2380

重要​​多节点集群中,--advertise-client-urls--initial-advertise-peer-urls必须使用其他节点可访问的真实 IP​,不能使用 127.0.0.1,否则节点间无法建立连接。

5.2 启动节点

提示 **本节使用 **--network host 模式:容器直接使用宿主机网络栈,容器内监听地址即为宿主机地址,无需端口映射,最适合跨主机的 etcd 集群。

在节点 1(10.0.0.11)上执行:

docker run -d \
  --name etcd \
  --restart=always \
  --network host \
  -v /var/lib/etcd:/etcd-data \
  quay.io/coreos/etcd:v3.6.12 \
  /usr/local/bin/etcd \
  --name etcd-1 \
  --data-dir /etcd-data \
  --listen-client-urls http://0.0.0.0:2379 \
  --advertise-client-urls http://10.0.0.11:2379 \
  --listen-peer-urls http://0.0.0.0:2380 \
  --initial-advertise-peer-urls http://10.0.0.11:2380 \
  --initial-cluster etcd-1=http://10.0.0.11:2380,etcd-2=http://10.0.0.12:2380,etcd-3=http://10.0.0.13:2380 \
  --initial-cluster-state new \
  --initial-cluster-token etcd-prod-cluster

在节点 2(10.0.0.12)上执行:

docker run -d \
  --name etcd \
  --restart=always \
  --network host \
  -v /var/lib/etcd:/etcd-data \
  quay.io/coreos/etcd:v3.6.12 \
  /usr/local/bin/etcd \
  --name etcd-2 \
  --data-dir /etcd-data \
  --listen-client-urls http://0.0.0.0:2379 \
  --advertise-client-urls http://10.0.0.12:2379 \
  --listen-peer-urls http://0.0.0.0:2380 \
  --initial-advertise-peer-urls http://10.0.0.12:2380 \
  --initial-cluster etcd-1=http://10.0.0.11:2380,etcd-2=http://10.0.0.12:2380,etcd-3=http://10.0.0.13:2380 \
  --initial-cluster-state new \
  --initial-cluster-token etcd-prod-cluster

在节点 3(10.0.0.13)上执行:

docker run -d \
  --name etcd \
  --restart=always \
  --network host \
  -v /var/lib/etcd:/etcd-data \
  quay.io/coreos/etcd:v3.6.12 \
  /usr/local/bin/etcd \
  --name etcd-3 \
  --data-dir /etcd-data \
  --listen-client-urls http://0.0.0.0:2379 \
  --advertise-client-urls http://10.0.0.13:2379 \
  --listen-peer-urls http://0.0.0.0:2380 \
  --initial-advertise-peer-urls http://10.0.0.13:2380 \
  --initial-cluster etcd-1=http://10.0.0.11:2380,etcd-2=http://10.0.0.12:2380,etcd-3=http://10.0.0.13:2380 \
  --initial-cluster-state new \
  --initial-cluster-token etcd-prod-cluster

重要​​三台节点上的 --initial-cluster--initial-cluster-token--initial-cluster-state 必须完全一致,仅 --name 与各 advertise 地址随节点变化。三台节点需同时启动​(或在彼此 --initial-cluster-state=new 的引导窗口内启动),集群才能成功组建。

5.3 验证集群

在任意一台节点上执行:

# 查看成员列表
docker exec etcd /usr/local/bin/etcdctl \
  --endpoints=http://10.0.0.11:2379,http://10.0.0.12:2379,http://10.0.0.13:2379 \
  member list --write-out=table

# 检查各端点健康状态(应为 3 个 healthy)
docker exec etcd /usr/local/bin/etcdctl \
  --endpoints=http://10.0.0.11:2379,http://10.0.0.12:2379,http://10.0.0.13:2379 \
  endpoint health --write-out=table

# 查看端点状态(含 leader、raft term、DB 大小)
docker exec etcd /usr/local/bin/etcdctl \
  --endpoints=http://10.0.0.11:2379,http://10.0.0.12:2379,http://10.0.0.13:2379 \
  endpoint status --write-out=table

**预期 **member list 列出 3 个成员,endpoint health 全部显示 healthyendpoint status 中有且仅有一个节点标记为 true(即 leader)。

5.4 容错验证

停止某一节点(例如节点 3),观察集群是否仍可正常读写:

# 在节点 3 上停止容器
docker stop etcd

# 在节点 1 上读写,集群应仍可正常工作(容忍 1 节点故障)
docker exec etcd /usr/local/bin/etcdctl \
  --endpoints=http://10.0.0.11:2379 put ha-test ok

docker exec etcd /usr/local/bin/etcdctl \
  --endpoints=http://10.0.0.11:2379 get ha-test

验证完成后恢复节点 3:

# 在节点 3 上重新启动
docker start etcd

6. 安全加固(TLS 与鉴权)

重要默认配置下 etcd 的客户端与伙伴通信均为明文,且无鉴权。生产环境****必须启用 TLS 与访问控制,否则任何可达 2379 端口的主机都可读写您的数据。

6.1 启用 TLS

**为客户端(client)与节点间(peer)通信分别启用 TLS,需准备 CA 证书与各节点证书(证书生成属独立主题,可使用 **cfsslopenssl,本节假定证书已就绪并放置于宿主机 /etc/etcd/ssl)。

**在原有 **docker run 命令中追加挂载与以下参数:

-v /etc/etcd/ssl:/etc/etcd/ssl:ro \
  ... \
  # 客户端 TLS
  --client-cert-auth \
  --trusted-ca-file /etc/etcd/ssl/ca.pem \
  --cert-file /etc/etcd/ssl/server.pem \
  --key-file /etc/etcd/ssl/server-key.pem \
  # 节点间 TLS
  --peer-client-cert-auth \
  --peer-trusted-ca-file /etc/etcd/ssl/ca.pem \
  --peer-cert-file /etc/etcd/ssl/peer.pem \
  --peer-key-file /etc/etcd/ssl/peer-key.pem

​启用后,​etcdctl 也需携带证书:

docker exec etcd /usr/local/bin/etcdctl \
  --endpoints=https://10.0.0.11:2379 \
  --cacert /etc/etcd/ssl/ca.pem \
  --cert /etc/etcd/ssl/client.pem \
  --key /etc/etcd/ssl/client-key.pem \
  member list

6.2 启用鉴权

启用基于角色的访问控制(RBAC),创建 root 用户与角色:

# 创建 root 用户
docker exec etcd /usr/local/bin/etcdctl --endpoints=http://127.0.0.1:2379 \
  user add root

# 授予 root 角色
docker exec etcd /usr/local/bin/etcdctl --endpoints=http://127.0.0.1:2379 \
  user grant-role root root

# 启用鉴权
docker exec etcd /usr/local/bin/etcdctl --endpoints=http://127.0.0.1:2379 \
  auth enable

警告 **启用鉴权后,所有后续操作都必须携带 **--user root:<密码> 参数。请妥善保管 root 密码,丢失将导致无法管理集群。


7. 数据持久化与快照备份

7.1 持久化

  • **单节点示例已通过命名卷 **etcd-data 持久化;
  • **集群示例已将宿主机 **/var/lib/etcd 挂载到容器内,数据直接落盘宿主机。

容器删除重建后,只要挂载路径不变,数据即可恢复。

7.2 快照备份

定期对 etcd 做快照是灾难恢复的关键。在任意健康节点上执行:

# 1. 生成快照(保存到挂载目录内)
docker exec etcd /usr/local/bin/etcdctl \
  --endpoints=http://10.0.0.11:2379 \
  snapshot save /etcd-data/snapshot.db

# 2. 将快照拷贝到宿主机(建议进一步转存到对象存储)
docker cp etcd:/etcd-data/snapshot.db ./etcd-snapshot.db

# 3. 验证快照完整性
docker exec etcd /usr/local/bin/etcdctl \
  snapshot status /etcd-data/snapshot.db --write-out=table

提示 **建议将快照备份纳入定时任务(如 cron),并异地保存。从快照恢复属于独立的运维流程,可参考 etcd 官方文档的 **disaster recovery 章节。


8. 故障排除

现象 可能原因与处理
节点启动后集群一直无法选主 三节点的--initial-cluster/--initial-cluster-token不一致;或 advertise 地址不可达。请逐项核对,并确认使用的是真实可达 IP 而非127.0.0.1
节点重启后无法重新加入 首次引导后再次启动时--initial-cluster-state仍设为new。集群组建后,节点重启应使用existing
拉取镜像超时 / TLS handshake timeout gcr.io/quay.io在部分网络不可达。参见第 2.5 节「配置镜像加速」,或通过跳板机docker save/load离线传入镜像。
etcdctl报版本不匹配 宿主机安装的etcdctl与集群大版本差异过大。建议统一使用容器内自带的etcdctl(版本与集群一致)。
connection refused/ 无法访问 2379 安全组或防火墙未放行端口;或--listen-client-urls未包含0.0.0.0
写入延迟很高、频繁切主 磁盘 I/O 抖动(常见于共享/网络存储)。改用本地 SSD,并检查是否有其他 I/O 密集进程争用。

查看实时日志以辅助排查:

docker logs -f etcd

9. 清理资源

完成测试后,可按需清理。

9.1 单节点

docker rm -f etcd
docker volume rm etcd-data

9.2 集群(在三台节点上分别执行)

docker rm -f etcd
sudo rm -rf /var/lib/etcd

警告rm -rf /var/lib/etcd 会永久删除该节点的所有 etcd 数据,操作前请确认无需保留或已完成快照备份。


10. 后续步骤

  • 监控​:etcd 在 /metrics 暴露 Prometheus 指标,可接入 Prometheus + Grafana 监控领导者变更、提交延迟、DB 大小等关键指标。
  • 压缩与碎片整理​:定期执行 etcdctl compactetcdctl defrag,控制历史版本与磁盘占用。
  • 成员管理​:学习使用 member add / member remove 在线扩缩容集群。
  • 灾难恢复​:熟悉从快照恢复集群的完整流程,制定灾备预案。
  • 生产加固​:参见 etcd 官方文档的 ​hardware​、securitytuning 章节进行生产调优。

参考

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0