暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Docker swarm(6)swarm网络配置

运维笔记本 2020-01-24
7922

一,swarm的三个网络

名称类型注释
docker_gwbridgebridgenone
ingressoverlaynone
<custom-network>
overlaynone

Docker中内置的网络模式包括如下几种:

  • bridge 我们基于该网络模式创建了mynet网络
  • host 本地网络模式
  • macvlan 这个模式貌似是最新加的
  • null 无网络
  • overlay 用于swarm集群中容器的跨主机网络访问

docker_gwbridge和ingress是当用户执行了docker swarm init/connect之后自动创建的。

  1. docker_gwbridge是bridge类型的负责本机container和主机直接的连接。docker_gwbridge是一种桥接网络,将 overlay 网络(包括 ingress 网络)连接到一个单独的 Docker 守护进程的物理网络。默认情况下,服务正在运行的每个容器都连接到本地 Docker 守护进程主机的 docker_gwbridge 网络。docker_gwbridge 网络在初始化或加入 Swarm 时自动创建。大多数情况下,用户不需要自定义配置,但是 Docker 允许自定义。
  2. ingress负责service在多个主机container之间的路由。ingress network 是一个特殊的 overlay 网络,用于服务节点间的负载均衡。当任何 Swarm 节点在发布的端口上接收到请求时,它将该请求交给一个名为 IPVS 的模块。IPVS 跟踪参与该服务的所有IP地址,选择其中的一个,并通过 ingress 网络将请求路由到它。初始化或加入 Swarm 集群时会自动创建 ingress 网络,大多数情况下,用户不需要自定义配置,但是 docker 17.05 和更高版本允许你自定义。
  3. <custom-network>
    是用户自己创建的overlay网络,通常我们都需要创建自己的network并把service挂在上面。
  • Overlay networks 管理 Swarm 中 Docker 守护进程间的通信。你可以将服务附加到一个或多个已存在的 overlay 网络上,使得服务与服务之间能够通信。

二,swarm service的路由

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

(一) service路由之:虚拟IP

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

Overlay 网络创建及部署

    docker network create --driver overlay mynet


    docker@manager1:~$ docker network ls
    NETWORK ID NAME DRIVER SCOPE
    669d98d758ac bridge bridge local
    042df78b01ec docker_gwbridge bridge local
    1c27fcf531c2 host host local
    95e47qzos7zn ingress overlay swarm
    pybpdb2fibky my-network overlay swarm
    i5xm0y9n835s mynet overlay swarm
    37d3b44c34e2 none null local


    复制

    创建新服务并使用 overlay 网络

    创建两个service

      docker@manager1:~$ docker service create --replicas 2 --network mynet --name my-web nginx                                                                     
      lpgc43imsl1s3iocgcpy3dhkm
      overall progress: 2 out of 2 tasks
      1/2: running [==================================================>]
      2/2: running [==================================================>]
      verify: Service converged
      docker@manager1:~$ docker service create --replicas 1 --network mynet --name my-box busybox:1.28.3 sleep 3000
      overall progress: 1 out of 1 tasks
      1/1: running [==================================================>]
      verify: Service converged


      复制

      部署完成之后 查看 my-web 服务的虚拟IP 地址

        docker service inspect my-web -f "{{ .Endpoint.VirtualIPs }}"
        复制
          docker@manager1:~$ docker service inspect my-web -f "{{ .Endpoint.VirtualIPs }}"
          [{pybpdb2fibkyk9jklcjqkrch7 10.0.1.2/24}]
          docker@manager1:~$ docker service inspect my-box -f "{{ .Endpoint.VirtualIPs }}"
          [{pybpdb2fibkyk9jklcjqkrch7 10.0.1.19/24}]
          复制

          查看容器IP地址 和 service 的VIP

            docker@manager1:~$ docker ps                                                                                                              
            CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
            fcd9f0e5d0f2 nginx:latest "nginx -g 'daemon of…" 8 hours ago Up 8 hours 80/tcp my-web.2.ssl05byx4s3kr4dku1mw79f6f
            docker@manager1:~$ docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' my-web.2.ssl05byx4s3kr4dku1mw79f6f
            10.0.1.8

            复制
              docker@worker1:~$ docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' my-box.1.vc14enzddj8c88rykqszf38fe                     
              10.0.1.20
              docker@worker1:~$ docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' my-web.1.50zdanlgukvwxq2fujtcg9o4n
              10.0.1.7
              复制
                docker@worker1:~$ docker exec -it ae92907ac302 sh                                                                                                     
                / #
                / #
                / # nslookup my-web
                Server: 127.0.0.11
                Address 1: 127.0.0.11


                Name: my-web
                Address 1: 10.0.1.2 bogon # my-web 的虚拟IP


                / # nslookup tasks.my-web
                Server: 127.0.0.11
                Address 1: 127.0.0.11


                Name: tasks.my-web # 返回服务的容器IP地址
                Address 1: 10.0.1.8 my-web.2.ssl05byx4s3kr4dku1mw79f6f.my-network
                Address 2: 10.0.1.7 my-web.1.50zdanlgukvwxq2fujtcg9o4n.my-network




                / # nslookup my-box # 返回my-box服务的VIP
                Server: 127.0.0.11
                Address 1: 127.0.0.11


                Name: my-box
                Address 1: 10.0.1.19 bogon
                / # nslookup tasks.my-box
                Server: 127.0.0.11
                Address 1: 127.0.0.11


                Name: tasks.my-box
                Address 1: 10.0.1.20 ae92907ac302
                复制

                将现有服务连接到 overlay 网络

                  docker service update --network-add my-network my-web
                  复制

                  删除正在运行的服务网络连接

                    docker service update --network-rm my-network my-web
                    复制

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

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

                    我们再进入container看看:

                      docker@worker1:~$ docker exec -it 29cce8d4f412 sh                                                                                                     
                      / # ifconfig
                      eth0 Link encap:Ethernet HWaddr 02:42:0A:00:01:15
                      inet addr:10.0.1.21 Bcast:10.0.1.255 Mask:255.255.255.0
                      UP BROADCAST RUNNING MULTICAST MTU:1450 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)


                      eth1 Link encap:Ethernet HWaddr 02:42:AC:12:00:04
                      inet addr:172.18.0.4 Bcast:172.18.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:866 (866.0 B) TX bytes:0 (0.0 B)


                      lo Link encap:Local Loopback
                      inet addr:127.0.0.1 Mask:255.0.0.0
                      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:1000
                      RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
                      复制

                      每一个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可以看到:

                        docker@worker1:~$ ifconfig 
                        docker0 Link encap:Ethernet HWaddr 02:42:F1:8A:BC:80
                        inet addr:172.17.0.1 Bcast:172.17.255.255 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:B0:55:BE:A8
                        inet addr:172.18.0.1 Bcast:172.18.255.255 Mask:255.255.0.0
                        inet6 addr: fe80::42:b0ff:fe55:bea8/64 Scope:Link
                        UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
                        RX packets:41 errors:0 dropped:0 overruns:0 frame:0
                        TX packets:126 errors:0 dropped:0 overruns:0 carrier:0
                        collisions:0 txqueuelen:0
                        RX bytes:2041 (1.9 KiB) TX bytes:9471 (9.2 KiB)


                        复制

                        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>

                          1. docker_gwbridge

                          1. ingress, 其网段是10.255.X.X,每一个service在ingress上也有一个VIP,例如VIP=10.255.0.2,对映两个container:10.255.0.3和10.255.0.4

                        遇到的一些问题:docker busybox服务中nslookup命令报错

                          docker@worker1:~$ docker ps                                                                                                                           
                          CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
                          275444f7dbac busybox:latest "sleep 3000" 32 minutes ago Up 32 minutes my-box.1.lz7cd0j5h86m4h353rjt21wcy
                          fe7281a21572 nginx:latest "nginx -g 'daemon of…" 8 hours ago Up 8 hours 80/tcp my-web.1.50zdanlgukvwxq2fujtcg9o4n


                          docker@manager1:~$ docker exec -it my-box.1.zuga19xe4yau0mtgpuos936zs bin/sh
                          / #
                          / # nslookup my-web
                          Server: 127.0.0.11
                          Address: 127.0.0.11:53


                          Non-authoritative answer:


                          *** Can't find my-web: No answer
                          复制

                          新版的busybox好像有问题,使用旧版的busybox即可

                            docker@manager1:~$ docker service create --replicas 1 --network mynet --name my-box busybox:1.28.3 sleep 3000                                                        
                            overall progress: 1 out of 1 tasks
                            1/1: running [==================================================>]
                            verify: Service converged
                            复制

                            (二) service路由之:DSN轮询

                              $ docker service create --replicas 2 --network my-network --name my-dnsrr-web --endpoint-mode dnsrr richarvey/nginx-php-fpm
                              复制

                              dns方式是不允许有-p这个参数的,同时vip是 创建VIP类型,也可以不加--endpoint-mode参数。

                              先看两个容器的IP地址:

                                docker@manager1:~$ docker service ls
                                ID NAME MODE REPLICAS IMAGE PORTS
                                r6agac07qrx4 my-dnsrr-web replicated 2/2 richarvey/nginx-php-fpm:latest
                                docker@manager1:~$ docker service ps my-dnsrr-web
                                ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
                                i92e357ahd5l my-dnsrr-web.1 richarvey/nginx-php-fpm:latest worker1 Running Running 20 seconds ago
                                juqnhkk8e4fb my-dnsrr-web.2 richarvey/nginx-php-fpm:latest manager1 Running Running 19 seconds ago
                                docker@manager1:~$
                                docker@manager1:~$
                                docker@manager1:~$ docker ps
                                CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
                                3a47e1aacdc6 richarvey/nginx-php-fpm:latest "docker-php-entrypoi…" 24 seconds ago Up 23 seconds 80/tcp, 443/tcp, 9000/tcp my-dnsrr-web.2.juqnhkk8e4fbnz7bs1xpzbz42
                                docker@manager1:~$ docker exec -it my-dnsrr-web.2.juqnhkk8e4fbnz7bs1xpzbz42 bash
                                bash-5.0# ifconfig
                                eth0 Link encap:Ethernet HWaddr 02:42:0A:00:01:83
                                inet addr:10.0.1.131 Bcast:10.0.1.255 Mask:255.255.255.0
                                UP BROADCAST RUNNING MULTICAST MTU:1450 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)


                                eth1 Link encap:Ethernet HWaddr 02:42:AC:12:00:03
                                inet addr:172.18.0.3 Bcast:172.18.255.255 Mask:255.255.0.0
                                UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
                                RX packets:9 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:726 (726.0 B) TX bytes:0 (0.0 B)


                                lo Link encap:Local Loopback
                                inet addr:127.0.0.1 Mask:255.0.0.0
                                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:1000
                                RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)


                                bash-5.0#
                                复制
                                  docker@worker1:~$ docker exec -it my-dnsrr-web.1.i92e357ahd5lz91lseal6aa00 bash
                                  bash-5.0# ifconfig
                                  eth0 Link encap:Ethernet HWaddr 02:42:0A:00:01:82
                                  inet addr:10.0.1.130 Bcast:10.0.1.255 Mask:255.255.255.0
                                  UP BROADCAST RUNNING MULTICAST MTU:1450 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)


                                  eth1 Link encap:Ethernet HWaddr 02:42:AC:12:00:03
                                  inet addr:172.18.0.3 Bcast:172.18.255.255 Mask:255.255.0.0
                                  UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
                                  RX packets:10 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:796 (796.0 B) TX bytes:0 (0.0 B)


                                  lo Link encap:Local Loopback
                                  inet addr:127.0.0.1 Mask:255.0.0.0
                                  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:1000
                                  RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)


                                  复制

                                  my-dnsrr-web.1.i92e357ahd5lz91lseal6aa00

                                  • eth0  10.0.1.130
                                  • eth1  172.18.0.3

                                  my-dnsrr-web.2.juqnhkk8e4fbnz7bs1xpzbz42

                                  • eth0  10.0.1.131
                                  • eth1  172.18.0.3

                                  查看DNS解析结果(轮询访问)

                                    bash-5.0# ping my-dnsrr-web
                                    PING my-dnsrr-web (10.0.1.131): 56 data bytes
                                    64 bytes from 10.0.1.131: seq=0 ttl=64 time=0.039 ms
                                    64 bytes from 10.0.1.131: seq=1 ttl=64 time=0.074 ms
                                    64 bytes from 10.0.1.131: seq=2 ttl=64 time=0.071 ms
                                    ^C
                                    --- my-dnsrr-web ping statistics ---
                                    3 packets transmitted, 3 packets received, 0% packet loss
                                    round-trip min/avg/max = 0.039/0.061/0.074 ms
                                    bash-5.0# ping my-dnsrr-web
                                    PING my-dnsrr-web (10.0.1.130): 56 data bytes
                                    64 bytes from 10.0.1.130: seq=0 ttl=64 time=1.029 ms
                                    64 bytes from 10.0.1.130: seq=1 ttl=64 time=0.894 ms
                                    64 bytes from 10.0.1.130: seq=2 ttl=64 time=0.846 ms
                                    64 bytes from 10.0.1.130: seq=3 ttl=64 time=1.233 ms
                                    复制

                                    nslookup访问

                                      bash-5.0# nslookup my-dnsrr-web
                                      nslookup: can't resolve '(null)': Name does not resolve


                                      Name: my-dnsrr-web
                                      Address 1: 10.0.1.131 3a47e1aacdc6
                                      Address 2: 10.0.1.130 my-dnsrr-web.1.i92e357ahd5lz91lseal6aa00.my-network
                                      bash-5.0#
                                      复制

                                      三、发布服务端口

                                      当你创建一个服务时, 你可以使用--publish参数来发布端口。

                                        # docker service create \
                                        --name <Service-Name> \
                                        --publish <Publish-Port>:<Target-Port> \
                                        <Docker Image>
                                        复制

                                        <目标端口>为Docker容器中所监听的端口,<发布端口>为Swarm集群中使得服务可以访问的端口。

                                        例如, 在Swarm集群中发布Nginx应用服务, 将容器中的80端口映射为Swarm集群的8080端口。

                                          $ docker service create \
                                          --name my-web \
                                          --publish 8080:80 \
                                          --replicas 2 \
                                          nginx
                                          复制

                                          当你在任何节点上访问8080端口时,Swarm集群的负载均衡会将您的请求路由至活动容器中。

                                          Swarm集群的路由网络在发布的端口上监听分配给该节点的任何IP地址。对于外部可路由的IP地址,端口可从主机外部获得。对于其他的IP地址,只能从主机中访问。

                                          Ingress Network 使用以下命令可以为已经发布的服务发布端口:

                                            $ docker service update \
                                            --publish-add <PUBLISHED-PORT>:<TARGET-PORT> \
                                            <SERVICE>
                                            复制

                                            使用docker service inspect查看服务端口。

                                              # docker service inspect --format="" nginx-service
                                              复制

                                              仅发布TCP端口或仅发布UDP端口

                                              默认情况下, 所发布的端口一般为TCP端口。你可以专门指定发布UDP端口,而不是TCP或之外的端口。当发布TCP和UDP端口时,Docker 1.12.2版本和早前版本需要为TCP端口指定后缀/tcp。后缀为可选的参数。

                                              仅发布TCP端口

                                                # docker service create --name dns-cache -p 53:53 dns-cache
                                                复制

                                                  # docker service create --name dns-cache -p 53:53/tcp dns-cache
                                                  复制

                                                  发布TCP和UDP端口

                                                    # docker service create --name dns-cache -p 53:53/tcp -p 53:53/udp dns-cache
                                                    复制

                                                    仅发布UDP端口

                                                      # docker service create --name dns-cahce -p 53:53/udp dns-cache
                                                      复制

                                                      配置外部负载均衡

                                                      可通过配置外部负载均衡实现Swarm集群的服务路由。例如, 使用HAProxy实现已发布端口8080的Nginx服务的负载均衡。

                                                      Load Balance 在这种情况下, 必须在Swarm集群节点和HAProxy之间打开8080端口,Swarm集群节点可以驻留在代理服务器可以访问的专用网络上,但不能公开访问。

                                                      我们可以将负载均衡配置为Swarm集群中的每个节点之间的请求平衡,即使该 节点上没有计划任务。例如, 我们可以在/etc/haproxy/haproxy.cfg
                                                      中配置HAProxy的负载均衡。

                                                        global
                                                        log dev/log local0
                                                        log dev/log local1 notice
                                                        ...snip...


                                                        # Configure HAProxy to listen on port 80
                                                        frontend http_front
                                                        bind *:80
                                                        stats uri /haproxy?stats
                                                        default_backend http_back


                                                        # Configure HAProxy to route requests to swarm nodes on port 8080
                                                        backend http_back
                                                        balance roundrobin
                                                        server node1 192.168.99.100:8080 check
                                                        server node2 192.168.99.101:8080 check
                                                        server node3 192.168.99.102:8080 check
                                                        复制

                                                        当您在端口80上访问HAProxy负载均衡服务时,它会将请求转发到Swarm集群中的节点。Swarm集群路由网络将请求路由到活动任务中。如果由于任何原因swarm调度程序将任务分派给不同的节点,则不需要重新配置负载均衡。

                                                        https://www.linuxidc.com/Linux/2017-11/148370.htm[1]

                                                        https://www.jianshu.com/p/cacdd5ff0f14[2]

                                                        参考资料

                                                        [1]

                                                        https://www.linuxidc.com/Linux/2017-11/148370.htm: https://www.linuxidc.com/Linux/2017-11/148370.htm

                                                        [2]

                                                        https://www.jianshu.com/p/cacdd5ff0f14: https://www.jianshu.com/p/cacdd5ff0f14


                                                        最后修改时间:2020-01-25 11:33:51
                                                        文章转载自运维笔记本,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                                        评论