使用Weave构建跨主机的容器网络

目录
  1. 安装Weave
  2. 设置Weave
  3. 测试连接

作者:杨冬 欢迎转载,也请保留这段声明。谢谢!
出处:https://andyyoung01.github.io/http://andyyoung01.16mb.com/

当容器分布在多个不同的主机上时,这些容器之间的相互通信变得复杂起来。容器在不同主机之间都使用的是自己的私有IP地址,不同主机的容器之间进行通讯需要将主机的端口映射到容器的端口上,而且IP地址需要使用主机的IP地址。Weave正是为了解决这个问题而出现的,它把不同主机上容器互相连接的网络虚拟成一个类似于本地网络的网络。

如果您了解SDN技术或者部署过OpenStack的网络模块(Neutron)的话,这里通过Weave构建的网络与它们比较类似。它是在一个网络的基础上,构建了一层由软件定义的网络层,这个网络看起来就像是一个本地的局域网,但是实际上它的底层通过另一个网络进行通信。这个网络可能会比实际物理局域网的可靠性要差一些,但是从可用性角度来看,它带来了很大的便利性:你可以在位于不同位置的节点之间通信,而好像它们在一个地方一样。你也可以把这种网络想象成一个类似于VPN似的东西。
对于Docker容器来说,这种网络可以将不同主机上的容器连接起来,正如将不同网络下的主机连接起来一样。这样做就无需计划在单台主机上可以容纳的容器数量。下图展示了一个典型的Weave网络的概览:
“一个典型的Weave网络”
上图中,主机1和主机3并没有直接的网络连接。但是这三个主机内部的容器之间可以通过Weave网络进行通信,就好像它们在一台主机的本地网络上一样。Weave网络并不开放到公有网络上,只有在Weave网络下启动的容器才可以访问。
下面我们演示一下如何通过Weave构建前面提到的这种网络。

安装Weave

Weave就是一个可执行的shell脚本文件。可以将其下载到所有需要加入Weave网络的主机上,然后更改其文件属性,使其变为可执行:

1
2
$ sudo curl -L git.io/weave -o /usr/local/bin/weave
$ sudo chmod +x /usr/local/bin/weave

设置Weave

本示例使用了两台主机,两台主机的主机名分别为centos7-A和centos7-B,ip地址分别为192.168.71.167和192.168.71.168。确保这两台主机之间可以正常通信(可以ping通)。如果在实践这个技术时遇到问题,很有可能是防火墙阻挡了Weave的通信,所以需要防火墙打开TCP和UDP的6783端口。
在第一台主机上,可以先启动第一个Weave route:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[yangdong@centos7-A ~]$ sudo /usr/local/bin/weave launch
...
[yangdong@centos7-A ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
becc8de53d1a weaveworks/plugin:1.6.1 "/home/weave/plugin" 22 seconds ago Up 20 seconds weaveplugin
6a2f7a53e5ac weaveworks/weaveexec:1.6.1 "/home/weave/weavepro" 31 seconds ago Up 30 seconds weaveproxy
1fc72da07340 weaveworks/weave:1.6.1 "/home/weave/weaver -" 36 seconds ago Up 35 seconds weave
[yangdong@centos7-A ~]$ C=$(sudo /usr/local/bin/weave run 10.0.1.2/24 -it ubuntu:14.04)
[yangdong@centos7-A ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0a43860f4660 ubuntu:14.04 "/bin/bash" 2 minutes ago Up 2 minutes nauseous_kilby
becc8de53d1a weaveworks/plugin:1.6.1 "/home/weave/plugin" 7 minutes ago Up 7 minutes weaveplugin
6a2f7a53e5ac weaveworks/weaveexec:1.6.1 "/home/weave/weavepro" 7 minutes ago Up 7 minutes weaveproxy
1fc72da07340 weaveworks/weave:1.6.1 "/home/weave/weaver -" 7 minutes ago Up 7 minutes weave

上述第1行命令运行weave脚本启动了Weave,如果是第一次运行,该脚本会下载Weave相关的docker镜像。第3行命令确认了Weave正常启动,实质上是启动了3个Weave容器。第8行命令在一个容器内启动了Weave router。通过命令行参数提供的IP地址和CIDR网络掩码,指定了Weave网络使用的IP地址和子网。此行命令将容器的标识符ID存入了变量C中,以便于后面进行引用。第9行命令确认了通过Weave命令启动的ubuntu容器的正常运行。
下面我们在第二台主机centos7-B上进行类似的步骤,但是需要告诉Weave第一台主机的IP地址,而且需要给第二个容器指定一个相同子网中的不同IP地址:

1
2
[yangdong@centos7-B ~]$ sudo /usr/local/bin/weave launch 192.168.71.167
[yangdong@centos7-B ~]$ C=$(sudo /usr/local/bin/weave run 10.0.1.3/24 -it ubuntu:14.04)

上述命令告诉Weave它应该与centos7-A连接,所以在启动时通过参数给出了centos7-A的IP地址。另外,在启动ubuntu容器时指定了与第一个容器相同子网内的不同IP。

测试连接

现在在两台主机上都设置好了Weave网络,下面测试一下这两个不同主机上的容器是否能互相访问:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[yangdong@centos7-A ~]$ docker attach $C
root@0a43860f4660:/# ping 10.0.1.3
PING 10.0.1.3 (10.0.1.3) 56(84) bytes of data.
64 bytes from 10.0.1.3: icmp_seq=1 ttl=64 time=5.43 ms
64 bytes from 10.0.1.3: icmp_seq=2 ttl=64 time=0.808 ms
64 bytes from 10.0.1.3: icmp_seq=3 ttl=64 time=1.29 ms
^C
--- 10.0.1.3 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 0.808/2.513/5.435/2.075 ms
[yangdong@centos7-B ~]$ docker attach $C
root@06373ddc56a1:/# ping 10.0.1.2
PING 10.0.1.2 (10.0.1.2) 56(84) bytes of data.
64 bytes from 10.0.1.2: icmp_seq=1 ttl=64 time=13.8 ms
64 bytes from 10.0.1.2: icmp_seq=2 ttl=64 time=0.721 ms
64 bytes from 10.0.1.2: icmp_seq=3 ttl=64 time=0.761 ms
^C
--- 10.0.1.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 0.721/5.099/13.815/6.163 ms

如果可以ping通,说明在你自己指定的子网中,两个容器是可以跨主机连接的。这样就可以在多台不同的主机上启动容器,但这些容器的网络好像连接在一个本地的网络当中。