本文演示如何在docker中运行zookeeper,以及链接方式
centos7.6系统上实验,其他环境操作类似
1. 基础环境准备
已经搭建好docker环境的本章节可以跳过
docker基本使用可以参见之前的文章,此处仅简单描述安装docker过程
宿主机准备源:
# mkdir /etc/yum.repos.d/back
# mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/back
# curl http://mirrors.aliyun.com/repo/Centos-7.repo > /etc/yum.repos.d/Centos-7.repo
# curl http://mirrors.aliyun.com/repo/epel-7.repo > /etc/yum.repos.d/epel.repo
# yum makecache
安装docker并启动
# yum install docker
# systemctl start docker
# systemctl enable docker
2. 运行单实例zookeeper
2.1 启动zookeeper
启动的的时候会从公网容器中拉取zookeeper镜像,因此第一次启动需要有个下载镜像pull的过程
# docker run --name zookeeper-server --restart always -d zookeeper
8018a27ff505fa7d45219d371d1e0f5b945a4fe8a5b31325ee98b6acd5976e5b
启动后通过docker ps -a
查询状态,如果STATUS不是up,说明启动有问题,需要排查
# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8018a27ff505 zookeeper "/docker-entrypoin..." 3 seconds ago Up 2 seconds 2181/tcp, 2888/tcp, 3888/tcp, 8080/tcp zookeeper-server
参数解释:
--name : 容器取名为zookeeper-server, 此名称可以随意定义
--restart always : 定义容器的重启策略,即在容器退出时总是重启容器,如果只是实验,该参数非必须
-d : 以daemon方式运行
zookeeper : zookeeper的镜像名称,docker会到网络仓库中拉取该名称的镜像,因此不可修改
通过上述docker ps -a
可以看到该容器导出了2181/2888/3888/8080端口
2181: 客户端链接端口
2888: follower同步数据端口
3888: zookeeper选举端口
8080: 额外提供的一个restful-api的入口,可以按类似http://<zookeeper-docker-ip>:8080/commands/stat的方式执行四字命令
需要补充的是,这些端口仅暴露在容器内部,也就是仅容器之间可以访问,就是启动的其他容器可以访问
但是宿主机到容器、甚至其他节点到容器是访问不到的
可以在宿主机上通过netstat查看端口情况,正常应该看不到输出
(通过yum install net-tools
可以获得netstat命令)
# netstat -anp | grep 2181
2.2 其他容器链接zookeeper
其他容器和zookeeper因为在同一网络,因此链接zookeeper的方法本质就是要知道zookeeper容器的ip地址
可以通过2种方法获取
方法一 (官方推荐方法):
如下使用--link zookeeper-server:zk
将zookeeper-server的网络配置和环境变量共享给新启动的容器
其中zookeeper-server
为运行zookeeper服务的容器,zk
为该容器取的另外一个别名,可以随意设置
# docker run -ti --name client --link zookeeper-server:zk docker.io/centos:centos7.6.1810 /bin/bash
运行后,可以在新容器的环境变量和hosts文件中,获取和查看到zookeeper-server的地址和相关环境变量
环境变量:
[root@6e1159a751d7 /]# env | grep ^ZK
ZK_PORT_3888_TCP_ADDR=172.17.0.2
ZK_PORT_2888_TCP_ADDR=172.17.0.2
ZK_PORT_2888_TCP_PROTO=tcp
ZK_PORT_3888_TCP_PORT=3888
ZK_ENV_ZOO_DATA_DIR=/data
ZK_PORT_8080_TCP_PROTO=tcp
ZK_ENV_ZOO_INIT_LIMIT=5
ZK_ENV_ZOO_CONF_DIR=/conf
ZK_PORT_3888_TCP_PROTO=tcp
ZK_ENV_LANG=C.UTF-8
ZK_PORT=tcp://172.17.0.2:2181
ZK_PORT_8080_TCP_ADDR=172.17.0.2
ZK_ENV_ZOOCFGDIR=/conf
ZK_ENV_ZOO_STANDALONE_ENABLED=true
ZK_ENV_ZOO_AUTOPURGE_PURGEINTERVAL=0
ZK_PORT_8080_TCP=tcp://172.17.0.2:8080
ZK_PORT_2181_TCP_PORT=2181
ZK_ENV_ZOO_ADMINSERVER_ENABLED=true
ZK_PORT_2888_TCP_PORT=2888
ZK_PORT_8080_TCP_PORT=8080
ZK_PORT_2888_TCP=tcp://172.17.0.2:2888
ZK_ENV_ZOO_TICK_TIME=2000
ZK_PORT_2181_TCP_ADDR=172.17.0.2
ZK_ENV_ZOO_LOG_DIR=/logs
ZK_NAME=/client/zk
ZK_ENV_ZOO_AUTOPURGE_SNAPRETAINCOUNT=3
ZK_ENV_JAVA_HOME=/usr/local/openjdk-11
ZK_PORT_2181_TCP=tcp://172.17.0.2:2181
ZK_ENV_ZOO_DATA_LOG_DIR=/datalog
ZK_ENV_JAVA_VERSION=11.0.13
ZK_PORT_3888_TCP=tcp://172.17.0.2:3888
ZK_ENV_ZOO_SYNC_LIMIT=2
ZK_PORT_2181_TCP_PROTO=tcp
ZK_ENV_ZOO_MAX_CLIENT_CNXNS=60
hosts信息,其中可以通过zk/8018a27ff505/zookeeper-server任意名称链接到zookeeper-server
[root@6e1159a751d7 /]# cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 zk 8018a27ff505 zookeeper-server
172.17.0.3 6e1159a751d7
方法二:
在宿主机上获取zookeeper容器的ip地址,其他容器种可以通过该ip地址访问zookeeper
# docker inspect zookeeper-server | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.2",
"IPAddress": "172.17.0.2",
无论通过上述方法一、方法二,链接到zookeeper本质是获取zookeeper-server的ip地址
2.3 容器外链接zookeeper
上面链接方法仅适用于容器间访问zookeeper,但是实际部署时,可能会有业务在容器之外,就会有在容器外访问zookeeper的场景
解决方法就是端口映射或者透传宿主机地址到容器里面,
端口映射就是将宿主机的port和容器内的port做映射,然后访问宿主机的port,就可以完成和zookeeper的通信
删除原来的容器,再重新启动容器,补充--publish 2181:2181
参数,即可完成端口映射
# docker rm -f zookeeper-server
# docker run --name zookeeper-server --restart always --publish 2181:2181 -d zookeeper
0fbffd0a9f083c1eb1e6cd388599971f8c2052905e393b6e38ce1ca60d505474
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0fbffd0a9f08 zookeeper "/docker-entrypoin..." 3 seconds ago Up 2 seconds 2888/tcp, 3888/tcp, 0.0.0.0:2181->2181/tcp, 8080/tcp zookeeper-server
此时在宿主机上再通过netstat即可以看到2181端口的监听情况
# netstat -anp | grep 2181
tcp6 0 0 :::2181 :::* LISTEN 29477/docker-proxy-
# ps -elf | grep 29477
4 S root 29477 24048 0 80 0 - 50192 futex_ 16:51 ? 00:00:00 /usr/libexec/docker/docker-proxy-current -proto tcp -host-ip 0.0.0.0 -host-port 2181 -container-ip 172.17.0.2 -container-port 2181
0 R root 29613 23755 0 80 0 - 28203 - 16:52 pts/1 00:00:00 grep --color=auto 29477
也可以在宿主机上访问zookeeper-server,其他节点也可以通过宿主机ip访问容器的zookeeper
以下通过zookeeper四字命令获取zookeeper的服务状态,是在宿主机上执行(可以通过yum install nc
获取nc工具)
# echo srvr | nc 127.0.0.1 2181
Zookeeper version: 3.7.0-e3704b390a6697bfdf4b0bef79e3da7a4f6bac4b, built on 2021-03-17 09:46 UTC
Latency min/avg/max: 0/0.0/0
Received: 3
Sent: 2
Connections: 1
Outstanding: 0
Zxid: 0x0
Mode: standalone
Node count: 5
3. 运行多实例zookeeper
上述运行zookeeper是运行的standalone
模式,即单节点无冗余,实际生产部署的时候,会按照zookeper的奇数原则将容器部署在多台服务器上
此处按照zookeeper容器官网上的实例,在同一个宿主机上部署3个zookeeper容器,并且将宿主机的2181/2182/2183映射给3个zookeper容器的2181端口
# cat stack.yml
version: '3.1'
services:
zoo1:
image: zookeeper
restart: always
hostname: zoo1
ports:
- 2181:2181
environment:
ZOO_MY_ID: 1
ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
zoo2:
image: zookeeper
restart: always
hostname: zoo2
ports:
- 2182:2181
environment:
ZOO_MY_ID: 2
ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
zoo3:
image: zookeeper
restart: always
hostname: zoo3
ports:
- 2183:2181
environment:
ZOO_MY_ID: 3
ZOO_SERVERS: server.1=zoo1:2888:3888;2181 server.2=zoo2:2888:3888;2181 server.3=zoo3:2888:3888;2181
执行部署流程
# docker swarm init
# docker stack deploy -c stack.yml zookeeper
部署后结果
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
NAMES
0ae84ed27822 zookeeper@sha256:2c8c5c2db6db22184e197afde13e33dad849af90004c330f20b17282bcd5afd7 "/docker-entrypoin..." 2 seconds ago Up Less than a second 2181/tcp, 2888/tcp, 3888/tcp, 8080/tcp zookeeper_zoo3.1.8jstwsbkq591my2qe5cf6z9va
e4b0b8e2d716 zookeeper@sha256:2c8c5c2db6db22184e197afde13e33dad849af90004c330f20b17282bcd5afd7 "/docker-entrypoin..." 5 seconds ago Up 4 seconds 2181/tcp, 2888/tcp, 3888/tcp, 8080/tcp zookeeper_zoo2.1.jonbwugqcuiywkhx58bq0g0fr
31243f56dff8 zookeeper@sha256:2c8c5c2db6db22184e197afde13e33dad849af90004c330f20b17282bcd5afd7 "/docker-entrypoin..." 8 seconds ago Up 7 seconds 2181/tcp, 2888/tcp, 3888/tcp, 8080/tcp zookeeper_zoo1.1.l5yfrya1k8cdaewcb8fg5oxjo
# netstat -anp | grep 218* | grep LISTEN
tcp6 0 0 :::2183 :::* LISTEN 24048/dockerd-curre
tcp6 0 0 :::2181 :::* LISTEN 24048/dockerd-curre
tcp6 0 0 :::2182 :::* LISTEN 24048/dockerd-curre
相关参考:
https://hub.docker.com/_/zookeeper
https://www.cnblogs.com/telwanggs/p/10855665.html
https://www.jianshu.com/p/21d66ca6115e