Weave

weave网络通信模型

weave通过在docker集群的每个主机上启动虚拟的路由器,将主机作为路由器,形成互联互通的网络拓扑,在此基础上,实现容器的跨主机通信。其主机网络拓扑参见下图:

在这里插入图片描述

如上图所示,在每一个部署Docker的主机(可能是物理机也可能是虚拟机)上都部署有一个W(即weave router,它本身也可以以一个容器的形式部署)。

weave网络是由这些weave routers组成的对等端点(peer)构成,并且可以通过weave命令行定制网络拓扑。

 

每个部署了weave router的主机之间都会建立TCP和UDP两个连接,保证weave router之间控制面流量和数据面流量的通过。控制面由weave routers之间建立的TCP连接构成,通过它进行握手和拓扑关系信息的交换通信。控制面的通信可以被配置为加密通信。而数据面由weave routers之间建立的UDP连接构成,这些连接大部分都会加密。这些连接都是全双工的,并且可以穿越防火墙。

当容器通过weave进行跨主机通信时,其网络通信模型可以参考下图:

在这里插入图片描述

从上面的网络模型图中可以看出,对每一个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承载容器之间的数据包,并且可以完全自定义整个集群的网络拓扑,但从性能和使用角度来看,还是有比较大的缺陷的:

1)weave自定义容器数据包的封包解包方式,不够通用,传输效率比较低,性能上的损失也比较大。

2)集群配置比较负载,需要通过weave命令行来手工构建网络拓扑,在大规模集群的情况下,加重了管理员的负担。

Weave的应用示例

1)直接从github下载二进制文件安装。

[root@localhost ~]# wget -O /usr/local/bin/weave https://raw.githubusercontent.com/zettio/weave/master/weave

[root@localhost ~]# chmod a+x /usr/local/bin/weave

     

2)启动weave路由器,这个路由器其实也是以容器的形式运行的。(前提是已经启动了docker服务进程)

[root@localhost ~]# weave launch                      

Unable to find image 'weaveworks/weaveexec:latest' locally

Trying to pull repository docker.io/weaveworks/weaveexec ...

latest: Pulling from docker.io/weaveworks/weaveexec

79650cf9cc01: Pull complete

a0a33a8311d7: Pull complete

e95af5f75fa8: Pull complete

7119d296ce72: Pull complete

7f0698aa2117: Pull complete

db711cb12a2b: Pull complete

.......

     

3)查看镜像,可以发现上面下载的weave路由容器镜像

[root@localhost ~]# docker images

REPOSITORY                         TAG                 IMAGE ID            CREATED             SIZE

docker.io/weaveworks/weaveexec     latest              e4870c565dfa        11 hours ago        107.7 MB

docker.io/weaveworks/weave         latest              70bd2bf0b0eb        11 hours ago        58.22 MB

docker.io/weaveworks/weavedb       latest              9a4a497119c4        3 months ago        252 B

docker.io/centos                 latest              67591570dd29        5 months ago        191.8 MB

     

4)此时会发现有两个网桥,一个是Docker默认生成的,另一个是Weave生成的。

[root@localhost ~]# brctl show                                     #yum安装bridge-utils工具后,就会出现brctl命令    

bridge name bridge id       STP enabled interfaces

docker0     8000.0242376456d7   no 

weave       8000.32298bba31f1   no      vethwe-bridge

     

查看运行的容器,发现weave路由容器已经自动运行

[root@localhost ~]# docker ps

CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS              PORTS               NAMES

c5aacecbe40e        weaveworks/weave:latest   "/home/weave/weaver -"   6 minutes ago       Up 6 minutes                            weave

     

weave关闭

[root@localhost ~]# weave stop

或者直接关闭weave容器

[root@localhost ~]# docker stop weave

[root@localhost ~]# docker rm weave

  

weave命令帮助

[root@localhost ~]#weave --help

Usage:

    

weave --help | help

      setup

      version

    

weave launch        [--password <pass>] [--trusted-subnets <cidr>,...]

                    [--host <ip_address>]

                    [--name <mac>] [--nickname <nickname>]

                    [--no-restart] [--resume] [--no-discovery] [--no-dns]

                    [--ipalloc-init <mode>]

                    [--ipalloc-range <cidr> [--ipalloc-default-subnet <cidr>]]

                    [--plugin=false] [--proxy=false]

                    [-H <endpoint>] [--without-dns] [--no-multicast-route]

                    [--no-rewrite-hosts] [--no-default-ipalloc]

                    [--hostname-from-label <labelkey>]

                    [--hostname-match <regexp>]

                    [--hostname-replacement <replacement>]

                    [--rewrite-inspect]

                    [--log-level=debug|info|warning|error]

                    <peer> ...

    

weave prime

    

weave env           [--restore]

      config

      dns-args

    

weave connect       [--replace] [<peer> ...]

      forget        <peer> ...

    

weave attach        [--without-dns] [--rewrite-hosts] [--no-multicast-route]

                      [<addr> ...] <container_id>

      detach        [<addr> ...] <container_id>

    

weave expose        [<addr> ...] [-h <fqdn>]

      hide          [<addr> ...]

    

weave dns-add       [<ip_address> ...] <container_id> [-h <fqdn>] |

                    <ip_address> ... -h <fqdn>

      dns-remove    [<ip_address> ...] <container_id> [-h <fqdn>] |

                    <ip_address> ... -h <fqdn>

      dns-lookup    <unqualified_name>

    

weave status        [targets | connections | peers | dns | ipam]

      report        [-f <format>]

      ps            [<container_id> ...]

    

weave stop

    

weave reset         [--force]

      rmpeer        <peer_id> ...

    

where <peer>     = <ip_address_or_fqdn>[:<port>]

      <cidr>     = <ip_address>/<routing_prefix_length>

      <addr>     = [ip:]<cidr> | net:<cidr> | net:default

      <endpoint> = [tcp://][<ip_address>]:<port> | [unix://]/path/to/socket

      <peer_id>  = <nickname> | <weave internal peer ID>

      <mode>     = consensus[=<count>] | seed=<mac>,... | observer

    

接下来就可以运行应用容器,使用weave提供的网络功能了。

Weave的应用示例

1)机器环境准备:

node-1    103.10.86.238 

node-2    103.10.86.239    

 

node-1宿主机上的应用容器my-test1: 192.168.0.2/24

node-2宿主机上的应用容器my-test2: 192.168.0.3/24

 

两台机上均安装Docker及Weave,并均启动好Weave路由容器(安装及启动操作如上)。最好关闭两台机器的防火墙!(如果打开防火墙,需要开放6783端口)

 

2)在两台机上均启动一个应用容器,有以下两种方式:

第一种方式:可以直接使用weave run命令;

[root@node-1 ~]# weave run 192.168.0.2/24 -itd docker.io/centos /bin/bash

The 'weave run' command has been removed as of Weave Net version 2.0

Please see release notes for further information

 

由上可知,weave在2.0版本之后就没有“docker run”这个命令了,所以还是使用下面的第二种方式

 

第二种方式:先使用docker run启动好容器,然后使用weave attach命令给容器绑定IP地址

在node-1机器上启动第一个容器my-test1,容器ip绑定为192.168.0.2

[root@node-1 ~]# docker run -itd --name=my-test1 docker.io/centos /bin/bash

06d70049141048798519bfa1292ed81068fc28f1e142a51d22afd8f3fc6d0239

[root@node-1 ~]# weave attach 192.168.0.2/24 my-test1           #使用容器名称或容器id都可以;即给my-test1容器绑定ip为192.168.0.2

192.168.0.2

 

[root@node-1 ~]# docker exec -ti my-test1 /bin/bash

[root@00efd39d3a7d /]# ifconfig              #执行安装yum install -y net-tools,就会出现ifconfig命令

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500

        inet 172.17.0.2  netmask 255.255.0.0  broadcast 0.0.0.0

        inet6 fe80::42:acff:fe11:2  prefixlen 64  scopeid 0x20<link>

        ether 02:42:ac:11:00:02  txqueuelen 0  (Ethernet)

        RX packets 5559  bytes 11893401 (11.3 MiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 5287  bytes 410268 (400.6 KiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

 

ethwe: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1376

        inet 192.168.0.2  netmask 255.255.255.0  broadcast 0.0.0.0

        inet6 fe80::88b0:ddff:fea2:58c5  prefixlen 64  scopeid 0x20<link>

        ether 8a:b0:dd:a2:58:c5  txqueuelen 0  (Ethernet)

        RX packets 97  bytes 7234 (7.0 KiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 66  bytes 4316 (4.2 KiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

 

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536

        inet 127.0.0.1  netmask 255.0.0.0

        inet6 ::1  prefixlen 128  scopeid 0x10<host>

        loop  txqueuelen 0  (Local Loopback)

        RX packets 21  bytes 2352 (2.2 KiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 21  bytes 2352 (2.2 KiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

 

在node-2机器上启动容器my-test2,容器ip绑定为192.168.0.3

[root@node-2 ~]# docker run -itd --name=my-test2 docker.io/centos /bin/bash

8f2ecc2449a0be1f1be2825cb211f275f9adb2109249ab0ff1ced6bbb92dd733

[root@node-2 ~]# weave attach 192.168.0.3/24 my-test2                     //weave detach 192.168.0.3/24 my-test2表示删除这个绑定

192.168.0.3

[root@node-2 ~]# docker exec -ti my-test2 /bin/bash

[root@e0ed62d30226 /]# ifconfig                                          //或者ip addr命令查看

......

ethwe: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1376

        inet 192.168.0.3  netmask 255.255.255.0  broadcast 0.0.0.0

        inet6 fe80::3064:8fff:fe3c:909a  prefixlen 64  scopeid 0x20<link>

        ether 32:64:8f:3c:90:9a  txqueuelen 0  (Ethernet)

        RX packets 63  bytes 4734 (4.6 KiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 34  bytes 2580 (2.5 KiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

 

温馨提示:

上面在docker run启动容器时,可以添加--net=none参数,这个表示容器启动后不使用默认的虚拟网卡docker0自动分配的ip,而是使用weave绑定的ip;

当然也可以选择不添加这个参数去启动容器,这样,容器启动后就会有两个网卡,即两个ip:

一个是docker0自动分配的ip,这个适用于同主机内的容器间通信,即同主机的容器使用docker0分配的ip可以相互通信;另一个就是weave网桥绑定的ip。

 

3)容器互联

默认情况下,上面在node-1和node-2两台宿主机上创建的2个容器间都是相互ping不通的。需要使用weave connect命令在两台weave的路由器之间建立连接。

[root@node-1 ~]# weave connect 103.10.86.239                            //连接的是对方宿主机的ip,注意"weave forget ip" z则表示断开这个连接

 

然后就会发现,此时位于两台不同主机上的相同子网段内的容器之间可以相互ping通了

[root@node-1 ~]# docker exec -ti my-test1 /bin/bash

[root@00efd39d3a7d /]# ping 192.168.0.3

PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.

64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=3.27 ms

64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.657 ms

.....

 

[root@node-2 ~]# docker exec -ti my-test2 /bin/bash

[root@e0ed62d30226 /]# ping 192.168.0.2

PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.

64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.453 ms

64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.320 ms

.....

 

再在node-1上启动容器my-test3,绑定ip为192.168.0.8,在node-2上启动容器my-test4,绑定ip为192.168.0.10

会发现这四个在同一个子网内的容器都是可以相互ping通的。

 

--------------------------------------------------------------------------------------------------------

再接着启动与上面不在同一个子网内的容器

node-1上启动容器my-test4,绑定ip为192.168.10.10,node-2上启动容器my-test5,绑定ip为192.168.10.20

 

[root@node-1 ~]# docker run -itd --name=my-test5 docker.io/centos /bin/bash

2896b6cad7afcd57d8b9091a020f1837992bade2567752614caf3cb645b6d315

[root@node-1 ~]# weave attach 192.168.10.10/24 my-test5

192.168.10.10

[root@node-1 ~]# docker exec -ti my-test5 /bin/bash

[root@2896b6cad7af /]#

 

[root@node-2 ~]# docker run -itd --name=my-test6 docker.io/centos /bin/bash

b4627f0a6e657f5dc719c917349ad832e15f360f75d5743b489f8e7e18b7dc2e

[root@node-2 ~]# weave attach 192.168.10.20/24 my-test6

192.168.10.20

[root@node-2 ~]# docker exec -ti my-test6 /bin/bash

[root@b4627f0a6e65 /]# ping 192.168.10.10

PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.

64 bytes from 192.168.10.10: icmp_seq=1 ttl=64 time=0.417 ms

64 bytes from 192.168.10.10: icmp_seq=2 ttl=64 time=0.324 ms

......

 

会发现在跨主机情况下,相同子网内的容器是可以相互通信的;但是处于不同子网的两个容器是不能互联的,尽管这两个容器在同一个主机下也是不能通信的!

这样的好处就是:使用不同子网进行容器间的网络隔离了。

 

--------------------------------------------------------------------------------------------------------

注意一个细节,在使用weave的时候:

1)如果使用Docker的原生网络,在容器内部是可以访问宿主机以及外部网络的。也就是说在启动容器的时候,使用了虚拟网卡docker0分配ip,

这种情况下,登陆容器后是可以ping通宿主机ip,并且可以对外联网的!

 

这个时候,在宿主机上是可以ping通docker0网桥的ip,但是ping不通weave网桥的ip。这个时候可以使用

"weave expose 192.168.0.1/24"命令来给weave网桥添加IP,以实现容器与宿主机网络连通。如下:

 

默认在node-1和node-2宿主机上是ping不通my-test1容器的weave网桥ip的

[root@node-1 ~]# ping 192.168.0.2

PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.

.......

 

[root@node-2 ~]# ping 192.168.0.3

PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.

.......

 

在node-1和node-2两台机器上都添加weave网桥的ip

[root@node-1 ~]# weave expose 192.168.0.1/24            //注意这里的192.168.0.1/24是上面my-test1、my-test2、my-test3、my-test4容器的weave网桥的网关地址

[root@node-2 ~]# weave expose 192.168.0.1/24            //weave hide 192.168.0.1/24表示覆盖/删除这个设置

 

然后再在两台宿主机上ping上面同网段内的容器,发现都可以ping通了

[root@node-1 ~]# ping 192.168.0.10

PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.

64 bytes from 192.168.0.3: icmp_seq=4 ttl=64 time=0.391 ms

64 bytes from 192.168.0.3: icmp_seq=5 ttl=64 time=0.363 ms

 

[root@node-2 ~]# ping 192.168.0.8

PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.

64 bytes from 192.168.0.3: icmp_seq=4 ttl=64 time=0.391 ms

64 bytes from 192.168.0.3: icmp_seq=5 ttl=64 time=0.363 ms

 

然后再给另一网段的容器的weave网桥添加ip(可以在宿主机上对不同网段的容器的weave网桥添加ip)

[root@node-1 ~]# weave expose 192.168.10.1/24

[root@node-2 ~]# weave expose 192.168.10.1/24

 

[root@node-1 ~]# ping 192.168.10.20

PING 192.168.10.20 (192.168.10.20) 56(84) bytes of data.

64 bytes from 192.168.10.20: icmp_seq=1 ttl=64 time=2.50 ms

64 bytes from 192.168.10.20: icmp_seq=2 ttl=64 time=0.318 ms

 

[root@node-2 ~]# ping 192.168.10.10

PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.

64 bytes from 192.168.10.10: icmp_seq=1 ttl=64 time=0.335 ms

64 bytes from 192.168.10.10: icmp_seq=2 ttl=64 time=0.310 ms

 

2)如果不适用Docker的原生网络,即在容器启动的时候,添加--net=none,这样容器启动后,就不会使用docker0网卡分配ip。

这种情况下,登陆容器后发现不能访问宿主机以及外部网络的,而在宿主机上也不能ping通容器ip。

这个时候添加对应容器网段的weave网桥ip,这样可以实现容器与宿主机网络连通。但是,此时在容器内部依然不能访问外部网络。

 

所以说,可以同时使用Docker的原生网络和weave网络来实现容器互联及容器访问外网和端口映射。

使用外部网络及端口映射的时候就使用docker0网桥,需要容器互联的时候就使用weave网桥。每个容器分配两个网卡。

weave的其他特性

1)应用隔离:

不同子网容器之间默认隔离的,即便它们位于同一台物理机上也相互不通(使用-icc=false关闭容器互通);不同物理机之间的容器默认也是隔离的

  

2)安全性:

可以通过weave launch -password wEaVe设置一个密码用于weave peers之间加密通信

  

3)查看weave路由状态:weave ps

[root@node-1 ~]# weave ps

weave:expose 06:9d:3b:91:3d:f3 192.168.0.1/24 192.168.10.1/24

2896b6cad7af 56:46:8c:14:42:e6 192.168.10.10/24

c9aa381c1203 4a:0d:16:4d:bb:c2 192.168.0.8/24

00efd39d3a7d 8a:b0:dd:a2:58:c5 192.168.0.2/24

  

[root@node-2 ~]# weave ps

weave:expose 26:b8:82:03:ff:24 192.168.0.1/24 192.168.10.1/24

b4627f0a6e65 22:10:c4:b8:87:b3 192.168.10.20/24

61722c59e3a0 d2:d5:34:1e:86:df 192.168.0.10/24

e0ed62d30226 32:64:8f:3c:90:9a 192.168.0.3/24

  

4)效率

weave 路由通过pcap捕获包这种方式来完成封装和解封装这个过程,效率应该是有问题的。

这个过程中需要将数据包从内核态拷贝到用户态,然后按照自定义的格式完成封装和解封装。

 

--------------------------------------------------------------------------------------------------

在已经关闭了weave(weave stop)后,发现weave网桥信息还在:

[root@node-2 ~]# brctl show

bridge name bridge id       STP enabled interfaces

docker0     8000.0242b0c9bf2d   no     

weave       8000.22a85b2682a1   no      vethwe-bridge

 

[root@node-2 ~]# ifconfig

........

 

weave: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1376

        inet 192.168.100.1  netmask 255.255.255.0  broadcast 0.0.0.0

        inet6 fe80::20a8:5bff:fe26:82a1  prefixlen 64  scopeid 0x20<link>

        ether 22:a8:5b:26:82:a1  txqueuelen 0  (Ethernet)

        RX packets 57  bytes 3248 (3.1 KiB)

        RX errors 0  dropped 0  overruns 0  frame 0

        TX packets 22  bytes 1460 (1.4 KiB)

        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

 

删除weave网桥信息(其他ifconfig命令查出的网络设备删除的方法类似):

[root@node-2 ~]# ip link set dev weave down

[root@node-2 ~]# brctl delbr weave

 

[root@node-2 ~]# brctl show

bridge name bridge id       STP enabled interfaces

docker0     8000.0242b0c9bf2d   no 

https://www.cnblogs.com/ic-wen/p/13539689.html
https://www.cnblogs.com/kevingrace/p/6590319.html
https://blog.csdn.net/mnasd/category_7498619.html
https://blog.csdn.net/mnasd/article/details/83059752
https://blog.csdn.net/lizy0327/article/details/114214665
https://blog.csdn.net/mnasd/article/details/83060043
https://blog.csdn.net/mnasd/article/details/83060087
https://blog.csdn.net/weixin_34149796/article/details/85891438
https://www.cnblogs.com/kevingrace/p/6864804.html
https://www.cnblogs.com/renshengdezheli/p/17469079.html
https://juejin.cn/post/6844904068465311758

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值