在5台物理主机上的虚拟机中都装了Docker,每台中都有3个容器,现在要解决容器跨主机通信,五种方案:
一、利用OpenVSwitch
二、利用Weave
三、Docker在1.9之后支持的Overlay network(这个好像是官方的做法)
四、将多个物理机的容器组到一个物理网络来
1.创建自己的网桥br0
2.将docker默认网桥绑定到br0
五、修改主机docker默认的虚拟网段,然后在各自主机上分别把对方的docker网段加入到路由表中,配合iptables即可实现docker容器跨主机通信
跨主机容器通信大致有以下几种方式:
docker-machine version 0.5.0 (04cfa58)
docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM
官方文档的使用virtualbox进行各种角色主机的启用。本篇文档则在已有的虚拟机环境中进行。
使用docker-machine进行推送安装
首先需要拥有一台linux系统,并使docker-machine主机可以无密码访问到这台系统。
#ssh-copy-id -i /root/.ssh/id_rsa.pub root@172.25.2.43
之后即可通过docker-machine进行安装。
安装通过internet下载相关包,并通过docker-machine进行设置安装的。必须保证网络畅通,否则可能安装失败。
#docker-machine create -d generic –generic-ip-address=172.25.2.43 –generic-ssh-user=root test5
安装后,可以查看所有被docker-machine安装控制后的主机状态
NAME ACTIVE DRIVER STATE URL SWARM
c0-master - generic Running tcp://172.25.2.44:2376 c0-master (master)
c0-n1 - generic Running tcp://172.25.2.45:2376 c0-master
c0-n2 - generic Running tcp://172.25.2.46:2376 c0-master
dm01 - generic Running tcp://172.25.2.43:2376
local - generic Running tcp://172.25.2.34:2376
可以查看相应主机的环境变量
#docker-machine env local
把当前操作环境变更为指定主机
#eval “$(docker-machine env local)”
在docker-machine主机上操纵host
#docker $(docker-machine config local) run -tid ubuntu /bin/bash
通过ssh连接到相应主机
# docker-machine ssh dm01
Docker Compose安装
docker compose用于同时启动多个容器,构成同一组应用环境,在这里用于支持swarm的安装。
curl -L https://github.com/docker/comp … ose-X 10X- uname -m > /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose
Docker Swarm集群安装
启用一台主机安装key value service,用于节点、主机发现等工作。
本例使用了consul的镜像,也可以使用如etcd、zookeeper等组件。
在dm01上启动一个consul服务:
docker $(docker-machine config dm01) run -d
-p “8500:8500”
-h “consul”
progrium/consul -server -bootstrap
创建swarm集群可以通过key value服务,也可以使用swarm cluster ID字符串创建。
创建swarm manager
docker-machine create
-d generic –generic-ip-address=172.25.2.44 –generic-ssh-user=root
–swarm
–swarm-master
–swarm-discovery=”consul://$(docker-machine ip dm01):8500”
–engine-opt=”cluster-store=consul://$(docker-machine ip dm01):8500”
–engine-opt=”cluster-advertise=eth0:2376”
c0-master
创建swarm node
docker-machine create
-d generic –generic-ip-address=172.25.2.45 –generic-ssh-user=root
–swarm
–swarm-discovery=”consul://$(docker-machine ip dm01):8500”
–engine-opt=”cluster-store=consul://$(docker-machine ip dm01):8500”
–engine-opt=”cluster-advertise=eth0:2376”
c0-n1
docker-machine create
-d generic –generic-ip-address=172.25.2.46 –generic-ssh-user=root
–swarm
–swarm-discovery=”consul://$(docker-machine ip dm01):8500”
–engine-opt=”cluster-store=consul://$(docker-machine ip dm01):8500”
–engine-opt=”cluster-advertise=eth0:2376”
c0-n2
Overlay Network创建
设置环境变量
#eval “$(docker-machine env –swarm c0-master)”
可以用docker info看到现在的集群状况
#docker network create -d overlay myStack1
root@local:~# docker network ls
NETWORK ID NAME DRIVER
685ed9e9f701 myStack1 overlay
4c88e7c52a7c c0-n1/bridge bridge
7fd49a4f6a64 c0-n1/none null
8b2372139902 c0-n2/host host
d998a91dcfea c0-n2/bridge bridge
afd7a1190fb4 c0-n2/none null
0f2b5dae67f7 c0-n1/host host
a45b8049f8e6 c0-master/bridge bridge
d13eed83f250 c0-master/none null
364a592ae9ae c0-master/host host
测试
在c0-n1上启动一个nginx,并加入myStack1网络
#docker run -itd –name=web –net=myStack1 –env=”constraint:node==c0-n1” nginx
在c0-n2上启动一个shell,同样加入myStack1网络
#docker run -ti –name=webtest –net=myStack1 –env=”constraint:node==c0-n2” ubuntu /bin/bash
在shell中将可以通过容器名或ip获取到web容器的状态
{{{#apt-get install wget
wget -O- http://web }}}
docker在官方文档上主推以swarm的方式创建cluster,相对比较复杂,但提供了整体Cluster的解决方案,可以将容器进行整体管理、推送、使用。
如何使不同主机上的docker容器互相通信
docker启动时,会在宿主主机上创建一个名为docker0的虚拟网络接口,默认选择172.17.42.1/16,一个16位的子网掩码给容器提供了65534个IP地址。docker0只是一个在绑定到这上面的其他网卡间自动转发数据包的虚拟以太网桥,它可以使容器和主机相互通信,容器与容器间通信。
问题是,如何让位于不同主机上的docker容器可以通信?
最简单的思路,修改一台主机docker默认的虚拟网段,然后在各自主机上分别把对方的docker网段加入到路由表中,即可实现docker容器夸主机通信。
现有两台虚拟机
v1:192.168.124.51
v2:192.168.124.52
更改虚拟机docker0网段,修改为
v1:172.17.1.1/24
v2:172.17.2.1/24
#v1
sudo ifconfig docker0 172.17.1.1 netmask 255.255.255.0
sudo service docker restart
#v2
sudo ifconfig docker0 172.17.2.1 netmask 255.255.255.0
sudo service docker restart
然后在v1,v2上把对方的docker0网段加入到自己的路由表中
#v1
sudo route add -net 172.17.2.0 netmask 255.255.255.0 gw 192.168.124.52
sudo iptables -t nat -F POSTROUTING
sudo iptables -t nat -A POSTROUTING -s 172.17.1.0/24 ! -d 172.17.0.0/16 -j MASQUERADE
#v2
sudo route add -net 172.17.1.0 netmask 255.255.255.0 gw 192.168.124.51
sudo iptables -t nat -F POSTROUTING
sudo iptables -t nat -A POSTROUTING -s 172.17.2.0/24 ! -d 172.17.0.0/16 -j MASQUERADE
测试,v1,v2创建容器test1,test2
#v1
docker run –rm –name test1 -i -t base:latest bin/bash
docker inspect –format ‘{{.NetworkSettings.IPAddress}}’ test1
#172.17.1.1
v2
docker run –rm –name test2 -i -t base:latest bin/bash
docker inspect –format ‘{{.NetworkSettings.IPAddress}}’ test2
#172.17.2.1
主机上可以ping通对方容器ip,至此也就ok了。