几乎现在大部分的分布式中间件都需要使用zk作为协调者,所以在我们搭建各种中间件的时候难免需要额外搭建一个zk集群。通过docker compose可以很方便的搭建一个少量zk节点的zk集群。
一、基本工作
环境:centos7
![c561520b48b46492ac028e6436aa8a39.png](https://img-blog.csdnimg.cn/img_convert/c561520b48b46492ac028e6436aa8a39.png)
目录结构:
![2b11a4d3fdb2295472e5832af56dc153.png](https://img-blog.csdnimg.cn/img_convert/2b11a4d3fdb2295472e5832af56dc153.png)
docker-compose.yml是docker编排文件,一般情况下这个yml文件的文件名是默认的,即约定先行与配置,当然也可以指定为其他名称。
zk1、zk2、zk3为与docker-compose.yml文件同级的三个文件夹,用来存放不同zk实例与docker container的挂载路径
![038dcbcad72a8449f802356690a2433f.png](https://img-blog.csdnimg.cn/img_convert/038dcbcad72a8449f802356690a2433f.png)
二、docker-compose.yml
version: '3.7'
# 给zk集群配置一个网络,网络名为zk-net
networks:
zk-net:
name: zk-net
# 配置zk集群的
# container services下的每一个子配置都对应一个zk节点的docker container
services:
zk1:
# docker container所使用的docker image
image: zookeeper
hostname: zk1
container_name: zk1
# 配置docker container和宿主机的端口映射
ports:
- 2181:2181
- 8081:8080
# 配置docker container的环境变量
environment:
# 当前zk实例的id
ZOO_MY_ID: 1
# 整个zk集群的机器、端口列表
ZOO_SERVERS: server.1=0.0.0.0:2888:3888;2181 server.2=zk2:2888:3888;2181 server.3=zk3:2888:3888;2181
# 将docker container上的路径挂载到宿主机上 实现宿主机和docker container的数据共享
volumes:
- ./zk1/data:/data
- ./zk1/datalog:/datalog
# 当前docker container加入名为zk-net的隔离网络
networks:
- zk-net
zk2:
image: zookeeper
hostname: zk2
container_name: zk2
ports:
- 2182:2181
- 8082:8080
environment:
ZOO_MY_ID: 2
ZOO_SERVERS: server.1=zk1:2888:3888;2181 server.2=0.0.0.0:2888:3888;2181 server.3=zk3:2888:3888;2181
volumes:
- ./zk2/data:/data
- ./zk2/datalog:/datalog
networks:
- zk-net
zk3:
image: zookeeper
hostname: zk3
container_name: zk3
ports:
- 2183:2181
- 8083:8080
environment:
ZOO_MY_ID: 3
ZOO_SERVERS: server.1=zk1:2888:3888;2181 server.2=zk2:2888:3888;2181 server.3=0.0.0.0:2888:3888;2181
volumes:
- ./zk3/data:/data
- ./zk3/datalog:/datalog
networks:
- zk-net
简单来说下上面这个配置
1、网络配置
顶级的networks标签指定创建了一个标识为zk-net的隔离网络,并且给该网络命名为zk-net。虽然这里将标识和命名都设置为zk-net,但其实他们是不同的配置:
网络标志符是为了配置docker container属于某个网络的标志,而命名是为了开发者能够查看和区分宿主机上的所有网络环境,便于了解宿主机上的系统运行情况
docker network ls 查看宿主机上所有网络
![1477233b8feedd8432cf25de84d3151d.png](https://img-blog.csdnimg.cn/img_convert/1477233b8feedd8432cf25de84d3151d.png)
services标签下的每一个子标签代表一个docker container实例,以zk1标签为例。zk1标签下的networks子标签,表示将zk1所对应的docker container加入到标识为zk-net的子网中。
我们可以通过
docker inspect zk1
来查看zk1的网络配置
![7ac8d657590053d4096f693930a2220c.png](https://img-blog.csdnimg.cn/img_convert/7ac8d657590053d4096f693930a2220c.png)
对于zk2、zk3同理:
![1077b4012ceb21dab1ac3a22b93cfd67.png](https://img-blog.csdnimg.cn/img_convert/1077b4012ceb21dab1ac3a22b93cfd67.png)
![d4ebe580e3b0822d1230db0e2f097fb2.png](https://img-blog.csdnimg.cn/img_convert/d4ebe580e3b0822d1230db0e2f097fb2.png)
可以看到zk1、zk2、zk3同属于名为zk-net的网络,该网络的网关是172.19.0.1,zk1、zk2、zk3的ip地址分别为172.190.0.2、172.190.0.3、172.190.0.4
2、环境变量
zk1、zk2、zk3标签下都有一个environment标签,该标签配置的是容器的环境变量。配置在environment标签下的环境变量最终会被添加到docker container的环境变量中,同样可以通过
docker inspect zk1
来查看zk1的所有环境变量
![13764305b8deeb1d4addb03e3df6692e.png](https://img-blog.csdnimg.cn/img_convert/13764305b8deeb1d4addb03e3df6692e.png)
Env标签下除了我们在yml文件中显式配置的环境变量以外,还有一些容器自带的环境变量,对于zookeeper的docker container来说,这两个配置的十分重要的,必须要来了解一下。
ZOO_MY_ID 表示当前zookeeper实例在zookeeper集群中的编号,范围为1-255,所以一个zk集群最多有255个节点
ZOO_SERVERS 表示当前zookeeper实例所在zookeeper集群中的所有节点的编号、端口、主机名(或IP地址)配置
Zookeeper一共需要用到三个端口:
1、2181:对client端提供服务的端口
2、3888:选举leader使用
3、2888:集群内机器通讯使用(Leader监听此端口)
三、启动容器
配置完docker-compose.yml文件之后,在其所在的目录中运行如下命令
docker-compose up -d
该命令默认会加载当前目录下的名为docker-compose.yml的文件中的配置
![f5b5a883a9c21b1f8838f2bf11212bbc.png](https://img-blog.csdnimg.cn/img_convert/f5b5a883a9c21b1f8838f2bf11212bbc.png)
容器启动成功后,可以通过下面命令查看容器状态
docker ps -a
![e4d30839af31b2b57e60e6047786cf9e.png](https://img-blog.csdnimg.cn/img_convert/e4d30839af31b2b57e60e6047786cf9e.png)
由于在配置文件中,将zk1、zk2、zk3的容器内部8080端口分别映射到了宿主机上的8081、8082、8083端口,所以我们可以在宿主机上通过浏览器访问这三个zk实例内嵌的web控制台:
http:// localhost:8081/commands
http://localhost:8082/commands
http://localhost:8083/commands
![b11f742b55c938fbfb7b66f9d0b9aefb.png](https://img-blog.csdnimg.cn/img_convert/b11f742b55c938fbfb7b66f9d0b9aefb.png)
在configuration目录下我们可以看到zk实例的基本配置信息,比如server_id、提供客户端服务的端口、数据目录、日志目录等
![0ce6bd739ad1060f918e40ff7edf135e.png](https://img-blog.csdnimg.cn/img_convert/0ce6bd739ad1060f918e40ff7edf135e.png)
在stats目录下可以看到zk实例的运行状态信息,比如节点身份、数据大小、日志大小等,
![cc1bace7fef5a1524397cc328f5245e6.png](https://img-blog.csdnimg.cn/img_convert/cc1bace7fef5a1524397cc328f5245e6.png)
![1bd64493f0a7fa15bde49e54169689d1.png](https://img-blog.csdnimg.cn/img_convert/1bd64493f0a7fa15bde49e54169689d1.png)
![43ff30f1181ccf64b0430e8423526f19.png](https://img-blog.csdnimg.cn/img_convert/43ff30f1181ccf64b0430e8423526f19.png)
通过查看三个zk实例的stats信息,可以看到zk3是整个集群的leader角色,zk1、zk2都是zk3的follower角色(zk的具体使用细节不是本文关注的重点)。