使用docker 运行etcd 单实例/集群
Posted NezhaYoung
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用docker 运行etcd 单实例/集群相关的知识,希望对你有一定的参考价值。
一. 介绍
本文描述了如何使用docker搭建etcd集群,github/etcd上有单实例etcd服务的搭建方法,包括linux,mac,docker。
在操作之前你需要安装docker
docker-compose 是可选的,如果你不想使用 docker-compose 就跳过他
二. etcd 单实例
1. 准备
a. 创建本机数据存储目录
创建本机目录,用于挂载到容器来保存etcd data
你可以更换目录位置
rm -rf /tmp/etcd/single/data
mkdir -p /tmp/etcd/single/data
mkdir -p /tmp/etcd/single/conf
b. 关闭本机 etcd 服务
没有就跳过
ubuntu
systemctl stop etcd
mac
brew services stop etcd
c.编写 etcd config
打开etcd.yml
vim /tmp/etcd/single/conf/etcd.yml
name: s1
data-dir: /etcd-data
listen-client-urls: http://0.0.0.0:2379
advertise-client-urls: http://0.0.0.0:2379
listen-peer-urls: http://0.0.0.0:2380
initial-advertise-peer-urls: http://0.0.0.0:2380
initial-cluster: s1=http://0.0.0.0:2380
initial-cluster-token: etcd-cluster-token
initial-cluster-state: new
log-level: info
logger: zap
log-outputs: stderr
config 介绍
name
节点的名字,在集群中必须唯一data-dir
存储数据的路径,注意这是容器内部路径listen-client-urls
:这个参数用于指定 etcd 服务监听客户端请求的地址和端口。客户端(如 etcdctl 命令行工具、其他使用 etcd 客户端库的应用程序)将通过这些地址与 etcd 服务进行通信,以执行各种操作,如读取、写入和修改键值对.http://127.0.0.1:2379
就只能内网访问,http://0.0.0.0:2379
则表示 etcd 服务将在所有可用的 IPv4 网络接口上监听客户端请求advertise-client-urls
:这个参数用于告知客户端和其他 etcd 成员如何访问 etcd 服务器。这些 URL 通常是可以从集群外部访问的地址。客户端和其他 etcd 服务器将使用这些地址与 etcd 服务进行通信。listen-peer-urls
:这个参数用于指定 etcd 服务监听其他 etcd 集群成员节点间通信请求的地址和端口。这个参数对于 etcd 集群的节点之间的数据同步、心跳检测和集群管理等操作至关重要。initial-advertise-peer-urls
:这个参数用于指定 etcd 服务在初始化时向其他 etcd 集群成员宣告其可用于集群间通信的地址和端口。其他 etcd 成员节点将使用这些地址与当前 etcd 服务进行通信,进行数据同步、心跳检测和集群管理等操作。initial-cluster
:这个参数用于在 etcd 集群初始化时定义集群内所有成员的列表。它是一个逗号分隔的键值对列表,键是成员的名称,值是对应的 initial-advertise-peer-urls。当一个新的 etcd 节点加入集群时,它需要知道集群内其他成员的信息,这个参数就是提供这些信息的途径。
2.下载 etcd image
docker pull gcr.io/etcd-development/etcd:v3.4.25
3. 使用 docker-compose 启动 etcd
a. 编写 docker-compose
vim ~/docker-compose.yml
version: \'3.8\'
services:
etcd-single:
image: gcr.io/etcd-development/etcd:v3.4.25
restart: on-failure
entrypoint: ["/usr/local/bin/etcd", "--config-file", "/tmp/etcd/conf/etcd.yml"]
ports:
- "2379:2379"
- "2380:2380"
environment:
ETCDCTL_API: 3
volumes:
- type: bind
source: /tmp/etcd/single/
target: /tmp/etcd
b. 参数介绍
etcd-single
: 容器名称image
: 容器使用的docker镜像restart
: 设置自动重启策略,这里是当容器退出时,只有当退出码非 0 时才重启容器。entrypoint
: 入口点(初学者很容易和 command 搞混)ports
: 将容器内端口映射到主机端口,以便从主机或外部网络访问容器中的服务environment
: 设置容器的环境变量volumes
: 在启动容器时挂载volume或绑定主机目录,这里使用bind绑定刚才创建的主机目录
c. 运行容器
# --detach 在后台运行容器
# up 启动或重启配置的所有容器
docker-compose up --detach
d. 管理容器
docker-compose的配置文件中可以定义多个容器,从而来一条命令启动/停止多个容器,通过命令最后添加容器名(刚才定义的etcd-single)可以只操作一个容器
# 查看容器状态
docker-compose ps -a
# 查看容器日志
docker-compose logs --detach
# 停止容器
docker-compose stop
# 启动停止的容器
docker-compose start
# 停止并删除容器
docker-compose down
e. 如何使用我们刚启动的 etcd
- 通过容器内部的 etcdctl 读写 etcd
# exec 命令需要指定容器名,也就是etcd-single
# 容器名后面参数是在容器内部执行的命令
docker-compose exec etcd-single etcdctl get foo
- 通过本机etcdctl
# 因为我们将容器端口映射到主机端口上,并且是 etcd 默认端口
# 所以我们可以像使用本地服务一样使用 etcd 容器
# 当然前提是你本机已经安装了 etcdctl
# 设置请求版本
export ETCDCTL_API=3
etcdctl put foo bar
etcdctl get foo
- 远程访问本机
添加参数--endpoints=[127.0.0.1:2379]
,
如果你没有外网 ip 就只能在局域网使用局域网 ip 访问,
否则可以在任意位置通过 ip:port 访问
4. 使用 docker run 启动 etcd
a. 运行容器
这条命令与编写docker-compose.yml 没有区别
docker run \\
-d \\
-p 2379:2379 \\
-p 2380:2380 \\
-e ETCDCTL_API=3 \\
--mount type=bind,source=/tmp/etcd/single,destination=/tmp/etcd \\
--name etcd-single \\
gcr.io/etcd-development/etcd:v3.4.25 \\
/usr/local/bin/etcd \\
--config-file /tmp/etcd/conf/etcd.yml
b. 参数介绍
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
-d
后台运行容器-p
或--publish
localhost-port:cantainer-port
将容器内端口映射到主机端口,以便从主机或外部网络访问容器中的服务,--mount
在启动容器时挂载volume或绑定主机目录,这里使用bind绑定刚才创建的主机目录,--name
指定运行的容器的名称,方便管理,如果没有指定将会生成一个随机的容器名gcr.io/etcd-development/etcd:v3.4.25
要运行的容器的镜像名称- 后续参数是容器内部执行的命令,在这里是使用配置文件启动 etcd
c. 管理 etcd
# docker ps -a
# 查看日志
docker logs etcd-single
# 停止容器
docker stop etcd-single
# 启动停止的容器
docker start etcd-single
# 删除容器
docker rm etcd-single
d. 使用 etcd
使用容器内部的 etcdctl
docker exec etcd-single etcdctl put foo bar
docker exec etcd-single etcdctl get foo
其他方法和 docker-compose上的相同
三. etcd 集群
因为 etcd 使用 raft 一致性协议, 所以最少需要 3 个节点
我们将使用 docker 创建 3 个 etcd 节点在本机搭建 etcd 集群
1. 准备
a. 创建数据目录与配置目录
与单节点相似
rm -rf /tmp/etcd/cluster
# node1
mkdir -p /tmp/etcd/cluster/edcd1/data
mkdir -p /tmp/etcd/cluster/edcd1/conf
# node2
mkdir -p /tmp/etcd/cluster/edcd2/data
mkdir -p /tmp/etcd/cluster/edcd2/conf
# node3
mkdir -p /tmp/etcd/cluster/edcd3/data
mkdir -p /tmp/etcd/cluster/edcd3/conf
b. 编写配置etcd config
每一个节点的 config 都类似,在这里我们之给出node1 的 config
vim /tmp/etcd/cluster/edcd1/conf/etcd.yml
# 其他node 分别将 `etcd1`改为 `etcd2`/ `etcd3`
name: etcd1
data-dir: /etcd/data
# 其他node 分别下面的将`172.25.0.101`改为`172.25.0.102`/ `172.25.0.103`
listen-client-urls: http://172.25.0.101:2379, http://127.0.0.1:2379
advertise-client-urls: http://172.25.0.101:2379
listen-peer-urls: http://172.25.0.101:2380
initial-advertise-peer-urls: http://172.25.0.101:2380
# 这里之后不需要改
initial-cluster: etcd1=http://172.25.0.101:2380,etcd2=http://172.25.0.102:2380,etcd3=http://172.25.0.103:2380
initial-cluster-token: etcd-cluster-token
initial-cluster-state: new
2. docker-compose
a. docker-compose 配置文件
version: \'3.8\'
services:
etcd-1:
image: gcr.io/etcd-development/etcd:v3.4.25
entrypoint: [ "/usr/local/bin/etcd", "--config-file", "/tmp/etcd/conf/etcd.yml" ]
ports:
- "23791:2379"
environment:
ETCDCTL_API: 3
volumes:
- type: bind
source: /tmp/etcd/cluster/etcd1
target: /tmp/etcd
networks:
etcd-net:
ipv4_address: 172.25.0.101
etcd-2:
image: gcr.io/etcd-development/etcd:v3.4.25
entrypoint: [ "/usr/local/bin/etcd", "--config-file", "/tmp/etcd/conf/etcd.yml" ]
ports:
- "23792:2379"
environment:
ETCDCTL_API: 3
volumes:
- type: bind
source: /tmp/etcd/cluster/etcd2
target: /tmp/etcd
networks:
etcd-net:
ipv4_address: 172.25.0.102
etcd-3:
image: gcr.io/etcd-development/etcd:v3.4.25
entrypoint: [ "/usr/local/bin/etcd", "--config-file", "/tmp/etcd/conf/etcd.yml" ]
ports:
- "23793:2379"
environment:
ETCDCTL_API: 3
volumes:
- type: bind
source: /tmp/etcd/cluster/etcd3
target: /tmp/etcd
networks:
etcd-net:
ipv4_address: 172.25.0.103
networks:
etcd-net:
driver: bridge
ipam:
config:
- subnet: 172.25.0.0/16
gateway: 172.25.0.1
b. 参数介绍
可以看到整体上每个容器和之前还是很相似的,只是做出了一点点修改
- 最外层
networks
等同于docker network create etcdnet --subnet 172.25.0.0/16
- 容器内部
networks
然后我们在容器内使用该 network 并给每个容器分配一个 ipv4 地址 ports
: 如果是使用其他Linux系统的用户则不必配置这个端口映射,Linxu系统会自动帮我们处理好ip之间的互通(宿主机和各个容器之间)。而Mac想要直接访问容器的ip,则需要曲线救国,通过搭建一个vpn服务,然后通过vpn再去和容器的网段互联。
c. 运行并使用etcd cluster
大致操作和单节点etcd 相同
只是在本机访问etcd容器时需要指定--endpoints=
ubuntu
etcdctl --endpoints="172.25.0.101:2379" put foo bar
etcdctl --endpoints="172.25.0.101:2379" get foo
mac(可以看其他,配置成功后就可以使用上面的命令直接访问 etcd cluster)
etcdctl --endpoints="127.0.0.1:23791" put foo bar
etcdctl --endpoints="127.0.0.1:23791" get foo
四. 其他
1. mac 下主机不能直接访问容器 ip
在 Mac 主机上,Docker 通过使用名为 "Docker Desktop" 的虚拟化技术实现。由于这种虚拟化方法的限制,主机到容器子网的网络访问与 Linux 主机上的 Docker 有所不同。
a. 解决方法1, 使用端口映射
在 docker-compose.yml 中使用ports
将容器内部端口映射到主机端口上,
注意,一个端口只能映射一个容器,所以我们使用23791,23792,23793
也就是我们目前使用的方法
b. 使用 vpn
参考
使用docker创建etcd集群
chat-gpt4
ETCD:在容器中运行etcd集群
原文地址:Docker container
以下指南显示了如何使用静态引导过程在rkt和Docker上运行etcd。
rkt
运行单节点的etcd
以下rkt run命令将在端口2379上公开etcd客户端API,并在端口2380上公开对等API。
配置etcd时使用主机IP地址。
export NODE1=192.168.1.21
信任CoreOS App签名密钥。
sudo rkt trust --prefix quay.io/coreos/etcd
# gpg key fingerprint is: 18AD 5014 C99E F7E3 BA5F 6CE9 50BD D3E0 FC8A 365E
运行etcd v3.2版本或指定其他发行版本。
sudo rkt run --net=default:IP=${NODE1} quay.io/coreos/etcd:v3.2 -- -name=node1 -advertise-client-urls=http://${NODE1}:2379 -initial-advertise-peer-urls=http://${NODE1}:2380 -listen-client-urls=http://0.0.0.0:2379 -listen-peer-urls=http://${NODE1}:2380 -initial-cluster=node1=http://${NODE1}:2380
列出集群成员:
etcdctl --endpoints=http://192.168.1.21:2379 member list
运行3个节点的etcd
使用-initial-cluster
参数在本地使用rkt设置3节点集群。
export NODE1=172.16.28.21
export NODE2=172.16.28.22
export NODE3=172.16.28.23
# node 1
sudo rkt run --net=default:IP=${NODE1} quay.io/coreos/etcd:v3.2 -- -name=node1 -advertise-client-urls=http://${NODE1}:2379 -initial-advertise-peer-urls=http://${NODE1}:2380 -listen-client-urls=http://0.0.0.0:2379 -listen-peer-urls=http://${NODE1}:2380 -initial-cluster=node1=http://${NODE1}:2380,node2=http://${NODE2}:2380,node3=http://${NODE3}:2380
# node 2
sudo rkt run --net=default:IP=${NODE2} quay.io/coreos/etcd:v3.2 -- -name=node2 -advertise-client-urls=http://${NODE2}:2379 -initial-advertise-peer-urls=http://${NODE2}:2380 -listen-client-urls=http://0.0.0.0:2379 -listen-peer-urls=http://${NODE2}:2380 -initial-cluster=node1=http://${NODE1}:2380,node2=http://${NODE2}:2380,node3=http://${NODE3}:2380
# node 3
sudo rkt run --net=default:IP=${NODE3} quay.io/coreos/etcd:v3.2 -- -name=node3 -advertise-client-urls=http://${NODE3}:2379 -initial-advertise-peer-urls=http://${NODE3}:2380 -listen-client-urls=http://0.0.0.0:2379 -listen-peer-urls=http://${NODE3}:2380 -initial-cluster=node1=http://${NODE1}:2380,node2=http://${NODE2}:2380,node3=http://${NODE3}:2380
验证集群是否健康并且可以访问。
ETCDCTL_API=3 etcdctl --endpoints=http://172.16.28.21:2379,http://172.16.28.22:2379,http://172.16.28.23:2379 endpoint health
DNS
通过本地解析器已知的DNS名称引用对等方的生产群集必须安装主机的DNS配置。
Docker
为了向Docker主机外部的客户端公开etcd API,请使用容器的主机IP地址。 请参阅docker inspect了解有关如何获取IP地址的更多详细信息。 或者,为docker run
命令指定--net = host
标志,以跳过将容器放置在单独的网络堆栈内的操作。
运行单节点的etcd
适用主机Ip地址配置etcd:
export NODE1=192.168.1.21
配置Docker卷存储etcd数据:
docker volume create --name etcd-data
export DATA_DIR="etcd-data"
运行最新版本的etcd:
REGISTRY=quay.io/coreos/etcd
# available from v3.2.5
REGISTRY=gcr.io/etcd-development/etcd
docker run -p 2379:2379 -p 2380:2380 --volume=${DATA_DIR}:/etcd-data --name etcd ${REGISTRY}:latest /usr/local/bin/etcd --data-dir=/etcd-data --name node1 --initial-advertise-peer-urls http://${NODE1}:2380 --listen-peer-urls http://0.0.0.0:2380 --advertise-client-urls http://${NODE1}:2379 --listen-client-urls http://0.0.0.0:2379 --initial-cluster node1=http://${NODE1}:2380
列出集群成员:
etcdctl --endpoints=http://${NODE1}:2379 member list
运行3个节点的etcd
REGISTRY=quay.io/coreos/etcd
# available from v3.2.5
REGISTRY=gcr.io/etcd-development/etcd
# For each machine
ETCD_VERSION=latest
TOKEN=my-etcd-token
CLUSTER_STATE=new
NAME_1=etcd-node-0
NAME_2=etcd-node-1
NAME_3=etcd-node-2
HOST_1=10.20.30.1
HOST_2=10.20.30.2
HOST_3=10.20.30.3
CLUSTER=${NAME_1}=http://${HOST_1}:2380,${NAME_2}=http://${HOST_2}:2380,${NAME_3}=http://${HOST_3}:2380
DATA_DIR=/var/lib/etcd
# For node 1
THIS_NAME=${NAME_1}
THIS_IP=${HOST_1}
docker run -p 2379:2379 -p 2380:2380 --volume=${DATA_DIR}:/etcd-data --name etcd ${REGISTRY}:${ETCD_VERSION} /usr/local/bin/etcd --data-dir=/etcd-data --name ${THIS_NAME} --initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://0.0.0.0:2380 --advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://0.0.0.0:2379 --initial-cluster ${CLUSTER} --initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}
# For node 2
THIS_NAME=${NAME_2}
THIS_IP=${HOST_2}
docker run -p 2379:2379 -p 2380:2380 --volume=${DATA_DIR}:/etcd-data --name etcd ${REGISTRY}:${ETCD_VERSION} /usr/local/bin/etcd --data-dir=/etcd-data --name ${THIS_NAME} --initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://0.0.0.0:2380 --advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://0.0.0.0:2379 --initial-cluster ${CLUSTER} --initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}
# For node 3
THIS_NAME=${NAME_3}
THIS_IP=${HOST_3}
docker run -p 2379:2379 -p 2380:2380 --volume=${DATA_DIR}:/etcd-data --name etcd ${REGISTRY}:${ETCD_VERSION} /usr/local/bin/etcd --data-dir=/etcd-data --name ${THIS_NAME} --initial-advertise-peer-urls http://${THIS_IP}:2380 --listen-peer-urls http://0.0.0.0:2380 --advertise-client-urls http://${THIS_IP}:2379 --listen-client-urls http://0.0.0.0:2379 --initial-cluster ${CLUSTER} --initial-cluster-state ${CLUSTER_STATE} --initial-cluster-token ${TOKEN}
适用版本v3的etcdctl
:
docker exec etcd /bin/sh -c "export ETCDCTL_API=3 && /usr/local/bin/etcdctl put foo bar"
Bare Metal
要在裸机上配置3节点etcd集群,裸机存储库中的示例可能会有用。
挂载一个证书卷:
etcd发布容器不包含默认的根证书。 要将HTTPS与受根权限信任的证书一起使用(例如,用于发现),请将证书目录安装到etcd容器中:
REGISTRY=quay.io/coreos/etcd
# available from v3.2.5
REGISTRY=docker://gcr.io/etcd-development/etcd
rkt run --insecure-options=image --volume etcd-ssl-certs-bundle,kind=host,source=/etc/ssl/certs/ca-certificates.crt --mount volume=etcd-ssl-certs-bundle,target=/etc/ssl/certs/ca-certificates.crt ${REGISTRY}:latest -- --name my-name --initial-advertise-peer-urls http://localhost:2380 --listen-peer-urls http://localhost:2380 --advertise-client-urls http://localhost:2379 --listen-client-urls http://localhost:2379 --discovery https://discovery.etcd.io/c11fbcdc16972e45253491a24fcf45e1
REGISTRY=quay.io/coreos/etcd
# available from v3.2.5
REGISTRY=gcr.io/etcd-development/etcd
docker run -p 2379:2379 -p 2380:2380 --volume=/etc/ssl/certs/ca-certificates.crt:/etc/ssl/certs/ca-certificates.crt ${REGISTRY}:latest /usr/local/bin/etcd --name my-name --initial-advertise-peer-urls http://localhost:2380 --listen-peer-urls http://localhost:2380 --advertise-client-urls http://localhost:2379 --listen-client-urls http://localhost:2379 --discovery https://discovery.etcd.io/86a9ff6c8cb8b4c4544c1a2f88f8b801
以上是关于使用docker 运行etcd 单实例/集群的主要内容,如果未能解决你的问题,请参考以下文章