oldme 博客

人类能够实现飞行,并非依靠其强健体魄,而是依靠思想的力量

Docker Compose 部署 etcd 集群(详细)

oldme create: 2023-08-13

看了很多网上部署的教程,要么超级简陋,要么搞一堆配置,也不说明每项配置的作用,让人一头雾水。所以在这里写一篇详细的博客,搭建出一个具体的 etcd 集群,并介绍每项的配置作用,镜像使用的是 bitnami/etcd。

舞台环境

这是我部署时的环境列表,版本相差不大也不会有什么影响:

  • Docker v24.0.2
  • Docker Compose v2.14.2
  • 镜像 bitnami/etcd TAG:3.5

如果你还没有安装 Docker 和 Docker Compose,请先参照网上的教程安装一下。

创建以下文件夹保存 etcd 相关的文件,我这里以 /home/docker/etcd 做为教程演示:

  • 创建 /home/docker/etcd 目录,保存所有 etcd 的相关文件;
  • 创建 /home/docker/etcd/data 目录,用作数据卷映射,持久化 etcd 数据到宿主机;
  • 创建 /home/docker/etcd/docker-compose.yml,用来编写我们的部署配置。

单节点部署

单节点部署比较简单,docker-compose.yml:

version: "3.7"

services:
    etcd:
        image: "bitnami/etcd:3.5"
        container_name: "etcd"
        # 总是重启
        restart: "always"
        ports:
            - 2379:2379
        environment:
            # 时区设置
            - TZ=Asia/Shanghai
            # 允许无认证访问
            - ALLOW_NONE_AUTHENTICATION=yes
            # etcd 客户端访问URL
            - ETCD_ADVERTISE_CLIENT_URLS=http://etcd:2379
        volumes:
            # 将数据映射到宿主机
            - etcd_data:/bitnami/etcd

volumes:
    etcd_data:
        driver: local
        driver_opts:
            type: "none"
            o: "bind"
            device: "/home/docker/etcd/data"

执行 docker-compose up -d 命令,此时在浏览器访问 http://IP:2379/version,即可看到我们的版本号:

此时,数据文件也会映射到 /home/docker/etcd/data 目录下,可以自行进去查看一下。

简单使用

执行如下命令,进入 etcd 容器:

docker exec -it etcd bash

创建一个key:

etcdctl put /k v

查看一个key:

etcdctl get /k

删除一个key:

etcdctl del /k

集群部署

集群部署较之单点配置,多了很多配置,请查看 docker-compose.yml:

version: "3.7"

services:
    etcd1:
        image: "bitnami/etcd:3.5"
        container_name: "etcd1"
        restart: "always"
        ports:
            - 12379:12379
        environment:
            - TZ=Asia/Shanghai
            # 允许无认证访问
            - ALLOW_NONE_AUTHENTICATION=yes
            # 名称
            - ETCD_NAME=etcd1
            # 列出这个成员的伙伴 URL 以便通告给集群的其他成员
            - ETCD_INITIAL_ADVERTISE_PEER_URLS=http://etcd1:2380
            # 用于监听伙伴通讯的URL列表
            - ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380
            # 用于监听客户端通讯的URL列表
            - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:12379
            # 初始化集群记号,建议一个集群内的所有节点都设置唯一的token
            - ETCD_INITIAL_CLUSTER_TOKEN=MyEtcd
            # 列出这个成员的客户端URL,通告给集群中的其他成员
            - ETCD_ADVERTISE_CLIENT_URLS=http://etcd1:12379
            # 集群配置,格式是ETCD_NAME=ETCD_INITIAL_ADVERTISE_PEER_URLS
            - ETCD_INITIAL_CLUSTER=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380
            # 初始化集群状态,这里写 new 就行
            - ETCD_INITIAL_CLUSTER_STATE=new

    etcd2:
        image: "bitnami/etcd:3.5"
        container_name: "etcd2"
        restart: "always"
        ports:
            - 22379:22379
        environment:
            - TZ=Asia/Shanghai
            # 允许无认证访问
            - ALLOW_NONE_AUTHENTICATION=yes
             # 名称
            - ETCD_NAME=etcd2
            # 列出这个成员的伙伴 URL 以便通告给集群的其他成员
            - ETCD_INITIAL_ADVERTISE_PEER_URLS=http://etcd2:2380
            # 用于监听伙伴通讯的URL列表
            - ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380
            # 用于监听客户端通讯的URL列表
            - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:22379
            # 初始化集群记号,建议一个集群内的所有节点都设置唯一的token
            - ETCD_INITIAL_CLUSTER_TOKEN=MyEtcd
            # 列出这个成员的客户端URL,通告给集群中的其他成员
            - ETCD_ADVERTISE_CLIENT_URLS=http://etcd2:22379
            # 集群配置,格式是ETCD_NAME=ETCD_INITIAL_ADVERTISE_PEER_URLS
            - ETCD_INITIAL_CLUSTER=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380
            # 初始化集群状态,这里写 new 就行
            - ETCD_INITIAL_CLUSTER_STATE=new

    etcd3:
        image: "bitnami/etcd:3.5"
        container_name: "etcd3"
        restart: "always"
        ports:
            - 32379:32379
        environment:
            - TZ=Asia/Shanghai
            # 允许无认证访问
            - ALLOW_NONE_AUTHENTICATION=yes
             # 名称
            - ETCD_NAME=etcd3
            # 列出这个成员的伙伴 URL 以便通告给集群的其他成员
            - ETCD_INITIAL_ADVERTISE_PEER_URLS=http://etcd3:2380
            # 用于监听伙伴通讯的URL列表
            - ETCD_LISTEN_PEER_URLS=http://0.0.0.0:2380
            # 用于监听客户端通讯的URL列表
            - ETCD_LISTEN_CLIENT_URLS=http://0.0.0.0:32379
            # 初始化集群记号,建议一个集群内的所有节点都设置唯一的token
            - ETCD_INITIAL_CLUSTER_TOKEN=MyEtcd
            # 列出这个成员的客户端URL,通告给集群中的其他成员
            - ETCD_ADVERTISE_CLIENT_URLS=http://etcd3:32379
            # 集群配置,格式是ETCD_NAME=ETCD_INITIAL_ADVERTISE_PEER_URLS
            - ETCD_INITIAL_CLUSTER=etcd1=http://etcd1:2380,etcd2=http://etcd2:2380,etcd3=http://etcd3:2380
            # 初始化集群状态,这里写 new 就行
            - ETCD_INITIAL_CLUSTER_STATE=new

看到这么长的配置不要怕,它们之中大部分都是重复的,你也可以先一个不看,复制下来,跑了再说。etcd 还有很多的环境配置,可以移步官方文档查看:etcd 配置手册

我这里没有配置数据卷映射,如果想配置,参照单节点部署即可,运行 docker-compose up -d 命令,三个节点的 etcd 集群就可以启动了,三个节点的客户端端口分别是 12379、22379、32379,可以分别在浏览器使用 http://IP:PORT 查看它们的版本号。

验证集群同步数据

随便进入一台节点容器,我这里以 etcd1 进行举例子:

docker exec -it etcd1 bash

创建一个 key:

etcdctl --endpoints=localhost:12379 put  /t v

--endpoints 用于指定节点地址,我们这里在 etcd1 节点上创建了一个key。然后试试其他节点是否能获取到信息:

etcdctl --endpoints=etcd2:22379 get /t
etcdctl --endpoints=etcd3:32379 get /t

docker 同网段的容器之间可以通过别名互相访问,所以这里直接使用 etcd2/etcd3 就可以了,结果截图:

结尾

etcd 采用 Raft 算法,Raft 要求集群中的大多数节点(即超过半数)都同意一个数据更新才能被提交,并且不会被回滚或覆盖。如果 etcd 挂掉的节点数量小于集群总数的一半,那么 etcd 集群仍然可以继续工作。所以 etcd 一般使用奇数个节点,其他基于 Raft 算法的也一样。

评论

欢迎您的回复 取消回复

您的邮箱不会显示出来,*必填

本文目录