Docker Etcd 部署指南
本文介绍如何使用 Docker 和 Docker Compose 部署 Etcd 分布式键值存储系统。Etcd 是一个高可用的分布式键值存储,常用于服务发现、配置管理和分布式协调。
📋 前置要求
- Docker 20.10+ 已安装
- Docker Compose V2 已安装(推荐)或 Docker Compose V1
- 如需使用 Docker Swarm,需要初始化 Swarm 集群
🚀 快速部署(单节点)
1. 克隆项目(如果使用项目模板)
1 2
| git clone https://github.com/noahzaozao/docker-etcd.git cd docker-etcd
|
2. 配置环境变量
1 2
| cp .env-trunk .env vi .env
|
编辑 .env 文件,设置 Etcd IP 地址:
3. 创建数据目录
4. 使用 Docker Compose 部署
1 2 3 4 5
| docker compose up -d
docker-compose up -d
|
5. 验证部署
1 2 3 4 5
| docker compose ps
docker compose exec etcd etcdctl --endpoints=http://127.0.0.1:2379 version
|
📝 Docker Compose 配置示例
单节点配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| version: '3.8'
services: etcd: container_name: etcd image: quay.io/coreos/etcd:v3.5.9 environment: ETCD_NAME: etcd-node ETCD_DATA_DIR: /default.etcd ETCD_ADVERTISE_CLIENT_URLS: "http://${ETCD_IP:-127.0.0.1}:2379" ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379" ETCD_INITIAL_ADVERTISE_PEER_URLS: "http://${ETCD_IP:-127.0.0.1}:2380" ETCD_LISTEN_PEER_URLS: "http://0.0.0.0:2380" ETCD_INITIAL_CLUSTER_TOKEN: etcd-cluster-1 ETCD_INITIAL_CLUSTER: etcd-node=http://${ETCD_IP:-127.0.0.1}:2380 ETCD_INITIAL_CLUSTER_STATE: new ETCDCTL_API: "3" volumes: - ./default.etcd:/default.etcd ports: - "2379:2379" - "2380:2380" restart: unless-stopped healthcheck: test: ["CMD", "etcdctl", "--endpoints=http://localhost:2379", "endpoint", "health"] interval: 30s timeout: 10s retries: 3
|
三节点集群配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
| version: '3.8'
services: etcd0: image: quay.io/coreos/etcd:v3.5.9 container_name: etcd0 environment: ETCD_NAME: etcd0 ETCD_DATA_DIR: /default.etcd ETCD_ADVERTISE_CLIENT_URLS: "http://etcd0:2379" ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379" ETCD_INITIAL_ADVERTISE_PEER_URLS: "http://etcd0:2380" ETCD_LISTEN_PEER_URLS: "http://0.0.0.0:2380" ETCD_INITIAL_CLUSTER: "etcd0=http://etcd0:2380,etcd1=http://etcd1:2380,etcd2=http://etcd2:2380" ETCD_INITIAL_CLUSTER_TOKEN: etcd-cluster-1 ETCD_INITIAL_CLUSTER_STATE: new ETCDCTL_API: "3" volumes: - etcd0_data:/default.etcd networks: - etcd_network
etcd1: image: quay.io/coreos/etcd:v3.5.9 container_name: etcd1 environment: ETCD_NAME: etcd1 ETCD_DATA_DIR: /default.etcd ETCD_ADVERTISE_CLIENT_URLS: "http://etcd1:2379" ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379" ETCD_INITIAL_ADVERTISE_PEER_URLS: "http://etcd1:2380" ETCD_LISTEN_PEER_URLS: "http://0.0.0.0:2380" ETCD_INITIAL_CLUSTER: "etcd0=http://etcd0:2380,etcd1=http://etcd1:2380,etcd2=http://etcd2:2380" ETCD_INITIAL_CLUSTER_TOKEN: etcd-cluster-1 ETCD_INITIAL_CLUSTER_STATE: new ETCDCTL_API: "3" volumes: - etcd1_data:/default.etcd networks: - etcd_network
etcd2: image: quay.io/coreos/etcd:v3.5.9 container_name: etcd2 environment: ETCD_NAME: etcd2 ETCD_DATA_DIR: /default.etcd ETCD_ADVERTISE_CLIENT_URLS: "http://etcd2:2379" ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379" ETCD_INITIAL_ADVERTISE_PEER_URLS: "http://etcd2:2380" ETCD_LISTEN_PEER_URLS: "http://0.0.0.0:2380" ETCD_INITIAL_CLUSTER: "etcd0=http://etcd0:2380,etcd1=http://etcd1:2380,etcd2=http://etcd2:2380" ETCD_INITIAL_CLUSTER_TOKEN: etcd-cluster-1 ETCD_INITIAL_CLUSTER_STATE: new ETCDCTL_API: "3" volumes: - etcd2_data:/default.etcd networks: - etcd_network
volumes: etcd0_data: etcd1_data: etcd2_data:
networks: etcd_network: driver: bridge
|
生产环境配置(带认证)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| version: '3.8'
services: etcd: container_name: etcd image: quay.io/coreos/etcd:v3.5.9 environment: ETCD_NAME: etcd-node ETCD_DATA_DIR: /default.etcd ETCD_ADVERTISE_CLIENT_URLS: "http://${ETCD_IP:-127.0.0.1}:2379" ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379" ETCD_INITIAL_ADVERTISE_PEER_URLS: "http://${ETCD_IP:-127.0.0.1}:2380" ETCD_LISTEN_PEER_URLS: "http://0.0.0.0:2380" ETCD_INITIAL_CLUSTER_TOKEN: etcd-cluster-1 ETCD_INITIAL_CLUSTER: etcd-node=http://${ETCD_IP:-127.0.0.1}:2380 ETCD_INITIAL_CLUSTER_STATE: new ETCDCTL_API: "3" ETCD_ROOT_PASSWORD: ${ETCD_ROOT_PASSWORD} volumes: - ./default.etcd:/default.etcd - ./certs:/etc/etcd/certs ports: - "2379:2379" - "2380:2380" restart: unless-stopped command: - /usr/local/bin/etcd - --name=etcd-node - --data-dir=/default.etcd - --advertise-client-urls=http://${ETCD_IP:-127.0.0.1}:2379 - --listen-client-urls=http://0.0.0.0:2379 - --initial-advertise-peer-urls=http://${ETCD_IP:-127.0.0.1}:2380 - --listen-peer-urls=http://0.0.0.0:2380 - --initial-cluster-token=etcd-cluster-1 - --initial-cluster=etcd-node=http://${ETCD_IP:-127.0.0.1}:2380 - --initial-cluster-state=new
|
🔧 常用操作
使用 etcdctl 操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| export ETCDCTL_API=3 export ETCDCTL_ENDPOINTS=http://127.0.0.1:2379
docker compose exec etcd etcdctl put mykey "myvalue"
docker compose exec etcd etcdctl get mykey
docker compose exec etcd etcdctl get --prefix my
docker compose exec etcd etcdctl del mykey
docker compose exec etcd etcdctl get --keys-only --prefix ""
docker compose exec etcd etcdctl member list
docker compose exec etcd etcdctl endpoint health
|
查看日志
1
| docker compose logs -f etcd
|
备份数据
1 2 3 4 5
| docker compose exec etcd etcdctl snapshot save /backup/etcd-snapshot.db
docker compose exec etcd etcdctl snapshot status /backup/etcd-snapshot.db
|
恢复数据
1 2 3 4 5 6 7 8 9
| docker compose stop etcd
docker compose exec etcd etcdctl snapshot restore /backup/etcd-snapshot.db \ --data-dir=/default.etcd
docker compose start etcd
|
🔐 安全配置建议
1. 启用认证
1 2 3 4 5 6 7 8 9 10 11 12 13
| docker compose exec etcd etcdctl user add root
docker compose exec etcd etcdctl auth enable
docker compose exec etcd etcdctl user add myuser
docker compose exec etcd etcdctl role add myrole docker compose exec etcd etcdctl role grant-permission myrole readwrite --prefix=/myapp/ docker compose exec etcd etcdctl user grant-role myuser myrole
|
2. 使用 TLS 加密
1 2 3 4 5 6 7 8 9 10 11
| command: - /usr/local/bin/etcd - --name=etcd-node - --cert-file=/etc/etcd/certs/server.crt - --key-file=/etc/etcd/certs/server.key - --trusted-ca-file=/etc/etcd/certs/ca.crt - --client-cert-auth=true - --peer-cert-file=/etc/etcd/certs/peer.crt - --peer-key-file=/etc/etcd/certs/peer.key - --peer-trusted-ca-file=/etc/etcd/certs/ca.crt - --peer-client-cert-auth=true
|
3. 限制网络访问
生产环境建议不暴露端口,或使用防火墙限制:
1 2 3 4 5 6 7
|
networks: - internal_network
|
📊 监控与维护
查看集群状态
1
| docker compose exec etcd etcdctl endpoint status --write-out=table
|
查看集群健康
1
| docker compose exec etcd etcdctl endpoint health
|
查看成员信息
1
| docker compose exec etcd etcdctl member list
|
监控指标
Etcd 在 /metrics 端点提供 Prometheus 格式的指标:
1
| curl http://127.0.0.1:2379/metrics
|
🐛 常见问题
1. 集群无法启动
- 检查
ETCD_INITIAL_CLUSTER 配置是否正确 - 确认所有节点网络连通性
- 查看日志:
docker compose logs etcd
2. 数据目录权限问题
1
| sudo chown -R 1000:1000 ./default.etcd
|
3. 端口冲突
修改 docker-compose.yml 中的端口映射:
1 2 3
| ports: - "23790:2379" - "23800:2380"
|
4. 集群分裂
如果集群出现分裂,需要重新初始化:
1 2 3 4 5 6 7 8
| docker compose down
rm -rf ./default.etcd
docker compose up -d
|
📚 参考资源