尝试docker的overlay网络
文章目录
docker搭建起集群后,跨主机的容器相互之间通信就要另想方案了。幸好docker1.9之后内置了跨节点通信技术Overlay网络,这里将使用方法简单示例一下以备忘。
下面的操作还是在上周搭建的docker集群中进行,集群的搭建见这里。
解决docker集群遗留问题
上周搭建的docker集群还有一个小问题
- 每次所有docker主机再启动后,docker主机内部通信的网络接口地址有很大可能发生变化,这个会造成docker集群无法达到健康状态。搜索了下,找到一个简单办法将virtualbox创建的docker主机ip固定下来。
#ssh登入一台docker主机
docker-machine ssh node1
#创建bootsync.sh文件,里面杀死dhcp客户端进程,并静态设置docker主机ip地址,注意不同的docker主机要设置不同的IP地址
sudo echo "
if [ -f /var/run/udhcpc.eth1.pid ] ; then
kill $(more /var/run/udhcpc.eth1.pid)
fi
ifconfig eth1 192.168.99.104 netmask 255.255.255.0 broadcast 192.168.99.255 up" > /var/lib/boot2docker/bootsync.sh
#设置bootsync.sh文件可执行权限,docker主机启动时会执行该文件
chmod +x /var/lib/boot2docker/bootsync.sh
集群中所有docker主机重启一次。
- etcd服务的3个节点不能随docker主机的启动而启动。搜索了下,找一个简单办法在docker daemon启动后自动启动3个etcd容器。
sudo echo "
sleep 5
/usr/local/bin/docker start etcd1 etcd2 etcd3" > /var/lib/boot2docker/bootlocal.sh
#设置bootlocal.sh文件可执行权限,docker daemon启动后会执行该文件
chmod +x /var/lib/boot2docker/bootlocal.sh
创建overlay网络并使用它
连入docker集群
eval $(docker-machine env --swarm node1)
创建名称为ovr0的overlay网络并验证ovr0网络的信息
docker network create --driver=overlay ovr0
docker network inspect ovr0
创建两个容器试验一下
docker run -ti --rm --name alpine1 --net ovr0 alpine /bin/sh
docker run -ti --rm --name alpine2 --net ovr0 alpine /bin/sh
docker ps
...
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
137b0fa48ad9 alpine "/bin/sh" 5 seconds ago Up 4 seconds node4/alpine2
67ed2ad7d8aa alpine "/bin/sh" 9 seconds ago Up 8 seconds node3/alpine1
...
上面可以看到这两个容器是创建在node3, node4两个docker主机上的。
再验证一下ovr0网络的信息
docker network inspect ovr0
...
[
{
"Name": "ovr0",
"Id": "f86789f2d9575830b57aae8385bcd02e76b342b466c677c8aa02c2557e3eacb3",
"Scope": "global",
"Driver": "overlay",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "10.0.0.0/24",
"Gateway": "10.0.0.1/24"
}
]
},
"Internal": false,
"Containers": {
"137b0fa48ad9df084afda45fd88f3312d481dafade0cc758f177761babd5f262": {
"Name": "alpine2",
"EndpointID": "860c6930714e41ebbe03315525c8c07f67119f1ececf05f2d15c3c0da4d28d62",
"MacAddress": "02:42:0a:00:00:03",
"IPv4Address": "10.0.0.3/24",
"IPv6Address": ""
},
"67ed2ad7d8aaa1447d8e4d97782e917e544e18be283dee5c471425087d2d6639": {
"Name": "alpine1",
"EndpointID": "aa3bdff0cd7a6dc81e9df89241768b7ff21ef6b3010c96f291bd1a927e82a233",
"MacAddress": "02:42:0a:00:00:02",
"IPv4Address": "10.0.0.2/24",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
...
可以看到两个容器均接入到了ovr0这网络,ip分别是10.0.0.2与10.0.0.3。
同时在两个容器里ping对方的主机名,均可正常ping通。
ping alpine2
PING alpine2 (10.0.0.3): 56 data bytes
64 bytes from 10.0.0.3: seq=0 ttl=64 time=0.686 ms
64 bytes from 10.0.0.3: seq=1 ttl=64 time=0.677 ms
同时再检查docker集群上所有的网络,发现node3、node4两个节点上多出了两个网络node3/docker_gwbridge、node4/docker_gwbridge。初步估计是overlay网络底层实现时依赖的桥接网络。
docker network ls
NETWORK ID NAME DRIVER
72afcd321dca node1/bridge bridge
109efe6a8422 node1/host host
93162425725b node1/none null
0225062d4555 node2/bridge bridge
9889390b8909 node2/host host
cf303662cde0 node2/none null
34f56fd67dcc node3/bridge bridge
0d91c9626d8f node3/docker_gwbridge bridge
52fa10224530 node3/host host
8f3212e00813 node3/none null
c9f525cd4380 node4/bridge bridge
787ce948a501 node4/docker_gwbridge bridge
853b5214d03a node4/host host
1e1e88ef6e50 node4/none null
f86789f2d957 ovr0 overlay
另外如果想某个容器断开某网络,可执行下面的命令
docker network disconnect ovr0 alpine1
disconnect之后,容器中与这个网络相关的网络接口立马就消失了,同时在同一网络的其它的主机即不可ping通该容器主机名。
如果又想将某个容器连接某网络,可执行下面的命令
docker network connect ovr0 alpine1
connect之后,容器中将会出现与这个网络相关的网络接口,同时在同一网络的其它的主机即可ping通该容器主机名。
总结
docker的overlay网络使用起来还是比较方便的,但如果要给容器配上固定的外部访问IP还是有点麻烦,后面准备研究一下pipework的用法。
参考
http://www.alauda.cn/2016/01/18/docker-1-9-network/
https://github.com/docker/machine/issues/1709
https://github.com/boot2docker/boot2docker/blob/master/rootfs/rootfs/bootscript.sh
文章作者 Jeremy Xu
上次更新 2016-08-29
许可协议 © Copyright 2020 Jeremy Xu