docker swarm网络模式

docker swarm 网络模式

swarm的三个网络

名称 类型 注释
docker_gwbridge bridge none
ingress overlay none
<custom-network> overlay none
  • docker_gwbridge和ingress是swarm自动创建的,当用户执行了docker swarm init/connect之后。
  • docker_gwbridge是bridge类型的负责本机container和主机直接的连接
  • ingress负责service在多个主机container之间的路由。
  • <custom-network> 是用户自己创建的overlay网络,通常我们都需要创建自己的network并把service挂在上面。

swarm service的路由办法通常有两种,VIP和DSN

service路由之:虚拟IP

这是缺省情况设置,当用户创建service的时候,这个service会被分配一个VIP,然后每一个具体的container都有一个独立的IP,ingress会负责从VIP到各个container之间的路由。

举例来说:

  1. 创建网络
$ docker network create --driver overlay my-network
kw3iy5w8ws7l568fe2o0ntpgw
$ docker network inspect my-network
[
    {
        "Name": "my-network",
        "Id": "kw3iy5w8ws7l568fe2o0ntpgw",
        ...,
        "IPAM": {
            ...,
            "Config": [
                {
                    "Subnet": "10.0.1.0/24",
                    "Gateway": "10.0.1.1"
                }
            ]
        },

并且看到了它的属性。

创建两个service:

$ docker service create --replicas 2 --network my-network --name my-web nginx
$ docker service create --replicas 1 --network my-network --name my-box busybox sleep 3000

nslookup查看域名解析:

$ docker ps | grep my-box
d0c2c0c88e20        busybox:latest      "sleep 3000"             32 seconds ago       Up 30 seconds                           my-box.1.rbdxb9ta7uk0606u7qw25wypc
$ docker exec -it d0c2c0c88e20 sh

/ # nslookup my-web     # 查看service的虚IP
Server:     127.0.0.11
Address:    127.0.0.11:53

Non-authoritative answer:
Name:   my-web
Address: 10.0.1.2             # 10.0.1.2就是service my-web的虚IP


/ # nslookup tasks.my-web        # 这个命令查看所有的tasks,即containers
Server:     127.0.0.11
Address:    127.0.0.11:53

Non-authoritative answer:
Name:   tasks.my-web
Address: 10.0.1.4
Name:   tasks.my-web
Address: 10.0.1.3


/ # nslookup 10.0.1.2
Server:     127.0.0.11
Address:    127.0.0.11:53

** server can't find 2.1.0.10.in-addr.arpa: NXDOMAIN

/ # nslookup 10.0.1.3
Server:     127.0.0.11
Address:    127.0.0.11:53

Non-authoritative answer:
3.1.0.10.in-addr.arpa   name = my-web.1.61t2nfcofsh3sqxarydp1tobi.my-network

/ # nslookup 10.0.1.4
Server:     127.0.0.11
Address:    127.0.0.11:53

Non-authoritative answer:
4.1.0.10.in-addr.arpa   name = my-web.2.3ngpbetri2v6jb84wysud76ux.my-network

从这个例子我们可以看到:

  1. service my-web的虚拟IP是10.0.1.2
  2. 它有两个containers,IP分别是:10.0.1.3 和 10.0.1.4
  3. 127.0.0.11是swarm内置的DSN服务器,用来解析service名字到IP地址

我们再进入container看看:

$ docker exec -it my-web.1.61t2nfcofsh3sqxarydp1tobi bash
root@1a55df476e01:/tools/tools# ./ifconfig 
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
        inet 10.0.1.3  netmask 255.255.255.0  broadcast 10.0.1.255
        ether 02:42:0a:00:01:03  txqueuelen 0  (Ethernet)
        ...
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.18.0.4  netmask 255.255.0.0  broadcast 172.18.255.255
        ether 02:42:ac:12:00:04  txqueuelen 0  (Ethernet)
        ...
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        ...

每一个container有两块网卡:
eth0: 10.0.1.3 这就是我们前面看到的service container IP地址,是属于网络my-network的。
eth1: 172.18.0.4,这是另一个网络地址;是谁的呢, 是网络docker_gwbridge。(另外bridge网络使用的是172.17网段)
也就是说每一个container属于两个网络,my-network和docker_gwbridge,分别用来service路由,和连接主机网络。

补充一点网卡eth1: 172.18.0.4,对应的网关地址是172.18.0.1,那个这个网关地址172.18.0.1是谁呢,它就是主机网络上的docker_gwbridge,在主机上运行ifconfig可以看到:

$ ifconfig 
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:4bff:fe9a:8b9a  prefixlen 64  scopeid 0x20<link>
        ether 02:42:4b:9a:8b:9a  txqueuelen 0  (Ethernet)
        ...
docker_gwbridge: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.18.0.1  netmask 255.255.0.0  broadcast 172.18.255.255
        inet6 fe80::42:cfff:fedc:ca8  prefixlen 64  scopeid 0x20<link>
        ether 02:42:cf:dc:0c:a8  txqueuelen 0  (Ethernet)
        ...

bridge网络的网段地址从172.17.X.X/16开始,第一个内置的docker0使用了172.17.X.X,后面每新增一个bridge网络就新增一个网地址,172.18.X.X, 172.19.X.X,。。。

至此两个bridge网络都比较清楚了。

另外如果发布service的时候指定了主机端口映射,那么container里面会有三块网卡分别属于:

  1. <my-network>
  2. docker_gwbridge
  3. ingress, 其网段是10.255.X.X,每一个service在ingress上也有一个VIP,例如VIP=10.255.0.2,对映两个container:10.255.0.3和10.255.0.4

做一个总结:

image.png

发布service的时候:

  1. 如果指定了--publish端口,那么会在ingress网络中创建接口,并产生路由信息。
  2. 如果指定了--network网络,那么会在指定网络里面创建接口,并产业路由信息。
  3. 如果都没有指定,实际上相当于没有通信,不和主机通信,互相之间也不通信。
  4. 如果两者都指定了,那么在两处均创建接口。
  5. 如果没有指定--network网络,那么无法通过service名字寻址,例如curl my-web:80将无法访问;所以通常来说创建swarm service都需要指定一个overlay网络。

注意swarm VIP使用的一个限制:

Swarm routes requests for the VIP in a round robin fashion at L4.
This means that the following Interlock features are incompatible with VIP mode:

* Sticky sessions

也就是说无法做到同一个client过来的请求保持路由到同一个container去。

service路由之:DSN轮询

适合使用自己的DSN Load-Balance算法,例如HAProxy。

创建使用DSN轮询的service。

$ docker service create --replicas 2 --network my-network --name my-dnsrr-web --endpoint-mode dnsrr nginx

由参数--endpoint-mode决定。

先看一下两个container的ip 地址:

# ifconfig  # container 1
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
        inet 10.0.1.28  netmask 255.255.255.0  broadcast 10.0.1.255
        ether 02:42:0a:00:01:1c  txqueuelen 0  (Ethernet)
        ...
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.18.0.7  netmask 255.255.0.0  broadcast 172.18.255.255
        ether 02:42:ac:12:00:07  txqueuelen 0  (Ethernet)
        ...
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 0  (Local Loopback)
        ...

# ifconfig  # container 2
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1450
        inet 10.0.1.29  netmask 255.255.255.0  broadcast 10.0.1.255
        ether 02:42:0a:00:01:1d  txqueuelen 0  (Ethernet)
        ...
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.18.0.6  netmask 255.255.0.0  broadcast 172.18.255.255
        ether 02:42:ac:12:00:06  txqueuelen 0  (Ethernet)
        ...
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 0  (Local Loopback)
        ...

两个contaienr的ip 地址分别是:

  1. my-dnsrr-web.1.6a1xknrmh8rxnlvwftuzytwxp: eth0 10.0.1.28, eth1 172.18.0.7
  2. my-dnsrr-web.2.i5sgozdgtj4vs6ahok9wxs1o3: eth0 10.0.1.29, eth1: 172.18.0.6

再看DSN解析结果:

# ping my-dnsrr-web
PING my-dnsrr-web (10.0.1.28) 56(84) bytes of data.
64 bytes from 0cd9f35e6082 (10.0.1.28): icmp_seq=1 ttl=64 time=0.043 ms
64 bytes from 0cd9f35e6082 (10.0.1.28): icmp_seq=2 ttl=64 time=0.040 ms

# ping my-dnsrr-web
PING my-dnsrr-web (10.0.1.29) 56(84) bytes of data.
64 bytes from my-dnsrr-web.2.i5sgozdgtj4vs6ahok9wxs1o3.my-network (10.0.1.29): icmp_seq=1 ttl=64 time=0.096 ms
64 bytes from cf75bccfbacd.my-network (10.0.1.29): icmp_seq=2 ttl=64 time=0.070 ms

# ping my-dnsrr-web
PING my-dnsrr-web (10.0.1.28) 56(84) bytes of data.
64 bytes from 0cd9f35e6082 (10.0.1.28): icmp_seq=1 ttl=64 time=0.024 ms
64 bytes from 0cd9f35e6082 (10.0.1.28): icmp_seq=2 ttl=64 time=0.041 ms

# ping my-dnsrr-web
PING my-dnsrr-web (10.0.1.29) 56(84) bytes of data.
64 bytes from my-dnsrr-web.2.i5sgozdgtj4vs6ahok9wxs1o3.my-network (10.0.1.29): icmp_seq=1 ttl=64 time=0.061 ms
64 bytes from my-dnsrr-web.2.i5sgozdgtj4vs6ahok9wxs1o3.my-network (10.0.1.29): icmp_seq=2 ttl=64 time=0.051 ms

# ping my-dnsrr-web
PING my-dnsrr-web (10.0.1.28) 56(84) bytes of data.
64 bytes from 0cd9f35e6082 (10.0.1.28): icmp_seq=1 ttl=64 time=0.022 ms
64 bytes from 0cd9f35e6082 (10.0.1.28): icmp_seq=2 ttl=64 time=0.022 ms

# ping my-dnsrr-web
PING my-dnsrr-web (10.0.1.29) 56(84) bytes of data.
64 bytes from cf75bccfbacd.my-network (10.0.1.29): icmp_seq=1 ttl=64 time=0.063 ms

每次运行ping解析出的IP地址在两个container之间轮换,也就没有虚IP概念了,而且swarm自动实现了DSN轮询的功能。

再看一个nslookup结果:

# nslookup my-dnsrr-web
Server:     127.0.0.11
Address:    127.0.0.11#53

Non-authoritative answer:
Name:   my-dnsrr-web
Address: 10.0.1.28
Name:   my-dnsrr-web
Address: 10.0.1.29

可见nslookup直接把两个container的地址都解析出来,说明一个域名(service name)对映有两个IP地址。对照前面使用VIP的,一个service name只对映一个IP地址,就是VIP地址,而不管具体有多少个container实例。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • docker-swarm本身就支持容器跨主机通信 实验环境为,一个主节点manager,2个从节点 node1,n...
    向上的路阅读 3,405评论 0 2
  • Docker 提供了 overlay driver,使用户可以创建基于 VxLAN 的 overlay 网络。Vx...
    Feel_狗焕阅读 12,852评论 9 10
  • 容器集群 swarm 容器生态包含三个部分 容器核心知识 架构、镜像、容器、网络、存储容器平台技术 容...
    why_not_阅读 1,973评论 0 2
  • 天气:大太阳和小雨很搭哦 莫要忘记的三件事:1.坚持简书打卡2.坚持简书打卡3.重复上面两件事 学习·工作·思考 ...
    君子之不器阅读 109评论 0 6
  • 2017-08-24 中医师表示,当体内湿气过重时,中医称为「湿邪」,湿邪容易导致气血不畅通,除了会让人觉得身体沉...
    a09546ae1403阅读 581评论 0 0