Docker网络 Weave
当容器分布在多个不同的主机上时,这些容器之间的相互通信变得复杂起来。容器在不同主机之间都使用的是自己的私有IP地址,不同主机的容器之间进行通讯需要将主机的端口映射到容器的端口上,而且IP地址需要使用主机的IP地址。Weave正是为了解决这个问题而出现的,它把不同主机上容器互相连接的网络虚拟成一个类似于本地网络的网络。
Weave是在一个网络的基础上,构建了一层由软件定义的网络层,这个网络看起来就像是一个本地的局域网,但是实际上它的底层通过另一个网络进行通信。这个网络可能会比实际物理局域网的可靠性要差一些,但是从可用性角度来看,它带来了很大的便利性:可以在位于不同位置的节点之间通信,而好像它们在一个地方一样。也可以把这种网络想象成一个类似于VPN似的东西。
一、Weave 介绍
Weave是Github上一个比较热门的Docker容器网络方案,具有非常良好的易用性且功能强大。Weave 的框架它包含了两大主要组件: 1)Weave:用户态的shell脚本,用于安装Weave,将container连接到Weave虚拟网络。并为它们分配IP。 2)Weaver:运行于container内,每个Weave网络内的主机都要运行,是一个Go语言实现的虚拟网络路由器。不同主机之间的网络通信依赖于Weaver路由。 Weave通过创建虚拟网络使Docker容器能够跨主机通信并能够自动相互发现。 通过weave网络,由多个容器构成的基于微服务架构的应用可以运行在任何地方:主机,多主机,云上或者数据中心。 应用程序使用网络就好像容器是插在同一个网络交换机上一样,不需要配置端口映射,连接等。 在weave网络中,使用应用容器提供的服务可以暴露给外部,而不用管它们运行在何处。类似地,现存的内部系统也可以接受来自于应用容器的请求,而不管容器运行于何处。 一个Weave网络由一系列的'peers'构成----这些weave路由器存在于不同的主机上。每个peer都由一个名字,这个名字在重启之后保持不变.这个名字便于用户理解和区分日志信息。 每个peer在每次运行时都会有一个不同的唯一标识符(UID).对于路由器而言,这些标识符不是透明的,尽管名字默认是路由器的MAC地址。 Weave路由器之间建立起TCP连接,通过这个连接进行心跳握手和拓扑信息交换,这些连接可以通过配置进行加密。 peers之间还会建立UDP连接,也可以进行加密,这些UDP连接用于网络包的封装,这些连接是双工的而且可以穿越防火墙。 Weave网络在主机上创建一个网桥,每个容器通过veth pari连接到网桥上,容器由用户或者weave网络的IPADM分配IP地址。
Weave网络可以在具有编号拓扑的部分连接的网络中路由数据包。如下:peer1和2、3直接相连,如果1想要传输数据到4和5,需要通过peer3。
二、选择weave的原因
https://www.weave.works/docs/net/latest/overview/
1)无忧的配置 Weave网络能够简化容器网络的配置。因为weave网络中的容器使用标准的端口提供服务(如,MySQL默认使用3306),管理微服务是十分直接简单的。 每个容器都可以通过域名来与另外的容器通信,也可以直接通信而无需使用NAT,也不需要使用端口映射或者复杂的linking. 部署weave容器网络的最大的好处是无需修改你的应用代码。 2)服务发现 Weave网络通过在每个节点上启动一个"微型的DNS"服务来实现服务发现。你只需要给你的容器起个名字就可以使用服务发现了,还可以在多个同名的容器上提供负载均衡的功能。 3)不需要额外的集群存储 所有其它的Docker网络插件,包括Docker自带的"overlay"驱动,在你真正能使用它们之间,都需要安装额外的集群存储----一个像Consul或者Zookeepr那样的中心数据库.
除了安装,维护和管理困难外,甚至Docker主机需要始终与集群存储保持连接,如果你断开了与其的连接,尽管很短暂,你也不能够启动和停止任何容器了。 Weave网络是与Docker网络插件捆绑在一起的,这意味着你可以马上就使用它,而且可以在网络连接出现问题时依旧启动和停止容器。 关于更多Weave Docker插件的介绍,请查看 Weave Network Plugin如何工作. 4)在部分连接情况下进行操作 Weave网络能够在节点间转发流量,它甚至能够在网状网络部分连接的情况下工作。这意味着你可以在混合了传统系统和容器化的应用的环境中使用Weave网络来保持通信。 5)Weave网络很快 Weave网络自动在两个节点之间选择最快的路径,提供接近本地网络的吞吐量和延迟,而且这不需要你的干预。 关于Fast Datapath如何工作请参考 How Fast Datapath Works . 6)组播支持 Weave网络完全支持组播地址和路径。数据可以被发送给一个组播地址,数据的副本可以被自动地广播。 7)NAT 转换 使用Weave网络,部署你的应用---无论是点对点的文件共享,基于ip的voice或者其它应用,你都可以充分利用内置的NAT转换。通过Weave网络,你的app将会是可移值的,容器化的, 加上它对网络标准化的处理,将又会使你少关心一件事。 8)与任何框架集成: Kubernetes, Mesos, Amazon ECS, … 如果你想为所有的框架使用一个工具,Weave网络是一个好的选择。比如: 除了作为Docker插件使用,你还可以将其作为一个Kubernetes插件plugin.你还可以在 Amazon ECS ,Mesos和 Marathon中使用它.
三、部署Weave网络
官方文档:https://www.weave.works/docs/net/latest/install/installing-weave/
3.1 前提条件
1)确保节点Linux内核版本3.8+,Docker1.10+
2)节点间如果有防火墙,必须彼此放行TCP 6783 和UDP 6783/6784端口,这是weave控制和数据端口
3)主机名不能相同,通过主机名识别子网
3.2 节点环境
节点 | ip | kernel |
weave-01 | 172.16.200.218 | 4.15.7-1.el7.elrepo.x86_64 |
weave-02 | 172.16.200.223 | 4.15.7-1.el7.elrepo.x86_64 |
3.3 安装weave
curl -L git.io/weave -o /usr/local/bin/weave chmod a+x /usr/local/bin/weave
3.4 启动并与其它主机建立联系
# weave-01 weave launch 172.16.200.223 # weave-02 weave launch 172.16.200.218
验证:
[root@weave-01 ~]# weave status connections <- 172.16.200.223:44899 established fastdp d2:cd:54:51:3e:bd(weave-02) mtu=1376
weave 命令帮助:
weave --help
3.5 使用weave网络创建容器
方式一:这种方式创建的容器,其名称无法在整个weave网络中的weave dns中被识别,只能被本宿主机的weave dns识别,推荐下一种
[root@weave-01 ~]# docker run -it --net=weave --name weave-01-box1 busybox / # ifconfig eth0 Link encap:Ethernet HWaddr 02:42:AC:16:00:02 inet addr:172.22.0.2 Bcast:172.22.255.255 Mask:255.255.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:11 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:942 (942.0 B) TX bytes:0 (0.0 B) ethwe0 Link encap:Ethernet HWaddr 4A:DD:B1:FE:9E:FD inet addr:10.40.0.0 Bcast:10.47.255.255 Mask:255.240.0.0 UP BROADCAST RUNNING MULTICAST MTU:1376 Metric:1 RX packets:6 errors:0 dropped:0 overruns:0 frame:0 TX packets:1 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:516 (516.0 B) TX bytes:42 (42.0 B)
[root@weave-02 ~]# docker run -it --net=weave --name weave-02-box2 busybox / # ifconfig eth0 Link encap:Ethernet HWaddr 02:42:AC:12:00:02 inet addr:172.18.0.2 Bcast:172.18.255.255 Mask:255.255.0.0 UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:12 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:1032 (1.0 KiB) TX bytes:0 (0.0 B) ethwe0 Link encap:Ethernet HWaddr 46:9F:96:9D:71:78 inet addr:10.32.0.1 Bcast:10.47.255.255 Mask:255.240.0.0 UP BROADCAST RUNNING MULTICAST MTU:1376 Metric:1 RX packets:6 errors:0 dropped:0 overruns:0 frame:0 TX packets:1 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:516 (516.0 B) TX bytes:42 (42.0 B)
weave网络中的容器通过ethwe0通信
测试互联
# weave-02 ping weave-01的容器 / # ping 10.40.0.0 PING 10.40.0.0 (10.40.0.0): 56 data bytes 64 bytes from 10.40.0.0: seq=0 ttl=64 time=1.474 ms 64 bytes from 10.40.0.0: seq=1 ttl=64 time=0.266 ms 64 bytes from 10.40.0.0: seq=2 ttl=64 time=0.252 ms
方式二(weave env):该方式创建的容器,名称能被整个weave 网络的dns 识别
不用指定网络,也是可以互通
eval $(weave env) # weave-01 docker run -it --name env_box01 busybox # weave-02 docker run -it --name env_box02 busybox
eval $(weave env) 设置环境变量,这样通过docker命令启动的容器就会自动连接到weave网络中
eval $(weave env --restore) 恢复之前的环境
[root@weave-02 ~]# docker exec env_box02 hostname env_box02.weave.local # weave dns 识别容器名称
四、Weave网络的实现
1.初始化weave后,会自动创建weave网络和网桥
确保要有bridge-utils网桥工具
2.查看weave容器中的网络(使用weave env)
weave容器env_box2中有两个网络接口:eth0@if46从ip地址来看,是和docker0同属于一个网段,默认连接在docker0上
其中有一个ethwe0@if48,从名称上看出与weave相关,其对应的编号是47。我们从宿主机上面ip link进行查看
vethwepl5889@if47与ethwe是一对veth pair,而且被挂在了weave上
3.查看host宿主机上的网络
这里出现了很多新得interface
datapath:是一个openvswitch
vethwe-datapath@vethwe-bridge:是veth pair
vethwe-datapath:父设备是datapath
vxlan-6784:是vxlan interface,其maste也是datapath,weave主机之间通过Vxlan节能型通信
宿主机host网络结构:
weave网络包含两个虚拟交换机:桥接的weave和openvswitch datapath,veth pair :vethwe-bridge将两者连接在一起。
weave与datapath分工不同,weave负责将容器接入weave网络,datapath负责在主机间建立vxlan隧道并收发数据
4. weave network
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的一些功能
5.1 IP地址管理(IPAM)
Weave自动为容器分配唯一的IP地址。可以通过weave ps 查看
[root@weave-02 ~]# weave ps weave:expose d2:cd:54:51:3e:bd 2447f41d7c62 6e:48:ca:ac:74:67 10.32.0.2/12 80007d745fbe a2:11:82:01:b0:8c 10.32.0.1/12
5.2 命名和自动发现
命名的容器会自动注册到Weave DNS中,Weave自己维护着一个微型的DNS服务器,可以通过容器名称来访问
创建了两个weave容器
可以通过名称来访问
5.3 负载均衡
允许在不同的weave主机上注册多个名称相同的容器,Weave DNS随机为每个请求返回地址,提供基本的负载均衡功能
在weave-01 和weave-02上都新建一个名称为test-slb-box的容器
# weave-01 [root@weave-01 ~]# eval $(weave env) [root@weave-01 ~]# docker run -itd --name=test-slb-box busybox ac36177c4fdbe98d47f63d0fbb9ce53f92d95f157b24a222cfa4c4c7629b9ed3 [root@weave-01 ~]# [root@weave-01 ~]# docker exec test-slb-box hostname test-slb-box.weave.local # weave-02 [root@weave-02 ~]# eval $(weave env) [root@weave-02 ~]# docker run -itd --name=test-slb-box busybox 47b292366add38968a956b4b4d921e312bbfe7c6690b80c5bf11a229c6037049 [root@weave-02 ~]# docker exec test-slb-box hostname test-slb-box.weave.local # 分别在两个宿主机上启动相同名称的容器 test-slb-box
在启动一个容器ping test-slb-box
可以看到请求的test-slb-box的地址确实不一样,能够简单的实现负载均衡的功能
5.4 手动指定IP地址
[root@weave-02 ~]# docker run -it -e WEAVE_CIDR=10.32.0.10/24 --name weave-test04 busybox
5.5 动态拓扑
可以在不停止或重新 配置剩余Docker主机的情况下添加主机到weave网络中或从weave网络中删除
5.6 容错
weave peer不断交换拓扑信息,监视 和建立与其它peer的网络连接。如果有主机或者网络出现故障,Weave会绕过这个主机,保证两边容器可以继续通信,当恢复时,恢复完全连接。
六、weave网络隔离
默认配置下,weave使用一个大subnet(例如10.32.0.0/12),所有主机的容器都从这个地址空间中分配IP ,因为同属一个subnet,容器可以直接通信。如果要实现网络隔离,可以通过换环境变量WEAVE_CIDR为容器分配不同的subnet的IP
# 创建一个独立网络的weave容器 [root@weave-02 ~]# eval $(weave env) [root@weave-02 ~]# docker run -e WEAVE_CIDR=net:10.32.2.0/24 -itd --name isolation_01 busybox # 创建两个默认网段的weave容器 [root@weave-02 ~]# docker run -itd --name default_net_01 busybox b7e750a49095bfb546be1472a35c43c6ce91346bb72b3ad93fdb1d2bb4bbc4d3 [root@weave-02 ~]# docker run -itd --name default_net_02 busybox 9d006e9db5a3e6cc86ad2735e8d97f41313edf7237b46b0126634a3147a2b637
测试连通性:
默认网段间可以相互通信
独立网段的不能和默认网段连通
注:weave容器isolation_01虽然不能通过weave网络和其他weave容器连通,但是另一个网络接口eth0还是可以相互通信的。