使用weave实现跨主机容器连接
Weave是由weaveworks公司开发的解决Docker跨主机网络的解决方案,它能够创建一个虚拟网络,用于连接多台主机上的Docker容器,这样容器就像被接入了同一个网络交换机,那些使用网络的应用程序不必去配置端口映射和链接等信息。
外部设备能够访问Weave网络上的应用程序容器所提供的服务,同时已有的内部系统也能够暴露到应用程序容器上。Weave能够穿透防火墙并运行在部分连接的网络上,另外,Weave的通信支持加密,所以用户可以从一个不受信任的网络连接到主机。
Weave会在主机上创建一个网桥,每一个容器通过 veth pair 连接到该网桥上,同时网桥上有个 Weave router 的容器与之连接,该router会通过连接在网桥上的接口来抓取网络包(该接口工作在Promiscuous模式)。
在每一个部署Docker的主机(可能是物理机也可能是虚拟机)上都部署有一个W(即Weave router),它本身也可以以一个容器的形式部署。Weave run的时候就可以给每个veth的容器端分配一个ip和相应的掩码。veth的网桥这端就是Weave router容器,并在Weave launch的时候分配好ip和掩码。
Weave网络是由这些weave routers组成的对等端点(peer)构成,每个对等的一端都有自己的名字,其中包括一个可读性好的名字用于表示状态和日志的输出,一个唯一标识符用于运行中相互区别,即使重启Docker主机名字也保持不变,这些名字默认是mac地址。
每个部署了Weave router的主机都需要将TCP和UDP的6783端口的防火墙设置打开,保证Weave router之间控制面流量和数据面流量的通过。控制面由weave routers之间建立的TCP连接构成,通过它进行握手和拓扑关系信息的交换通信。 这个通信可以被配置为加密通信。而数据面由Weave routers之间建立的UDP连接构成,这些连接大部分都会加密。这些连接都是全双工的,并且可以穿越防火墙。
对每一个weave网络中的容器,weave都会创建一个网桥,并且在网桥和每个容器之间创建一个veth pair,一端作为容器网卡加入到容器的网络命名空间中,并为容器网卡配置ip和相应的掩码,一端连接在网桥上,最终通过宿主机上weave router将流量转发到对端主机上。
其基本过程如下:
1,容器流量通过veth pair到达宿主机上weave router网桥上。
2,weave router在混杂模式下使用pcap在网桥上截获网络数据包,并排除由内核直接通过网桥转发的数据流量,例如本子网内部,本地容器之间的数据以及宿主机和本地容器之间的流量。捕获的包通过UDP转发到所其他主机的weave router端。
3,在接收端,weave router通过pcap将包注入到网桥上的接口,通过网桥的上的veth pair,将流量分发到容器的网卡上。
weave默认基于UDP承载容器之间的数据包,并且可以完全自定义整个集群的网络拓扑,但从性能和使用角度来看,还是有比较大的缺陷的:
weave自定义容器数据包的封包解包方式,不够通用,传输效率比较低,性能上的损失也比较大。
集群配置比较负载,需要通过weave命令行来手工构建网络拓扑,在大规模集群的情况下,加重了管理员的负担。
Weave优劣势:
- Weave优势
- 支持主机间通信加密。
- 支持container动态加入或者剥离网络。
- 支持跨主机多子网通信。
- Weave劣势
只能通过weave launch或者weave connect加入weave网络。
配置操作
- 安装weave
- 启动weave(veave launch)
- 连接不同主机
- 通过weave启动主机
下载安装weave
[root@localhost docker]# curl -L git.io/weave -o /usr/bin/weave
[root@localhost docker]# chmod a+x /usr/bin/weave
[root@localhost docker]# weave version
weave script 2.3.0
weave 2.3.0
启动weave,weave默认不会下载对应容器,初次运行时会下载容器。
[root@localhost docker]# weave launch
2.3.0: Pulling from weaveworks/weave
88286f41530e: Pull complete
ad4e50ed2c08: Pull complete
b3f4c952e7c2: Pull complete
5e27cb7f1c2b: Pull complete
f9dfb03c1d7b: Pull complete
Digest: sha256:02914df933ffd52c6daf8c4ced33e48dad36e4d4fd9e684d5004cd72236ced60
Status: Downloaded newer image for weaveworks/weave:2.3.0
latest: Pulling from weaveworks/weavedb
ecb15a45f93b: Pull complete
Digest: sha256:7fac063be31d48980361b7020d39ff91493c0bc6c844314b3e71f447bc8dff39
Status: Downloaded newer image for weaveworks/weavedb:latest
Unable to find image 'weaveworks/weaveexec:2.3.0' locally
2.3.0: Pulling from weaveworks/weaveexec
88286f41530e: Already exists
ad4e50ed2c08: Already exists
b3f4c952e7c2: Already exists
5e27cb7f1c2b: Already exists
f9dfb03c1d7b: Already exists
21771db04786: Pull complete
5fbda086495f: Pull complete
80427f885b22: Pull complete
0c4698905755: Pull complete
Digest: sha256:eb8eb1d83fc58716b20621d397d63737a18f86cbed1fedb1d71671cfc486517b
Status: Downloaded newer image for weaveworks/weaveexec:2.3.0
afe02ac7b3654226a09328c8688c8c3e5b6e4226d600dd6120c955ba90537e54
[root@localhost docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
afe02ac7b365 weaveworks/weave:2.3.0 "/home/weave/weave..." 2 minutes ago Up 2 minutes weave
[root@localhost docker]# docker images |grep weave
weaveworks/weavedb latest b5c2d24a7b71 6 weeks ago 282 B
weaveworks/weaveexec 2.3.0 c2030610fb92 6 weeks ago 79.1 MB
weaveworks/weave 2.3.0 6b9ea60b76e7 6 weeks ago 61.7 MB
运行结束后,会生成一个运行的容器和两个data-only的容器,和三个镜像
[root@localhost backup]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
afe02ac7b365 weaveworks/weave:2.3.0 "/home/weave/weave..." 13 minutes ago Up 13 minutes weave
c42cc69d7cf2 weaveworks/weaveexec:2.3.0 "data-only" 13 minutes ago Created weavevolumes-2.3.0
7ce56150aa56 weaveworks/weavedb:latest "data-only" 13 minutes ago Created weavedb
其中,weave的这些数据是保存在每台机器上分配的名为 weavedb 的容器上的,它是一个 data volume 容器,只负责数据的持久化。
还会生成一个名为weave的虚拟网络设备
[root@localhost backup]# ifconfig weave
weave: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1376
inet6 fe80::5cec:96ff:fe30:6abc prefixlen 64 scopeid 0x20<link>
ether 5e:ec:96:30:6a:bc txqueuelen 1000 (Ethernet)
RX packets 14 bytes 920 (920.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 8 bytes 648 (648.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
docker中也会生成一个使用weave的网桥的自定义网络。
[root@localhost backup]# docker network ls
NETWORK ID NAME DRIVER SCOPE
f6bdadf61ce7 bridge bridge local
1239bac87642 host host local
c0c6d15cdc49 none null local
37c69c2e8a78 weave weavemesh local
使用weave启动一个镜像
weave2.0之后删除了run命令,所以先使用docker run启动好容器,然后使用weave attach命令给容器绑定IP地址
配置宿主机1的容器:
[root@localhost system]# docker run -it --name weave_test ubuntu /bin/bash
[root@localhost system]# weave attach 172.25.11.23/24 weave_test
Address 172.25.11.23 overlaps with existing route 172.25.11.0/24 on host
172.25.11.23
[root@localhost system]# docker exec -it weave_test /bin/bash
//可以看到weave添加了一个网络设备,并绑定了ip地址
root@273bba12b3b9:/# ifconfig ethwe
ethwe Link encap:Ethernet HWaddr fe:11:53:ea:3e:ba
inet addr:172.25.11.23 Bcast:172.25.11.255 Mask:255.255.255.0
inet6 addr: fe80::fc11:53ff:feea:3eba/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1376 Metric:1
RX packets:12 errors:0 dropped:0 overruns:0 frame:0
TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:948 (948.0 B) TX bytes:300 (300.0 B)
配置宿主机2的容器:
[root@localhost volumes]# docker run -it --name weave_another ubuntu /bin/bash
[root@localhost volumes]# weave attach 172.25.11.112/24 weave_another
Address 172.25.11.112 overlaps with existing route 172.25.11.0/24 on host
172.25.11.112
root@44028ad4bdc2:/# ifconfig ethwe
ethwe Link encap:Ethernet HWaddr 86:ba:c8:b9:cc:eb
inet addr:172.25.11.112 Bcast:172.25.11.255 Mask:255.255.255.0
inet6 addr: fe80::84ba:c8ff:feb9:cceb/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1376 Metric:1
RX packets:12 errors:0 dropped:0 overruns:0 frame:0
TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:948 (948.0 B) TX bytes:300 (300.0 B)
宿主机1的容器weave_test和宿主机2的容器weave_another可以互相访问,验证如下:
//使用宿主机2的容器对宿主机1的容器进行ping访问
root@44028ad4bdc2:/# ping 172.25.11.23
PING 172.25.11.23 (172.25.11.23) 56(84) bytes of data.
64 bytes from 172.25.11.23: icmp_seq=1 ttl=64 time=0.077 ms
^C
--- 172.25.11.23 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.077/0.077/0.077/0.000 ms
//同样,使用宿主机1的容器对宿主机2的容器进行ping访问
root@273bba12b3b9:/# ping 172.25.11.112
PING 172.25.11.112 (172.25.11.112) 56(84) bytes of data.
64 bytes from 172.25.11.112: icmp_seq=1 ttl=64 time=0.072 ms
64 bytes from 172.25.11.112: icmp_seq=2 ttl=64 time=0.086 ms
^C
--- 172.25.11.112 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.072/0.079/0.086/0.007 ms