上一篇记录了使用Docker原生网络进行跨主机容器间网络通信的方法,本篇主要介绍如何使用第三方网络项目进行跨主机容器间通信。

第三方网络项目跨主机通信分为隧道方案和路由方案,隧道方案主要介绍Flannel、Weave和OpenvSwitch,路由方案则介绍Calico。


Flannel网络:

Flannel是CoreOS团队针对Kubernetes设计的一个网络规划服务,简单来说,它的功能是让集群中的不同节点主机创建的Docker容器都具有全集群唯一的虚拟IP地址。

Flannel的设计目的就是为集群中的所有节点重新规划IP地址的使用规则,从而使得不同节点上的容器能够获得“同属一个内网”且”不重复的”IP地址,并让属于不同节点上的容器能够直接通过内网IP通信。

工作原理:

    Flannel的工作原理是每个主机配置一个ip段和子网个数。例如,可以配置一个覆盖网络使用 10.100.0.0/16段,每个主机/24个子网。因此主机a可以接受10.100.5.0/24,主机B可以接受10.100.18.0/24的包。flannel使用etcd来维护分配的子网到实际的ip地址之间的映射。对于数据路径,flannel 使用udp来封装ip数据报,转发到远程主机。选择UDP作为转发协议是因为他能穿透防火墙。例如,AWS Classic无法转发IPoIP or GRE 网络包,是因为它的安全组仅仅支持TCP/UDP/ICMP。

    Flannel 使用etcd存储配置数据和子网分配信息。flannel 启动之后,后台进程首先检索配置和正在使用的子网列表,然后选择一个可用的子网,然后尝试去注册它。etcd也存储这个每个主机对应的ip。flannel 使用etcd的watch机制监视/atomic.io/network/subnets下面所有元素的变化信息,并且根据他来维护一个路由表。为了提高性能,flannel优化了Universal TAP/TUN设备,对TUN和UDP之间的ip分片做了代理。

    Docker系列(十三):Docker 跨主机容器间网络通信(二)_第1张图片

上图是Flannel的GitHub页面上的一张原理图,结合上图可以总结Flannel的数据传输过程如下:

        i. 数据从源容器中发出后,经由所在主机的docker0虚拟网卡转发到flannel0虚拟网卡,这是个P2P的虚拟网卡,flanneld服务监听在网卡的另外一端。
        ii. Flannel通过Etcd服务维护了一张节点间的路由表,在稍后的配置部分我们会介绍其中的内容。
        iii. 源主机的flanneld服务将原本的数据内容UDP封装后根据自己的路由表投递给目的节点的flanneld服务,数据到达以后被解包,然后直接进入目的节点的flannel0虚拟网卡,然后被转发到目的主机的docker0虚拟网卡,最后就像本机容器通信一下的有docker0路由到达目标容器。

这样整个数据包的传递就完成了,这里需要解释三个问题:

     1)UDP封装是怎么回事?

     在UDP的数据内容部分其实是另一个ICMP(也就是ping命令)的数据包。原始数据是在起始节点的Flannel服务上进行UDP封装的,投递到目的节点后就被另一端的Flannel服务还原成了原始的数据包,两边的Docker服务都感觉不到这个过程的存在。

     2)为什么每个节点上的Docker会使用不同的IP地址段?

     这个事情看起来很诡异,但真相十分简单。其实只是单纯的因为Flannel通过Etcd分配了每个节点可用的IP地址段后,偷偷的修改了Docker的启动参数。

     在运行了Flannel服务的节点上可以查看到Docker服务进程运行参数(ps aux|grep docker|grep "bip"),例如“--bip=182.48.25.1/24”这个参数,它限制了所在节点容器获得的IP范围。这个IP范围是由Flannel自动分配的,由Flannel通过保存在Etcd服务中的记录确保它们不会重复。

     3)为什么在发送节点上的数据会从docker0路由到flannel0虚拟网卡,在目的节点会从flannel0路由到docker0虚拟网卡?

     例如现在有一个数据包要从IP为172.17.18.2的容器发到IP为172.17.46.2的容器。根据数据发送节点的路由表,它只与172.17.0.0/16匹配这条记录匹配,因此数据从docker0出来以后就被投递到了flannel0。同理在目标节点,由于投递的地址是一个容器,因此目的地址一定会落在docker0对于的172.17.46.0/24这个记录上,自然的被投递到了docker0网卡。

实现方式:

    环境准备:


IP地址 主机名 Docker版本 系统(内核版本) 部署服务
节点1
192.168.49.41 docker01.contoso.com 1.13.1 CentOS 7(3.10.0-693.el7.x86_64)  etcd+flannel
节点2 192.168.49.42 docker02.contoso.com 1.13.1 CentOS 7(3.10.0-693.el7.x86_64)  flannel

    准备条件:

    1. 禁用SELinux

    2. 关闭防火墙

    3. 打开ip转发

    4. 配置yum源

    部署流程:

    1)安装etcd服务

    在节点1上操作:

    安装etcd服务

    [root@docker01 ~]# yum -y install etcd
    [root@docker01 ~]# vi /etc/etcd/etcd.conf

    修改后配置文件的内容

    [root@docker01 ~]# egrep -v "^(#|$)" /etc/etcd/etcd.conf
    ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
    ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379, http://0.0.0.0:4001"
    ETCD_NAME="default"
    ETCD_ADVERTISE_CLIENT_URLS="http://192.168.49.41:2379, http://192.168.49.41:4001"

    启动etcd服务

    [root@docker01 ~]# systemctl start etcd
    [root@docker01 ~]# systemctl enable etcd

    测试etcd服务是否正常

    [root@docker01 ~]# etcdctl ls /
    [root@docker01 ~]# etcdctl -C http://192.168.49.41:2379 cluster-health
    member 8e9e05c52164694d is healthy: got healthy result from http://192.168.49.41:2379
    cluster is healthy
    [root@docker01 ~]# etcdctl -C http://192.168.49.41:4001 cluster-health
    member 8e9e05c52164694d is healthy: got healthy result from http://192.168.49.41:2379
    cluster is healthy

    2)部署flannel服务

    在节点1上:

    [root@docker01 ~]# yum -y install flannel
    [root@docker01 ~]# cp /etc/sysconfig/flanneld /etc/sysconfig/flanneld.bak
    [root@docker01 ~]# vi /etc/sysconfig/flanneld

    编辑后的配置文件内容

    [root@docker01 ~]# egrep -v "^(#|$)" /etc/sysconfig/flanneld
    FLANNEL_ETCD_ENDPOINTS="http://192.168.49.41:2379"
    FLANNEL_ETCD_PREFIX="/atomic.io/network"

    3)在etcd中设置网段

    [root@docker01 ~]# etcdctl mk /atomic.io/network/config '{"Network":"10.0.0.0/16"}'
    {"Network":"10.0.0.0/16"}
    # 这里的/atomic.io/network是根据flannel中的FLANNEL_ETCD_PREFIX的值来的,不能随意修改

    4)启动flannel服务 

    [root@docker01 ~]# systemctl start flanneld
    [root@docker01 ~]# systemctl enable flanneld.service
    Created symlink from /etc/systemd/system/multi-user.target.wants/flanneld.service to /usr/lib/systemd/system/flanneld.service.
    Created symlink from /etc/systemd/system/docker.service.wants/flanneld.service to /usr/lib/systemd/system/flanneld.service.

    重启docker服务(也可以重置docker daemon)

    [root@docker01 ~]# systemctl restart docker

    使用ifconfig查看网卡信息,会看到多出一个flannel0的网卡,切已经分配了etcd设置的网段(如果没有,可以重启主机)

    [root@docker01 ~]# ifconfig
    ......
    flannel0: flags=4305  mtu 1472
            inet 10.0.94.0  netmask 255.255.0.0  destination 10.0.94.0
            inet6 fe80::f11e:cb84:d77f:2a75  prefixlen 64  scopeid 0x20
            unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 500  (UNSPEC)
            RX packets 0  bytes 0 (0.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 3  bytes 144 (144.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    ......

    查看docker的进程,发现多了一些参数选项 

 [root@docker01 ~]# ps -ef|grep docker
    root       1275     1  0 12:52 ?        00:00:12 /usr/bin/dockerd-current --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current --default-runtime=docker-runc --exec-opt native.cgroupdriver=systemd --userland-proxy-path=/usr/libexec/docker/docker-proxy-current --init-path=/usr/libexec/docker/docker-init-current --seccomp-profile=/etc/docker/seccomp.json --selinux-enabled --log-driver=journald --signature-verification=false --storage-driver overlay2 --bip=10.0.94.1/24 --ip-masq=true --mtu=1472
    root       1280   1275  0 12:52 ?        00:00:05 /usr/bin/docker-containerd-current -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2m --state-dir /var/run/docker/libcontainerd/containerd --shim docker-containerd-shim --runtime docker-runc --runtime-args --systemd-cgroup=true
    root       1454   1280  0 12:56 ?        00:00:00 /usr/bin/docker-containerd-shim-current 16f0b08aaf59e25c71ed728b6ea98764ea18827100d29f5bdfa99822c617b876 /var/run/docker/libcontainerd/16f0b08aaf59e25c71ed728b6ea98764ea18827100d29f5bdfa99822c617b876 /usr/libexec/dockerdocker-runc-current
    root       1497   1280  0 12:56 ?        00:00:00 /usr/bin/docker-containerd-shim-current 16f0b08aaf59e25c71ed728b6ea98764ea18827100d29f5bdfa99822c617b876 /var/run/docker/libcontainerd/16f0b08aaf59e25c71ed728b6ea98764ea18827100d29f5bdfa99822c617b876 /usr/libexec/dockerdocker-runc-current

    这些选项是由/run/flannel/docker这个文件引入的,另外在/run/flannel下还有一个子网环境变量的文件

    [root@docker01 ~]# cat /run/flannel/docker 
    DOCKER_OPT_BIP="--bip=10.0.94.1/24"
    DOCKER_OPT_IPMASQ="--ip-masq=true"
    DOCKER_OPT_MTU="--mtu=1472"
    DOCKER_NETWORK_OPTIONS=" --bip=10.0.94.1/24 --ip-masq=true --mtu=1472"
    [root@docker01 ~]# cat /run/flannel/subnet.env 
    FLANNEL_NETWORK=10.0.0.0/16
    FLANNEL_SUBNET=10.0.94.1/24
    FLANNEL_MTU=1472
    FLANNEL_IPMASQ=false

    使用etcdctl可以查看etcd维护的子网信息

    [root@docker01 ~]# etcdctl ls /atomic.io/network/subnets
    /atomic.io/network/subnets/10.0.94.0-24
    /atomic.io/network/subnets/10.0.18.0-24

    5)在节点2上部署并启动flannel服务

    [root@docker02 ~]# yum -y install flannel 
    [root@docker02 ~]# vi /etc/sysconfig/flanneld 
    [root@docker02 ~]# egrep -v "^(#|$)" /etc/sysconfig/flanneld 
    FLANNEL_ETCD_ENDPOINTS="http://192.168.49.41:2379"
    FLANNEL_ETCD_PREFIX="/atomic.io/network"
    [root@docker02 ~]# systemctl start flanneld.service
    [root@docker02 ~]# systemctl enable flanneld.service
    Created symlink from /etc/systemd/system/multi-user.target.wants/flanneld.service to /usr/lib/systemd/system/flanneld.service.
    Created symlink from /etc/systemd/system/docker.service.wants/flanneld.service to /usr/lib/systemd/system/flanneld.service.

    flannel同样也在/run/flannel下生成了子网环境变量和docker配置项文件

    [root@docker02 ~]# cat /run/flannel/subnet.env 
    FLANNEL_NETWORK=10.0.0.0/16
    FLANNEL_SUBNET=10.0.18.1/24
    FLANNEL_MTU=1472
    FLANNEL_IPMASQ=false
    [root@docker02 ~]# cat /run/flannel/docker 
    DOCKER_OPT_BIP="--bip=10.0.18.1/24"
    DOCKER_OPT_IPMASQ="--ip-masq=true"
    DOCKER_OPT_MTU="--mtu=1472"
    DOCKER_NETWORK_OPTIONS=" --bip=10.0.18.1/24 --ip-masq=true --mtu=1472"

    6)在两个节点上创建容器,进行测试   

    在节点1上创建一个名为bbox01容器

    [root@docker01 ~]# docker run -itd --name bbox01 busybox:latest
    16f0b08aaf59e25c71ed728b6ea98764ea18827100d29f5bdfa99822c617b876

    在节点2上创建一个名为bbox02容器

    [root@docker02 ~]# docker run -itd --name bbox02 busybox:latest
    089994999e8a267f822c3444b585da125b3e6031256b3d45e39d3f5030c7034b

    查看bbox01的ip地址

    [root@docker01 ~]# docker inspect --format='{{.NetworkSettings.IPAddress}}' bbox01
    10.0.94.2

    查看bbox02的ip地址

    [root@docker02 ~]# docker inspect --format='{{.NetworkSettings.IPAddress}}' bbox02
    10.0.18.2

    bbox01尝试ping bbox02的地址

    [root@docker01 ~]# docker exec -it bbox01 ping 10.0.18.2 -c2 -w2
    PING 10.0.18.2 (10.0.18.2): 56 data bytes
    64 bytes from 10.0.18.2: seq=0 ttl=60 time=1.273 ms
    64 bytes from 10.0.18.2: seq=1 ttl=60 time=0.531 ms
    --- 10.0.18.2 ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 0.531/0.902/1.273 ms

    bbox02尝试ping bbox01的

    [root@docker02 ~]# docker exec -it bbox02 ping 10.0.94.2 -c2 -w2
    PING 10.0.94.2 (10.0.94.2): 56 data bytes
    64 bytes from 10.0.94.2: seq=0 ttl=60 time=0.779 ms
    64 bytes from 10.0.94.2: seq=1 ttl=60 time=0.708 ms
    
    --- 10.0.94.2 ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 0.708/0.743/0.779 ms



Weave网络:

Weave是由weaveworks公司开发的解决Docker跨主机网络的解决方案,它能够创建一个虚拟网络,用于连接部署在多台主机上的Docker容器,这样容器就像被接入了同一个网络交换机,那些使用网络的应用程序不必去配置端口映射和链接等信息。

特性概述:

  • Weave在Docker主机之间实现Overlay网络,使用业界标准VXLAN封装,基于UDP传输,也可以加密传输。

  • Weave Net创建一个连接多个Docker主机的虚拟网络,类似于一个以太网交换机,所有的容器都连接到这上面,互相通信。

  • Weave Net由多个peer组成,Weave路由器运行不同Docker主机上,是一个用户空间的进程;每个peer都有一个名称,重启保持不变。它们通过TCP连接彼此,建立后交换拓补信息。

  • Weave Net可以在具有编号拓补的部分连接的网络中路由数据包。

  • Weave Net中的"fast data path"使用Linux内核的OpenvSwitch datapath模块。该模块使Weave Net路由器能够告知内核如何处理数据包。OpenvSwitch datapath和VXLAN功能在Linux内核版本3.12才支持,如果内核不支持,则Weave Net使用"user mode"数据包路径。Weave Net会自动选择两台主机之间最快的路径传输数据,提供近原生吞吐量和延迟。

工作原理:

Docker系列(十三):Docker 跨主机容器间网络通信(二)_第2张图片

容器的网络通讯都通过route服务和网桥转发。

Docker系列(十三):Docker 跨主机容器间网络通信(二)_第3张图片

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连接构成,这些连接大部分都会加密。这些连接都是全双工的,并且可以穿越防火墙。

使用前提:

确保Linux内核版本3.8+,Docker 1.10+

节点之间如果有防火墙时,必须彼此放行TCP 6783/6784端口,这是Weave控制和数据端口

主机名不能相同,通过主机名标识子网

安装配置:

    环境准备:   


IP地址 主机名 Docker版本 系统(内核版本) 部署服务
节点1
192.168.49.41 docker01.contoso.com 1.13.1 CentOS 7(3.10.0-693.el7.x86_64)  docker+weave
节点2 192.168.49.42 docker02.contoso.com 1.13.1 CentOS 7(3.10.0-693.el7.x86_64)  docker+weave

1)安装weave

curl -L git.io/weave -o /usr/local/bin/weave
chmod +x /usr/local/bin/weave

2)启动服务并与其他主机建立连接

节点1:

[root@docker01 ~]# weave launch 192.168.49.42

节点2:

[root@docker02 ~]# weave launch 192.168.49.41

3)使用weave网络创建容器

方法1:

eval $(weave env)         # 先加载包含weave环境变量的docker主机选项
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

方法2:

docker run --net=weave [OPTIONS] IMAGE [COMMAND] [ARG...]   # 使用--net选项指定容器使用weave网络

4)测试容器间通信

查看节点1上的容器b1的网络信息:

[root@docker01 ~]# docker exec -it b1 /bin/sh
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
          inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:acff:fe11:2/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:16 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1296 (1.2 KiB)  TX bytes:648 (648.0 B)
ethwe     Link encap:Ethernet  HWaddr 6A:D4:05:76:46:84  
          inet addr:10.32.0.1  Bcast:10.47.255.255  Mask:255.240.0.0
          inet6 addr: fe80::68d4:5ff:fe76:4684/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1376  Metric:1
          RX packets:16 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:1248 (1.2 KiB)  TX bytes:300 (300.0 B)
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

可以看到,容器有2张网卡,一个是docker0网络eth0,一个是weave网络ethwe。

再看一下节点2上的容器b2的网络信息:

[root@docker02 ~]# docker exec -it b2 /bin/sh
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
          inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:acff:fe11:2/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:16 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1296 (1.2 KiB)  TX bytes:648 (648.0 B)
ethwe     Link encap:Ethernet  HWaddr 8E:A4:F2:8E:45:07  
          inet addr:10.40.0.0  Bcast:10.47.255.255  Mask:255.240.0.0
          inet6 addr: fe80::8ca4:f2ff:fe8e:4507/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)
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

同样的,节点2上的容器也有2张网卡,一个位于docker0网络的eth0, 和一个位于weave网络的ethwe。

再看一下主机的网桥信息:

[root@docker01 ~]# brctl show 
bridge namebridge idSTP enabledinterfaces
docker08000.0242788135fenovethc74508a
weave8000.2e3a3605d0bbnovethwe-bridge
                        vethwepl2156
[root@docker02 ~]# brctl show
bridge namebridge idSTP enabledinterfaces
docker08000.02422905102bnoveth1f6eb6a
weave8000.fae2402f1d08        novethwe-bridge
                        vethwepl2152

此时,查看主机上的容器,发现有3个weave容器:

[root@docker01 ~]# docker ps -a 
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS               NAMES
fc2fede65833        busybox:latest               "/w/w sh"                34 minutes ago      Up 34 minutes                           b1
7c29cbb81199        weaveworks/weave:2.5.1       "/home/weave/weave..."   About an hour ago   Up About an hour                        weave
ff25d3699d63        weaveworks/weaveexec:2.5.1   "data-only"              About an hour ago   Created                                 weavevolumes-2.5.1
dedabd37643b        weaveworks/weavedb:latest    "data-only"              About an hour ago   Created                                 weavedb
[root@docker02 ~]# docker ps -a
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS               NAMES
ca8f506edc57        busybox:latest               "/w/w sh"                35 minutes ago      Up 35 minutes                           b2
75ea2c72d6f5        weaveworks/weave:2.5.1       "/home/weave/weave..."   41 minutes ago      Up 41 minutes                           weave
7373f675ebc8        weaveworks/weaveexec:2.5.1   "data-only"              41 minutes ago      Created                                 weavevolumes-2.5.1
18196d0b0e19        weaveworks/weavedb:latest    "data-only"              41 minutes ago      Created                                 weavedb

我们尝试在容器内进行测试:

在节点1上:

[root@docker01 ~]# docker exec -it b1 ping 10.40.0.0 -c2 -w2
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.148 ms
64 bytes from 10.40.0.0: seq=1 ttl=64 time=2.577 ms
--- 10.40.0.0 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 1.148/1.862/2.577 ms
[root@docker01 ~]# docker exec -it b1 ping b2 -c2 -w2
PING b2 (10.40.0.0): 56 data bytes
64 bytes from 10.40.0.0: seq=0 ttl=64 time=0.502 ms
64 bytes from 10.40.0.0: seq=1 ttl=64 time=0.434 ms
--- b2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.434/0.468/0.502 ms

节点1上的容器b1尝试ping节点2上的容器b2:不仅可以ping通,且可以使用容器名ping通。

[root@docker01 ~]# docker exec -it b1 ping 192.168.49.41 -c2 -w2
PING 192.168.49.41 (192.168.49.41): 56 data bytes
64 bytes from 192.168.49.41: seq=0 ttl=64 time=0.051 ms
64 bytes from 192.168.49.41: seq=1 ttl=64 time=0.188 ms
--- 192.168.49.41 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.051/0.119/0.188 ms

节点1上的容器b1尝试ping节点1的ip地址,也可以ping通。

[root@docker01 ~]# docker exec -it b1 ping 192.168.49.42 -c2 -w2
PING 192.168.49.42 (192.168.49.42): 56 data bytes
64 bytes from 192.168.49.42: seq=0 ttl=63 time=0.291 ms
64 bytes from 192.168.49.42: seq=1 ttl=63 time=0.315 ms
--- 192.168.49.42 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.291/0.303/0.315 ms

节点1上的容器b1尝试ping节点2主机的IP地址:发现也可以ping通。

在节点2上:

[root@docker02 ~]# docker exec -it b2 ping 10.32.0.1 -c2 -w2
PING 10.32.0.1 (10.32.0.1): 56 data bytes
64 bytes from 10.32.0.1: seq=0 ttl=64 time=0.618 ms
64 bytes from 10.32.0.1: seq=1 ttl=64 time=0.476 ms
--- 10.32.0.1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.476/0.547/0.618 ms
[root@docker02 ~]# docker exec -it b2 ping b1 -c2 -w2
PING b1 (10.32.0.1): 56 data bytes
64 bytes from 10.32.0.1: seq=0 ttl=64 time=0.468 ms
64 bytes from 10.32.0.1: seq=1 ttl=64 time=0.487 ms
--- b1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.468/0.477/0.487 ms

节点2上的容器b2尝试ping节点1上的容器b1:结果不仅可以ping通,也可以使用容器名ping通。

[root@docker02 ~]# docker exec -it b2 ping 192.168.49.41 -c2 -w2
PING 192.168.49.41 (192.168.49.41): 56 data bytes
64 bytes from 192.168.49.41: seq=0 ttl=63 time=0.398 ms
64 bytes from 192.168.49.41: seq=1 ttl=63 time=0.461 ms
--- 192.168.49.41 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.398/0.429/0.461 ms

节点2上的容器b2尝试ping节点1的ip地址:也可以ping通。

[root@docker02 ~]# docker exec -it b2 ping 192.168.49.42 -c2 -w2
PING 192.168.49.42 (192.168.49.42): 56 data bytes
64 bytes from 192.168.49.42: seq=0 ttl=64 time=0.048 ms
64 bytes from 192.168.49.42: seq=1 ttl=64 time=0.050 ms
--- 192.168.49.42 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.048/0.049/0.050 ms

节点2上的容器b2尝试ping节点2的ip地址:也可以ping的通。

以上证明,跨主机容器间通信没有问题,且不同主机上的容器也能和多个主机进行通信,那主机是否能跟容器的weave网络通信呢?

我们到节点1上尝试ping容器b1的weave网络地址:

[root@docker01 ~]# ping 10.32.0.1 -c2 -w2
PING 10.32.0.1 (10.32.0.1) 56(84) bytes of data.
--- 10.32.0.1 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1000ms

发现此时是无法ping通的,我们再查看一下主机的路由表:

[root@docker01 ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.49.2    0.0.0.0         UG    100    0        0 eth0
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.49.0    0.0.0.0         255.255.255.0   U     100    0        0 eth0

这里我们添加一条到weave网络的路由:

[root@docker01 ~]# route add -net 10.32.0.0/24 gw 172.17.0.1

再次尝试去ping容器的weave网络:

[root@docker01 ~]# ping 10.32.0.1 -c2 -w2
PING 10.32.0.1 (10.32.0.1) 56(84) bytes of data.
64 bytes from 10.32.0.1: icmp_seq=1 ttl=64 time=0.065 ms
64 bytes from 10.32.0.1: icmp_seq=2 ttl=64 time=0.037 ms
--- 10.32.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.037/0.051/0.065/0.014 ms

已经可以ping通了,同样的方法也适用于节点2,这里就不再演示了。

weave的优缺点:

优点:

  1. 支持主机间通信加密。

  2. 支持container动态加入或者剥离网络。

  3. 支持跨主机多子网通信。

缺点:

  1. 只能通过weave launch或者weave connect加入weave网络。

weave的其他功能:

  • IP地址管理(IPAM):Weave自动为容器分配唯一的IP地址,可以通过weave ps查看

  • 命名和发现:命名的容器自动会注册到Weave DNS中,并可以通过容器名称访问

  • 负载均衡:允许注册多个相同名称的容器,Weave DNS随机为每个请求返回地址,提供基本的负载均衡功能

  • 手动指定IP地址:docker run -it -e WEAVE_CIDR=10.0.0.1/24 busybox

  • 动态拓补:可以在不停止或重新配置剩余Docker主机的情况下添加主机到Weave网络中或从Weave网络中删除

  • 容错:weave peer不断交换拓补信息,监视和建立与其他peer的网络连接。如果有主机或网络出现故障,Weave会绕过这个主机,保证两边容器可以继续通信,当恢复时,恢复完全连接。



OpenvSwitch网络:

Open vSwitch是一个高质量的,多层虚拟交换机,使用开源Apache2.0许可协议,主要实现代码为可移植的C代码。它的目的是让大规模网络自动化可以通过变成扩展,同事仍然支持标准的管理接口和协议(例如NetFlow,sFlow,SPAN.RSPAN,CLI,LACP,802.1ag)

OpenvSwitch概念:开放虚拟交换标准,是一种基于开源Apache2.0许可证的多层软件交换机,专门管理多租赁云计算网络环境,支持KVM、Xen等虚拟化技术。

功能支持:

1、支持标准802.1Q VLAN模块的Trunk和access端口模式

2、QoS(Quality of Service)配置及管理

3、支持OpenFlow协议

4、支持GRE、VXLAN、STT和LISP隧道

5、具有C和Python接口配置数据库

6、支持内核态和用户态的转发引擎设置

7、支持流量控制及监控

主要组成部分:

ovs-vswitchd:一个实现交换机的守护程序

ovsdb-server:一个轻量级数据库,ovs-vswitchd查询以获取其配置

ovs-dpctl:用于配置交换机的内核模块工具

ovs-vsctl:用于查看和更新ovs-vswitchd的配置工具

ovs-appctl:一个向运行OVS守护程序发送命令的工具

还提供了openflow的工具:

ovs-ofctl:用于查看和控制OpenFlow交换机和控制器

ovs-pki:用于创建和管理公钥

ovs-tcpundump:解析openflow消息

GRE隧道:

        隧道技术:是一种通过使用互联网的基础设施在网络的基础设施在网络之间传递数据的方式。使用隧道传递的数据可以是不同协议的数据帧或包。隧道协议将其它协议的数据帧或包重新封装然互通过隧道发送。新的帧头提供路由信息,以便通过互联网传递被封装的负载数据。

工作原理:

Docker系列(十三):Docker 跨主机容器间网络通信(二)_第4张图片

两台节点主机容器,Container通过OpenvSitch通信

  1. Container eth0:veth它会将网络桥接到docker0网络。

  2. Docker0:Docker网桥默认网络。

  3. br0:OVS网桥,它会将Docker0网桥加入到br0网络,它会捕获到Container eth0 发出的数据包。

  4. gre0:OVS网络捕获数据包后通过gre协议将数据包封装。

  5. eth0:物理网卡,它会把gre数据包,转发给节点2。

  6. 节点2的eth0接收数据包后->交给OVS进行街封装->获取获取访问地址->装发到docker0->再交给容器的eth0。

安装配置:

        环境准备:


IP地址 主机名 Docker版本 系统(内核版本) 部署服务
节点1
192.168.49.41 docker01.contoso.com 1.13.1 CentOS 7(3.10.0-693.el7.x86_64)  docker+openvswitch
节点2 192.168.49.42 docker02.contoso.com 1.13.1 CentOS 7(3.10.0-693.el7.x86_64)  docker+openvswitch

以下操作如不指明则均在两个节点上执行

1)安装openvswitch

yum -y install openvswitch

2)创建网桥并激活

ovs-vsctl add-br br0
ip link set dev br0 up

3)将gre虚拟接口加入网桥br0,并设置接口类型和对端IP地址

节点1:

ovs-vsctl add-port br0 gre0 -- set Interface gre0 type=gre options:remote_ip=192.168.49.42

节点2:

ovs-vsctl add-port br0 gre0 -- set Interface gre0 type=gre options:remote_ip=192.168.49.41

4)添加docker0网桥到OVS网桥br0

brctl addif docker0 br0

5)查看网桥信息

节点1:

[root@docker01 ~]# brctl show
bridge name   bridge id            STP enabled    interfaces
docker0       000.0242f970866b     no             br0
[root@docker01 ~]# ovs-vsctl show
b1bd6c23-a478-4ff0-b8cf-75925281e029
    Bridge "br0"
        Port "gre0"
            Interface "gre0"
                type: gre
                options: {remote_ip="192.168.49.42"}
        Port "br0"
            Interface "br0"
                type: internal
    ovs_version: "2.0.0"

节点2:

[root@docker02 ~]# brctl show
bridge name    bridge id           STP enabled        interfaces
docker0        8000.0242d467fd96          no         br0
[root@docker02 ~]# ovs-vsctl show
780ffc9d-e7b6-4c77-965b-321fe37c4b30
    Bridge "br0"
        Port "gre0"
            Interface "gre0"
                type: gre
                options: {remote_ip="192.168.49.41"}
        Port "br0"
            Interface "br0"
                type: internal
    ovs_version: "2.0.0"

6)修改docker网络设置并重启docker服务

节点1:

[root@docker01 ~]# egrep -v "^(#|$)" /etc/sysconfig/docker-network 
DOCKER_NETWORK_OPTIONS="--bip=172.17.1.1/24"
[root@docker01 ~]# systemctl restart docker

节点2:

[root@docker02 ~]# egrep -v "^(#|$)" /etc/sysconfig/docker-network 
DOCKER_NETWORK_OPTIONS="--bip=172.17.2.1/24"
[root@docker02 ~]# systemctl restart docker

7)添加静态路由

ip route add 172.17.0.0/26 dev docker0
route add -net 172.17.0.0/16 dev docker0

8)创建容器,验证是否可以互相通信

节点1:

[root@docker01 ~]# docker run -itd --name bbox01 busybox:latest
b9f7e64c89465949db741a6fa104095e9d4b70157c79943d6abd3d33bf8ba72a
[root@docker01 ~]# docker inspect bbox01 --format='{{.NetworkSettings.IPAddress}}'
172.17.1.2

节点2:

[root@docker02 ~]# docker run -itd --name bbox02 busybox:latest
6c64ec8804a53c14553f5bf0303e50392724fab4c650274981d126e2cd008203
[root@docker02 ~]# docker inspect bbox02 --format='{{.NetworkSettings.IPAddress}}'
172.17.2.2

节点1上的容器ping节点2上的容器:

[root@docker01 ~]# docker exec -it bbox01 ping 172.17.2.2 -c2 -w2
PING 172.17.2.2 (172.17.2.2): 56 data bytes
64 bytes from 172.17.2.2: seq=0 ttl=63 time=1.896 ms
64 bytes from 172.17.2.2: seq=1 ttl=63 time=0.458 ms
--- 172.17.2.2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.458/1.177/1.896 ms

节点2上的容器ping节点1上的容器:

[root@docker02 ~]# docker exec -it bbox02 ping 172.17.1.2 -c2 -w2
PING 172.17.1.2 (172.17.1.2): 56 data bytes
64 bytes from 172.17.1.2: seq=0 ttl=63 time=1.197 ms
64 bytes from 172.17.1.2: seq=1 ttl=63 time=0.528 ms
--- 172.17.1.2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.528/0.862/1.197 ms

节点1上的容器ping节点1和节点2的ip地址:

[root@docker01 ~]# docker exec -it bbox01 ping 192.168.49.41 -c2 -w2
PING 192.168.49.41 (192.168.49.41): 56 data bytes
64 bytes from 192.168.49.41: seq=0 ttl=64 time=0.101 ms
64 bytes from 192.168.49.41: seq=1 ttl=64 time=0.048 ms
--- 192.168.49.41 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.048/0.074/0.101 ms

[root@docker01 ~]# docker exec -it bbox01 ping 192.168.49.42 -c2 -w2
PING 192.168.49.42 (192.168.49.42): 56 data bytes
64 bytes from 192.168.49.42: seq=0 ttl=63 time=0.422 ms
64 bytes from 192.168.49.42: seq=1 ttl=63 time=0.430 ms
--- 192.168.49.42 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.422/0.426/0.430 ms

节点2上的容器ping节点1和节点2的ip地址:

[root@docker02 ~]# docker exec -it bbox02 ping 192.168.49.41 -c2 -w2
PING 192.168.49.41 (192.168.49.41): 56 data bytes
64 bytes from 192.168.49.41: seq=0 ttl=63 time=0.577 ms
64 bytes from 192.168.49.41: seq=1 ttl=63 time=0.549 ms
--- 192.168.49.41 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.549/0.563/0.577 ms

[root@docker02 ~]# docker exec -it bbox02 ping 192.168.49.42 -c2 -w2
PING 192.168.49.42 (192.168.49.42): 56 data bytes
64 bytes from 192.168.49.42: seq=0 ttl=64 time=0.054 ms
64 bytes from 192.168.49.42: seq=1 ttl=64 time=0.044 ms
--- 192.168.49.42 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.044/0.049/0.054 ms

尝试在主机上ping不同主机上的容器网络:

[root@docker02 ~]# ping 172.17.1.2 -c2 -w2
PING 172.17.1.2 (172.17.1.2) 56(84) bytes of data.
64 bytes from 172.17.1.2: icmp_seq=1 ttl=63 time=2.10 ms
64 bytes from 172.17.1.2: icmp_seq=2 ttl=63 time=0.596 ms
--- 172.17.1.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.596/1.351/2.107/0.756 ms
[root@docker02 ~]# ping 172.17.2.2 -c2 -w2
PING 172.17.2.2 (172.17.2.2) 56(84) bytes of data.
64 bytes from 172.17.2.2: icmp_seq=1 ttl=64 time=0.032 ms
64 bytes from 172.17.2.2: icmp_seq=2 ttl=64 time=0.049 ms
--- 172.17.2.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.032/0.040/0.049/0.010 ms
[root@docker01 ~]# ping 172.17.1.2 -c2 -w2
PING 172.17.1.2 (172.17.1.2) 56(84) bytes of data.
64 bytes from 172.17.1.2: icmp_seq=1 ttl=64 time=0.047 ms
64 bytes from 172.17.1.2: icmp_seq=2 ttl=64 time=0.032 ms
--- 172.17.1.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.032/0.039/0.047/0.009 ms
[root@docker01 ~]# ping 172.17.2.2 -c2 -w2
PING 172.17.2.2 (172.17.2.2) 56(84) bytes of data.
64 bytes from 172.17.2.2: icmp_seq=1 ttl=63 time=1.13 ms
64 bytes from 172.17.2.2: icmp_seq=2 ttl=63 time=0.595 ms
--- 172.17.2.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1001ms
rtt min/avg/max/mdev = 0.595/0.866/1.137/0.271 ms



calico方案:

Calico 是一个纯3层协议,支持VM、Docker、Rocket、OpenStack、Kubernetes、或者直接在物理机上使用。官网上给出可以支持上万个主机、上百万的工作负载(container),由于它是纯三层协议,使用BGP协议(基于IP),更易于调试,支持IPv6,支持灵活的安全策略。

工作原理:

Calico把每个操作系统的协议栈认为是一个路由器,然后把所有的容器认为是连在这个路由器上的网络终端,在路由器之间跑标准的路由协议——BGP的协议,然后让它们自己去学习这个网络拓扑该如何转发。所以Calico方案其实是一个纯三层的方案,也就是说让每台机器的协议栈的三层去确保两个容器,跨主机容器之间的三层连通性。

对于控制平面,它每个节点上会运行两个主要的程序,一个是Felix,它会监听ECTD中心的存储,从它获取事件,比如说用户在这台机器上加了一个IP,或者是分配了一个容器等。接着会在这台机器上创建出一个容器,并将其网卡、IP、MAC都设置好,然后在内核的路由表里面写一条,注明这个IP应该到这张网卡。绿色部分是一个标准的路由程序,它会从内核里面获取哪一些IP的路由发生了变化,然后通过标准BGP的路由协议扩散到整个其他的宿主机上,让外界都知道这个IP在这里,你们路由的时候得到这里来。

由于Calico是一种纯三层的实现,因此可以避免与二层方案相关的数据包封装的操作,中间没有任何的NAT,没有任何的overlay,所以它的转发效率可能是所有方案中最高的,因为它的包直接走原生TCP/IP的协议栈,它的隔离也因为这个栈而变得好做。因为TCP/IP的协议栈提供了一整套的防火墙的规则,所以它可以通过IPTABLES的规则达到比较复杂的隔离逻辑。

安装配置:

        环境准备:


IP地址 主机名 Docker版本 系统(内核版本) 部署服务
节点1
192.168.49.41 docker01.contoso.com 1.13.1 CentOS 7(3.10.0-693.el7.x86_64)  docker+etcd+calico
节点2 192.168.49.42 docker02.contoso.com 1.13.1 CentOS 7(3.10.0-693.el7.x86_64)  docker+calico

1)在节点1上安装etcd并启动服务

wget https://github.com/etcd-io/etcd/releases/download/v3.3.12/etcd-v3.3.12-linux-amd64.tar.gz 
tar -zxf etcd-v3.3.12-linux-amd64.tar.gz
cd etcd-v3.3.12-linux-amd64
nohup ./etcd --name kube -listen-client-urls http://0.0.0.0:2379 -advertise-client-urls http://192.168.49.41:2379 > /var/log/etcd.log &

2)分别在两个节点添加docker网络配置cluster-store选项并重启docker服务

vi /etc/sysconfig/docker
OPTIONS="--cluster-store etcd://192.168.49.41:2379" 
systemctl restart docker

3)分别在两个节点安装calico服务

wget https://github.com/projectcalico/calico-containers/releases/download/v1.0.0-beta/calicoctl 
chmod +x calicoctl

4)分别在两个节点启动calico服务

节点1:

[root@docker01 ~]# export ETCD_ENDPOINTS=http://192.168.49.41:2379
[root@docker01 ~]# ./calicoctl node run --name 192.168.49.41

节点2:

[root@docker02 ~]# export ETCD_ENDPOINTS=http://192.168.49.41:2379
[root@docker02 ~]# ./calicoctl node run --name 192.168.49.42

命令实际使用 calico/node 镜像启动了一个容器,执行输出内容如下:

Running command to load modules: modprobe -a xt_set ip6_tables
Enabling IPv4 forwarding
Enabling IPv6 forwarding
Increasing contrack limit
Running the following command:
docker run -d --net=host --privileged --name=calico-node -e HOSTNAME=192.168.49.41 -e IP6= -e AS= -e NO_DEFAULT_POOLS= -e ETCD_AUTHORITY= -e CALICO_LIBNETWORK_ENABLED=true -e IP= -e CALICO_NETWORKING_BACKEND=bird -e ETCD_ENDPOINTS=http://192.168.49.41:2379 -e ETCD_SCHEME= -v /var/log/calico:/var/log/calico -v /var/run/calico:/var/run/calico -v /lib/modules:/lib/modules -v /run/docker/plugins:/run/docker/plugins -v /var/run/docker.sock:/var/run/docker.sock calico/node:v1.0.0-beta

上面的命令需要较长的时间执行,等待执行完毕后,可以查看calicoctl服务节点状态:

节点1:

[root@docker01 ~]# ./calicoctl get node
NAME            
192.168.49.41   
192.168.49.42   
[root@docker01 ~]# ./calicoctl node status
Calico process is running.
IPv4 BGP status
+---------------+-------------------+-------+----------+-------------+
| PEER ADDRESS  |     PEER TYPE     | STATE |  SINCE   |    INFO     |
+---------------+-------------------+-------+----------+-------------+
| 192.168.49.42 | node-to-node mesh | up    | 11:29:54 | Established |
+---------------+-------------------+-------+----------+-------------+
IPv6 BGP status
No IPv6 peers found.

节点2:

[root@docker02 ~]# ./calicoctl get node
NAME            
192.168.49.41   
192.168.49.42   
[root@docker02 ~]# ./calicoctl node status
Calico process is running.
IPv4 BGP status
+---------------+-------------------+-------+----------+-------------+
| PEER ADDRESS  |     PEER TYPE     | STATE |  SINCE   |    INFO     |
+---------------+-------------------+-------+----------+-------------+
| 192.168.49.41 | node-to-node mesh | up    | 11:29:53 | Established |
+---------------+-------------------+-------+----------+-------------+
IPv6 BGP status
No IPv6 peers found.

5)配置网络的ip地址池

默认地址池如下:

[root@docker01 ~]# ./calicoctl get ipPool
CIDR                       
192.168.0.0/16             
fd80:24e2:f998:72d6::/64

使用yml配置文件创建新的地址池(这一步只需在其中一个节点上执行即可):

[root@docker01 ~]# vim calico.yml 
[root@docker01 ~]# cat calico.yml 
- apiVersion: v1
  kind: ipPool
  metadata:
    cidr: 10.10.0.0/16
  spec:
    ipip:
      enabled: true
    nat-outgoing: true
[root@docker01 ~]# ./calicoctl create -f calico.yml 
Successfully created 1 'ipPool' resource(s)
[root@docker01 ~]# ./calicoctl delete ipPool 192.168.0.0/16
Successfully deleted 1 'ipPool' resource(s)

查看新的地址池信息:

节点1:

[root@docker01 ~]# ./calicoctl get ipPool
CIDR                       
10.10.0.0/16               
fd80:24e2:f998:72d6::/64

节点2:

[root@docker02 ~]# ./calicoctl get ipPool
CIDR                       
10.10.0.0/16               
fd80:24e2:f998:72d6::/64

6)创建使用calico驱动的docker网络

注意:只需要在其中一个节点上执行创建命令即可。

[root@docker01 ~]# docker network create --driver calico --ipam-driver calico-ipam calico-net1
4b0c9c48eb67eb6e230047cd0dba15c2baccce1ca71797ed8657fa8e5f1e27dc
[root@docker01 ~]# docker network create --driver calico --ipam-driver calico-ipam calico-net2
59919b1146e41be92825ffa2eb0a5321d1832405d251e5ac1ab3601a32577562

到另一个节点上查看:

[root@docker02 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
0aa898bff668        bridge              bridge              local
4b0c9c48eb67        calico-net1         calico              global
59919b1146e4        calico-net2         calico              global
43fd42bc0f76        host                host                local
364fc46102ac        none                null                local

7)创建容器,测试是否能互相通信

节点1:

[root@docker01 ~]# docker run -itd --net calico-net1 --name node1-box1 busybox
e1247a2cc11aea3f406539bf4844c8457ba54ecfacec8e1bb5faae6ee974a11c
[root@docker01 ~]# docker run -itd --net calico-net2 --name node1-box2 busybox
57216461e843230ee127d6fd4866336564c43eeb1192c671ecb92bc728e26b7d
[root@docker01 ~]# docker run -itd --net calico-net1 --name node1-box3 busybox
6c61ae89d83436379936ce5aa015bf21f731e14d83e5ba2eda44b21ea426062d

节点2:

[root@docker02 ~]# docker run -itd --net calico-net1 --name node2-box1 busybox
51e7cf1b48a4ae4ac3317328df2d0e4269caec337bd6da279d6bf5e6ab9fca7e
[root@docker02 ~]# docker run -itd --net calico-net2 --name node2-box2 busybox
25806aee00b4186b4ce8cf67f61e3b1a5230a962974e4e391b024953dc042263

同主机同一网络通信:

[root@docker01 ~]# docker exec -it node1-box1 ping node1-box3 -c2 -w2
PING node1-box3 (10.10.175.2): 56 data bytes
64 bytes from 10.10.175.2: seq=0 ttl=63 time=0.098 ms
64 bytes from 10.10.175.2: seq=1 ttl=63 time=0.124 ms
--- node1-box3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.098/0.111/0.124 ms

同主机不同网络通信:

[root@docker01 ~]# docker exec -it node1-box1 ping node1-box2 -c2 -w2
ping: bad address 'node1-box2'

跨主机同一网络通信:

[root@docker01 ~]# docker exec -it node1-box1 ping node2-box1 -c2 -w2
PING node2-box1 (10.10.179.128): 56 data bytes
64 bytes from 10.10.179.128: seq=0 ttl=62 time=0.551 ms
64 bytes from 10.10.179.128: seq=1 ttl=62 time=0.315 ms
--- node2-box1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.315/0.433/0.551 ms

跨主机不同网络通信:

[root@docker01 ~]# docker exec -it node1-box1 ping node2-box2 -c2 -w2
ping: bad address 'node2-box2'