多主机通信之ZK
目前(2016.09.15)公司正在开发一个新产品,每次测试组在部署新版本时,需要先将 Linux 环境配好,卸载后又需要重新配置 Linux 环境,显然中间有很多重复性工作,所以为了加快产品版本迭代速度,减少重复性工作,我们利用Docker来做环境隔离和快速部署。 而为了测试产品性能,又须要运行在多个物理机上,那么Docker如何在多物理机间通信,就是首先要解决的问题。 上网找了很久的资料,大概有以下几种:
Swarm模式:这是官方提供的Docker集群模式,且能够跨物理机通信,使用起简单方便,先看一个简单的例子,下面的命令在Swarm集群中创建一个Service:
docker service create \
--constraint node.hostname==biyu-c3.com \
--name sys \
--replicas 1 \
--network ingress \
kxdmmr/centos6.8-ssh bash -c '/usr/sbin/sshd -D'
而我们启动自已的容器可能要加一些别的参数,比如:
docker run --privileged=true --ip 19.19.19.19
--name hostname -h hostname -p 8080:8080 -p 80:80
-v /data/hadoop-data:/data --storage-opt size=30G
-tid registry.io:5000/centos6.5
如上,其中的选项:--privileged
、--ip
在 Swarm 模式中是不提供的,目前也没有办法实现(当然你也可以自已把 Docker 重写了…),所以不得不另寻它路。
自己修改网络配置,将 Dockre 网桥与物理机设在同一网段…,这种方式一看我就头大了,非官方的,太麻烦,且没有保证。
用第三方的服务发现工具,Docker 支持的工具有:Consul、Etcd、Zookeeper,官方给了一个列子,是在一个物理机创建多个虚拟机来模拟的,跟在物理机上还是有区别的,而且官方也没有给多更多资料,只好自已摸索了,好在最终用Zookeeper解决了问题。这种方式的好处是,我们在创建和使用容器时,跟以前没有任何区别,启动容器后,各物理机上的容器可以直接通信,且可以使用以前使用的任何选项。下面我们就动手实现一下。
基本原理
原理就是在物理机上搭建 Zookeeper,然后每个机器上的 Docker daemon 进程将网络配置和每个容器的ip等信息存储到 Zookeeper,具体细节较复杂,笔者没有彻底明白。
环境描述
硬件环境 机器数量:5
100.0.8.27 node27.kxdmmr.com
100.0.8.28 node28.kxdmmr.com
100.0.8.29 node29.kxdmmr.com
100.0.8.30 node30.kxdmmr.com
100.0.8.31 node31.kxdmmr.com
系统环境 系统版本:官方 CentOS 7 内核版本:3.10.0-327.el7.x86_64
Docker 环境 Docker版本:1.12.1 基础镜像拉取地址:daocloud.io/centos:6
基础镜像系统版本:centos 6.8
开始构建
搭建ZK服务
本次我们搭建三个节点的ZK集群,分别为node27, node29, node30三台机器,从官网下载ZK到leap27,解压到 /opt/modules/
tar -zxf zookeeper-3.4.6.tar.gz -C /opt/modules/
修改ZK配置文件,如下:
cd /opt/modules/zookeeper-3.4.6/
cp conf/zoo_sample.cfg conf/zoo.cfg
vi conf/zoo.cfg
发送ZK到其它两台机器
scp -r /opt/modules/zookeeper-3.4.6/ node29:/opt/modules/
scp -r /opt/modules/zookeeper-3.4.6/ node30:/opt/modules/
为每个机器上的ZK创建myid文件,这里以node27为例
mkdir /opt/modules/zookeeper-3.4.6/data
echo 27 > /opt/modules/zookeeper-3.4.6/data/myid
启动所有ZK服务,这里为node27为例
/opt/modules/zookeeper-3.4.6/bin/zkServer.sh start
查看每个ZK服务状态
/opt/modules/zookeeper-3.4.6/bin/zkServer.sh status
修改Docker配置
打开Docker配置文件,在ExecStart=/usr/bin/dockerd后面追加内容:
--cluster-store=zk://100.0.8.27:2181,100.0.8.29:2181,100.0.8.30:2181 --cluster-advertise=100.0.8.27:2376
如下:
vi /usr/lib/systemd/system/docker.service
重启Docker
systemctl daemon-reload; systemctl restart docker
每台机器上的Docker配置均作以上修改并重启Docker服务。
创建全局网络
做完以上操作时,就可以在Docker内创建Overlay类型的网络了
docker network create --driver overlay --subnet=19.19.0.0/16 overlay
然后就可以看到多了一个Docker网络,且每台机器上都能看到
docker network ls
启动容器并测试
在node27上启动一个容器
docker run -dt --name test1.kxdmmr.com -h test1 \
--network overlay kxdmmr.io:5000/centos6.5-ks
在node28上启动一个容器
docker run -dt --name test2.kxdmmr.com -h test2 \
--network overlay kxdmmr.io:5000/centos6.5-ks
进入容器test1
docker exec -ti test1.kxdmmr.com bash ping test2.kxdmmr.com
能ping通当然就大功告成咯!!
问题总结
--bip 11.11.0.1/16
:如果 Docker 自动分配的 ip 与本机 ip 冲突,可以在配置内修改Docker默认网关
--graph=/data/docker
:修改 Docker 默认存储位置,包括镜像,容器等,在配置内加此参数