鱼喃

听!布鲁布鲁,大鱼又在那叨叨了

基于Docker Swarm搭建Zookeeper集群

前言

Zookeeper算是我基于docker搭建的第一个集群吧,当时折腾了好久,主要是网络互连的问题。经过反复测试,我发现,当且仅当两个实例分配在同一个节点上时才能互连,不同节点上的zookeeper实例无法连接。后来尝试把endpoint-mode改成dnsrr之后就又可以了(默认是vip),不知道为什么(估计在路由上有些问题)。

实例(dnsrr模式)

以组建拥有3个zookeeper节点的集群为例
三个节点的name分别是:zookeeper_node1zookeeper_node2zookeeper_node3

依次启动3个实例

1
2
3
4
5
6
7
8
docker service create \
--name zookeeper_node${i} \
--replicas 1 \
--network swarm-net \
--endpoint-mode dnsrr \
--env ZOO_MY_ID=${i} \
--env ZOO_SERVERS="server.1=zookeeper_node1:2888:3888 server.2=zookeeper_node2:2888:3888 server.3=zookeeper_node3:2888:3888" \
zookeeper:3.4

脚本里的${i}需要修改成1,2,3

完整脚本:scripts/zookeeper

检查集群是否正常建立

1
2
3
4
# 自行替换下面的容器名
docker exec -it zookeeper_node1.xxxxxxxxxxxxxx bin/zkServer.sh status # 查看 zookeeper 集群组建情况

# 如果其中有一个显示leader,其他两个显示follower即表示集群建立成功

vip模式

docker 1.13 版本开始支持指定swarm mode的hostname,尝试了一下,发现原先的脚本把hostname指定成跟name一样就可以以vip模式运行了,不得其解。

1
2
3
4
5
6
7
8
9
docker service create \
--name zookeeper_node${i} \
--hostname zookeeper_node${i} \
--replicas 1 \
--network swarm-net \
--endpoint-mode vip \
--env ZOO_MY_ID=${i} \
--env ZOO_SERVERS="server.1=zookeeper_node1:2888:3888 server.2=zookeeper_node2:2888:3888 server.3=zookeeper_node3:2888:3888" \
zookeeper:3.4

脚本里的${i}需要修改成1,2,3

完整脚本:scripts/zookeeper

持久化

建议加上持久化,docker swarm现在还不稳定,持久化数据可以保证重启后数据不会丢失

1
2
--mount type=bind,source=/data/zookeeper/data/node${i},target=/data
--mount type=bind,source=/data/zookeeper/logs/node${i},target=/datalog