[Kubernetes]Docker的overlay网络模型

上一篇文章[Kubernetes]Docker的网络模型较详细介绍了Docker里的bridge网络模型。本篇介绍Docker的overlay网络模型。Docker内置overlay网路模式驱动libnetwork,可以用于创建跨多个主机的网络。在同一个overlay网络里的容器,无论运行在哪个主机上,都能相互通信。

环境准备

官方文档Getting started for overlay里使用Docker Machine和Docker Swarm来完成Docker跨主机网络的搭建。其实Docker Machine和Docker Swarm并不是必须的。只要有key-value存储服务器和运行了Docker引擎的主机就能完成搭建。作者的环境由两台主机构成:

主机名:DockerVM1,IP地址为192.168.31.127
主机名:DockerVM2,IP地址为192.168.31.234

两台主机上都安装了Docker引擎。主机DockerVM1上还运行了提供key-value存储服务的ZooKeeper

启动Docker

在启动DockerVM1和DockerVM2上的Docker之前,先查看一下两台主机的网络。

DockerVM1的网络:

felix@DockerVM1:~$ ifconfig
docker0   Link encap:Ethernet  HWaddr 02:42:84:50:1c:53  
          inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          UP BROADCAST MULTICAST  MTU:1500  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:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)


ens33     Link encap:Ethernet  HWaddr 00:0c:29:85:ea:81  
          inet addr:192.168.31.127  Bcast:192.168.31.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe85:ea81/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3767 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2498 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:425605 (425.6 KB)  TX bytes:309416 (309.4 KB)


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:8196 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8196 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1 
          RX bytes:554285 (554.2 KB)  TX bytes:554285 (554.2 KB)

DockerVM2的网络:

felix@DockerVM2:~$ ifconfig
docker0   Link encap:Ethernet  HWaddr 02:42:36:97:28:50  
          inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          UP BROADCAST MULTICAST  MTU:1500  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:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)


ens33     Link encap:Ethernet  HWaddr 00:0c:29:13:31:92  
          inet addr:192.168.31.234  Bcast:192.168.31.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe13:3192/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:19063 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9883 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:21820964 (21.8 MB)  TX bytes:894107 (894.1 KB)


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:160 errors:0 dropped:0 overruns:0 frame:0
          TX packets:160 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1 
          RX bytes:11840 (11.8 KB)  TX bytes:11840 (11.8 KB)

可以看到,两台主机上都有一个网络接口叫ens33,两台主机都通过该接口访问同一个网络192.168.31.0/24.

现在启动DockerVM1的Docker引擎:

felix@DockerVM1:~$ /usr/bin/docker daemon -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock --cluster-store=zk://192.168.31.127:2181 --cluster-advertise=ens33:2376

在Docker的启动选项里,-H tcp://0.0.0.0:2376表示Docker引擎监听所有网络接口上的2376端口,--cluster-store指定了ZooKeeper服务,--cluster-advertise表示Docker引擎要注册的网络接口。在这里,注册的是DockerVM1上ens33网络接口的2376端口。

启动DockerVM1的Docker引擎后,查看一下Docker的网络信息和主机DockerVM1的网络信息:

felix@DockerVM1:~$ docker network list
NETWORK ID          NAME                DRIVER              SCOPE
6e38f3735bbb        bridge              bridge              local               
317ff4bce36c        host                host                local               
69dfc5302c2a        none                null                local 
felix@DockerVM1:~$ ifconfig
docker0   Link encap:Ethernet  HWaddr 02:42:84:50:1c:53  
          inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          UP BROADCAST MULTICAST  MTU:1500  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:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)


ens33     Link encap:Ethernet  HWaddr 00:0c:29:85:ea:81  
          inet addr:192.168.31.127  Bcast:192.168.31.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe85:ea81/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:3767 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2498 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:425605 (425.6 KB)  TX bytes:309416 (309.4 KB)


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:8196 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8196 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1 
          RX bytes:554285 (554.2 KB)  TX bytes:554285 (554.2 KB)

可以看到,Docker启动后,Docker的网络和主机DockerVM1的网络并没有发生变化。我们再看看DockerVM1上运行的Docker的详细信息

felix@DockerVM1:~$ docker info
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 0
Server Version: 1.12.0
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 0
 Dirperm1 Supported: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
  Network: host null overlay bridge
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Security Options: apparmor seccomp
Kernel Version: 4.4.0-31-generic
Operating System: Ubuntu 16.04.1 LTS
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 975 MiB
Name: DockerVM1
ID: JERI:GJ6B:BXSQ:WVZZ:HIEQ:5FMO:RSDQ:LMYY:RCFB:QO77:PT4M:VCMB
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
WARNING: No swap limit support
Cluster Store: zk://192.168.31.127:2181
Cluster Advertise: 192.168.31.127:2376
Insecure Registries:
 127.0.0.0/8

从Docker的详细信息里可以看到Docker当前支持的网络模式有host null overlay bridge四种,Cluster Store为ZooKeeper服务器的地址zk://192.168.31.127:2181,Cluster Advertise为192.168.31.127:2376

类似的,我们在另一台主机DockerVM2上启动Docker引擎:

felix@DockerVM2:~$ /usr/bin/docker daemon -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock --cluster-store=zk://192.168.31.127:2181 --cluster-advertise=ens33:2376

参照前面的命令去查看DockerVM2主机上的Docker网络信息和主机网络信息,也会发现没有什么变化。查看一下DockerVM2上运行的Docker的详细信息

felix@DockerVM2:~$ docker info 
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 0
Server Version: 1.12.0
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 0
 Dirperm1 Supported: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: bridge host null overlay
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Security Options: apparmor seccomp
Kernel Version: 4.4.0-31-generic
Operating System: Ubuntu 16.04.1 LTS
OSType: linux
Architecture: x86_64
CPUs: 2
Total Memory: 975 MiB
Name: DockerVM2
ID: 5Q23:L4J5:2VAA:ANJA:FR6O:JK3B:PALZ:QIXG:T2V5:B4SQ:FZ4U:W4VE
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
WARNING: No swap limit support
Cluster Store: zk://192.168.31.127:2181
Cluster Advertise: 192.168.31.234:2376
Insecure Registries:
 127.0.0.0/8

现在一起来看看ZooKeeper上的数据。如下图,ZooKeeper上多出了一个docker根节点。docker根节点下的数据如下图:


可以看到,各主机上的Docker注册在了/docker/nodes下,以Cluster Advertise的值作为了/docker/nodes下节点的名称和Data. 细心的读者还能看到,/docker/network/v1.0/endpoint下的部分节点名称与Docker的none, host网络ID匹配:

DockerVM1的none网络 /docker/network/v1.0/endpoint/69dfc5302c2a96a5e74e52043504978018f02b963cea98cfa3df5d879dee793d 
DockerVM1的host网络 /docker/network/v1.0/endpoint/317ff4bce36cf21bb1dcac174c30001e0983f81038233468fb34574051e8e1f2 
DockerVM2的none网络 /docker/network/v1.0/endpoint/a4fd0797dcafe0d8c6efbd7a62fadac2b2b43a08c105c5e44449edb5fe97671e 
DockerVM2的host网络 /docker/network/v1.0/endpoint/30c2fe9c4d768a5261b063f532a4bb59ab1662f45c3a4ca0e1262716c569bafd 

创建一个overlay网络

可以在任意的主机上用docker network create命令创建一个overlay网络了。笔者选择在DockerVM1上创建一个名为my-net的overlay网络10.0.9.0/24:

felix@DockerVM1:~$ docker network create --driver overlay --subnet=10.0.9.0/24 my-net
873c9352d3cc0d34e5d065ccec9bdda6a2bc93dcce0c8b256f748e641e162449

创建出来的my-net网络在任意的主机上都能看到,例如在DockerVM2上用docker network list命令查看:

felix@DockerVM2:~$ docker network list
NETWORK ID          NAME                DRIVER              SCOPE
6e38f3735bbb        bridge              bridge              local               
317ff4bce36c        host                host                local               
873c9352d3cc        my-net              overlay             global 
69dfc5302c2a        none                null                local

如果此时在DockerVM1或DockerVM2上用ifconfig查看网络信息,会发现主机的网络还是没有变化。

现在一起来看看ZooKeeper上的数据。如下图,/docker/network节点下多出了很多东西:

/docker/network/v1.0/endpoint节点下又多出来了若干节点,仔细看看,不难发现多出来的节点里和Docker的bridge, my-net网络ID匹配:

my-net网络            /docker/network/v1.0/endpoint/873c9352d3cc0d34e5d065ccec9bdda6a2bc93dcce0c8b256f748e641e162449
DockerVM1的bridge网络 /docker/network/v1.0/endpoint/6e38f3735bbbae7ef83d2cb79f71e8a4fbf1f4cce4a90187bb7e5ff5cca58162
DockerVM2的bridge网络 /docker/network/v1.0/endpoint/e6c6f753962f695d39b364a127d8196df44dfdb68fbdce3262598dc51f7bea7a

其他多出来的节点的名称和my-net网络的ID相同,可以推测这些节点存储的是my-net网络的信息。展现如下:

/docker/network/v1.0/endpoint_count/873c9352d3cc0d34e5d065ccec9bdda6a2bc93dcce0c8b256f748e641e162449
{"Count":0}
/docker/network/v1.0/idm/vxlan-id
{
    "id" : "vxlan-id",
    "sequence" : "AAAAAAD//wAAAAAAAP//AAAAAAAAAAAAAAf/+A=="
}
/docker/network/v1.0/ipam/default/config/GlobalDefault
{
    "Scope" : "global",
    "Subnets" : {
        "GlobalDefault/10.0.9.0/24" : {
            "ParentKey" : {
                "AddressSpace" : "",
                "Subnet" : "",
                "ChildSubnet" : ""
            },
            "Pool" : "10.0.9.0/24",
            "RefCount" : 1
        }
    }
}
/docker/network/v1.0/ipam/default/config/data/GlobalDefault/10.0.9.0/24
{
    "id" : "GlobalDefault/10.0.9.0/24",
    "sequence" : "AAAAAAAAAQAAAAAAAAAA/cAAAAAAAAAAAAAAAQAAAAAAAAAAAAAABgAAAAEAAAAAAAAAAQ=="
}
/docker/network/v1.0/network/873c9352d3cc0d34e5d065ccec9bdda6a2bc93dcce0c8b256f748e641e162449
{
    "addrSpace" : "GlobalDefault",
    "enableIPv6" : false,
    "generic" : {
        "com.docker.network.enable_ipv6" : false,
        "com.docker.network.generic" : {}
    },
    "id" : "873c9352d3cc0d34e5d065ccec9bdda6a2bc93dcce0c8b256f748e641e162449",
    "inDelete" : false,
    "ingress" : false,
    "internal" : false,
    "ipamOptions" : {},
    "ipamType" : "default",
    "ipamV4Config" : "[{\"PreferredPool\":\"10.0.9.0/24\",\"SubPool\":\"\",\"Gateway\":\"\",\"AuxAddresses\":null}]",
    "ipamV4Info" : "[{\"IPAMData\":\"{\\\"AddressSpace\\\":\\\"GlobalDefault\\\",\\\"Gateway\\\":\\\"10.0.9.1/24\\\",\\\"Pool\\\":\\\"10.0.9.0/24\\\"}\",\"PoolID\":\"GlobalDefault/10.0.9.0/24\"}]",
    "labels" : {},
    "name" : "my-net",
    "networkType" : "overlay",
    "persist" : true,
    "postIPv6" : false,
    "scope" : "global"
}
/docker/network/v1.0/overlay/network/873c9352d3cc0d34e5d065ccec9bdda6a2bc93dcce0c8b256f748e641e162449
{
    "mtu" : 0,
    "secure" : false,
    "subnets" : [{
        "SubnetIP" : "10.0.9.0/24",
        "GwIP" : "10.0.9.1/24",
        "Vni" : 0
        }
    ]
}

在overlay网络上创建容器

笔者首先在DockerVM1上创建了一个容器container1,运行在my-net网络:

felix@DockerVM1:~$ docker run -itd --net=my-net --name container1 busybox
10d4bf6d5b01f46eaced0cfd56f4b74e5d5a03795cbaf8619ea376d68b119801

创建容器container1后,查看一下Docker的网络信息和主机DockerVM1的网络信息:

felix@DockerVM1:~$ docker network list
NETWORK ID          NAME                DRIVER              SCOPE
a4fe710b3361        bridge              bridge              local               
260241dd0562        docker_gwbridge     bridge              local             
317ff4bce36c        host                host                local               
873c9352d3cc        my-net              overlay             global              
69dfc5302c2a        none                null                local
felix@DockerVM1:~$ ifconfig
docker0   Link encap:Ethernet  HWaddr 02:42:84:50:1c:53  
          inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          UP BROADCAST MULTICAST  MTU:1500  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:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)


docker_gwbridge Link encap:Ethernet  HWaddr 02:42:6d:8c:ca:a0  
          inet addr:172.18.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:6dff:fe8c:caa0/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:7 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:536 (536.0 B)  TX bytes:558 (558.0 B)


ens33     Link encap:Ethernet  HWaddr 00:0c:29:85:ea:81  
          inet addr:192.168.31.127  Bcast:192.168.31.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe85:ea81/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:42383 errors:0 dropped:0 overruns:0 frame:0
          TX packets:29433 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:6222908 (6.2 MB)  TX bytes:3442655 (3.4 MB)


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:29130 errors:0 dropped:0 overruns:0 frame:0
          TX packets:29130 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1 
          RX bytes:2004034 (2.0 MB)  TX bytes:2004034 (2.0 MB)


vetha2fc675 Link encap:Ethernet  HWaddr e6:9d:27:4e:62:b5  
          inet6 addr: fe80::e49d:27ff:fe4e:62b5/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:13 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:648 (648.0 B)  TX bytes:1038 (1.0 KB)

创建容器container1后,主机DockerVM1上的Docker的网络里多出了一个bridge模式的网络docker_gwbridge,DockerVM1主机也多出了docker_gwbridge和vetha2fc675两个网络接口。其中docker_gwbridge与Docker里多出的网络对应。用docker network inspect命令分别查看my-net和docker_gwbridge:

felix@DockerVM1:~$ docker network inspect my-net
[
    {
        "Name": "my-net",
        "Id": "873c9352d3cc0d34e5d065ccec9bdda6a2bc93dcce0c8b256f748e641e162449",
        "Scope": "global",
        "Driver": "overlay",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "10.0.9.0/24"
                }
            ]
        },
        "Internal": false,
        "Containers": {
            "10d4bf6d5b01f46eaced0cfd56f4b74e5d5a03795cbaf8619ea376d68b119801": {
                "Name": "container1",
                "EndpointID": "0db4894742a1dd81fcfe46bc321f0d78c49945e139b7bdc14855bf2bd7690e0c",
                "MacAddress": "02:42:0a:00:09:02",
                "IPv4Address": "10.0.9.2/24",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
felix@DockerVM1:~$ docker network inspect docker_gwbridge
[
    {
        "Name": "docker_gwbridge",
        "Id": "260241dd0562f995c3586fea22ed2473a04dfb8132830e57f1815a64779072f8",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1/16"
                }
            ]
        },
        "Internal": false,
        "Containers": {
            "10d4bf6d5b01f46eaced0cfd56f4b74e5d5a03795cbaf8619ea376d68b119801": {
                "Name": "gateway_10d4bf6d5b01",
                "EndpointID": "de8ec4a0140c8b4c0105d965e7f66185018003c627a45fab3caf012c612ee5d2",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.enable_icc": "false",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.name": "docker_gwbridge"
        },
        "Labels": {}
    }
]

可以看到,container1同时运行在my-net和docker_gwbridge网络里,在my-net网络里,container1的IP地址为10.0.9.2/24,在docker_gwbridge网络里,container1的IP地址为172.18.0.2/16. 值得注意的是,container1在两个网络里都有一个EndpointID.

用docker attach命令连上container1查看它的网络信息:

felix@DockerVM1:~$ docker attach container1
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:0A:00:09:02  
          inet addr:10.0.9.2  Bcast:0.0.0.0  Mask:255.255.255.0
          inet6 addr: fe80::42:aff:fe00:902/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1450  Metric:1
          RX packets:13 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:1038 (1.0 KiB)  TX bytes:648 (648.0 B)


eth1      Link encap:Ethernet  HWaddr 02:42:AC:12:00:02  
          inet addr:172.18.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::42:acff:fe12:2/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:13 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:1038 (1.0 KiB)  TX bytes:648 (648.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)


/ # cat /etc/hosts
127.0.0.1    localhost
::1          localhost ip6-localhost ip6-loopback
fe00::0      ip6-localnet
ff00::0      ip6-mcastprefix
ff02::1      ip6-allnodes
ff02::2      ip6-allrouters
10.0.9.2     10d4bf6d5b01
172.18.0.2   10d4bf6d5b01

可以看到,container1里有两个网络接口eth0和eth1,分别对应container1所在的my-net网络和docker_gwbridge网络。

此刻,另一台主机DockerVM2上还没有创建任何运行在my-net网络里的容器。笔者很好奇DockerVM2的网络是否发生了变化。用ifconfig和docker network list命令查看,发现DockerVM2的网络并没有发生变化:主机上没有信息的网络接口产生,Docker网络里没有多出新的网络。在DockerVM2上用docker network inspect my-net能看到和在DockerVM1上运行docker network inspect my-net命令所看到的my-net网络内容及该网络上运行的容器信息。

再来看看ZooKeeper服务器上的数据发生了什么变化。如下图。

/docker/network/v1.0/endpoint/873c9352d3cc0d34e5d065ccec9bdda6a2bc93dcce0c8b256f748e641e162449下多出了一个子节点,并且子节点的名称正是container1在my-net网络里的EndpointID. 这个节点里存储的数据如下:

{
    "anonymous" : false,
    "disableResolution" : false,
    "ep_iface" : {
        "addr" : "10.0.9.2/24",
        "dstPrefix" : "eth",
        "mac" : "02:42:0a:00:09:02",
        "routes" : null,
        "srcName" : "veth0b42de0",
        "v4PoolID" : "GlobalDefault/10.0.9.0/24",
        "v6PoolID" : ""
    },
    "exposed_ports" : [],
    "generic" : {
        "com.docker.network.endpoint.exposedports" : [],
        "com.docker.network.portmap" : []
    },
    "id" : "0db4894742a1dd81fcfe46bc321f0d78c49945e139b7bdc14855bf2bd7690e0c",
    "ingressPorts" : null,
    "joinInfo" : {
        "StaticRoutes" : null,
        "disableGatewayService" : false
    },
    "locator" : "192.168.31.127",
    "myAliases" : ["10d4bf6d5b01"],
    "name" : "container1",
    "sandbox" : "e7a0774608d4abac024ab0a63902f1e52087d4bd26d3c965adae173df137f6c2",
    "svcAliases" : null,
    "svcID" : "",
    "svcName" : "",
    "virtualIP" : "\u003cnil\u003e"
}

这个节点的数据里记录了container1的IP地址为10.0.9.2/24,locator字段指出了container1所在主机IP为192.168.31.127,这证实了作者在上一篇文章里的猜想:“Docker的overlay网络的原理应该是在key-value存储服务器上创建了ip地址表,当overlay网络里的容器相互通信时,通过查找key-value服务器上的ip地址标来找到目标容器所在的主机地址,经过地址转换(NAT)完成通信。”

我们还能看到/docker/network/v1.0/endpoint_count/873c9352d3cc0d34e5d065ccec9bdda6a2bc93dcce0c8b256f748e641e162449里存储的数据变更为了{"Count":1}

类似的,在另一个主机DockerVM2上创建一个容器container2,运行在my-net网络:

felix@DockerVM2:~$ docker run -itd --net=my-net --name container2 busybox
99a3a82ba4fe97706392d91a940a5d42bc4e5871274b14037c0382bc62ae4b2c

遵循前面提到的方法去查看DockerVM2的网络信息和容器信息,会得到和DockerVM1类似的结果,这些步骤留给读者去实践查看。

在主机DockerVM2上的container2容器里用ping去测试主机DockerVM1里的container1:

felix@DockerVM2:~$ docker attach container2
/ # ping -w3 10.0.9.2
PING 10.0.9.2 (10.0.9.2): 56 data bytes
64 bytes from 10.0.9.2: seq=0 ttl=64 time=36.530 ms
64 bytes from 10.0.9.2: seq=1 ttl=64 time=5.953 ms
64 bytes from 10.0.9.2: seq=2 ttl=64 time=5.284 ms


--- 10.0.9.2 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 5.284/15.922/36.530 ms

这说明同在my-net网络里的容器container1和容器container2是互通的。

阅读更多 登录后自动展开
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页