管理swarm(19) – 将服务附加到覆盖网络

Docker Engine的swarm模式原生支持覆盖网络(overlay networks),所以你可以启用容器到容器的网络。swarm模式的覆盖网络包括以下功能:

  • 你可以附加多个服务到同一个网络
  • 默认情况下,service discovery为每个swarm服务分配一个虚拟IP地址(vip)和DNS名称,使得在同一个网络中容器之间可以使用服务名称为互相连接。
  • 你可以配置使用DNS轮循而不使用VIP
  • 为了可以使用swarm的覆盖网络,在启用swarm模式之间你需要在swarm节点之间开放以下端口:

  • TCP/UDP端口7946 – 用于容器网络发现
  • UDP端口4789 – 用于容器覆盖网络
  • 在swarm中创建一个覆盖网络

    当你运行Docker Engine的swarm模式时,你可以在管理节点执行docker network create命令来创建一个覆盖网络。例如,创建一个名为my-network的网络:

    1. $ docker network create \
    2.   --driver overlay \
    3.   --subnet 10.0.9.0/24 \
    4.   --opt encrypted \
    5.   my-network
    6.  
    7. 273d53261bcdfda5f198587974dae3827e947ccd7e74a41bf1f482ad17fa0d33

    默认情况下swarm中的节点通信是加密的。在不同节点的容器之间,可选的–opt encrypted参数能在它们的vxlan流量启用附加的加密层。
    –subnet参数指定覆盖网络的子网。当你不指定一个子网时,swarm管理器自动选择一个子网并分配给网络。在一些旧的内核,包括kernel 3.10,自动分配的地址可能会与其它子网重叠。这样的重叠可能引起连接问题。
    执行docker network ls来查看网络:

    1. $ docker network ls
    2.  
    3. NETWORK ID          NAME        DRIVER   SCOPE
    4. f9145f09b38b        bridge      bridge   local
    5. ..snip..
    6. 273d53261bcd        my-network  overlay  swarm

    swarm scope表示部署到swarm的服务可以使用这个网络。当你创建一个服务并附加到一个网络后,swarm仅仅扩展该网络到服务运行的节点上。在一个没有运行有附加到网络的服务worker节点上,network ls命令不会显示有任何网络。

    附加服务到覆盖网络

    要附加一个服务到一个覆盖网络,在创建服务的时候传递–network参数。例如创建一个nginx服务并附加到一个名为my-network的网络:

    1. $ docker service create \
    2.   --replicas 3 \
    3.   --name my-web \
    4.   --network my-network \
    5.   nginx

    注意:在附加服务到网络前,必须先创建这个网络。

    在同一个覆盖网络的容器之间能互相连接。在管理节点执行docker service ps 来查看哪些节点运行着这个服务:

    1. $ docker service ps my-web
    2.  
    3. ID                         NAME      IMAGE  NODE   DESIRED STATE  CURRENT STATE               ERROR
    4. 63s86gf6a0ms34mvboniev7bs  my-web.1  nginx  node1  Running        Running 58 seconds ago
    5. 6b3q2qbjveo4zauc6xig7au10  my-web.2  nginx  node2  Running        Running 58 seconds ago
    6. 66u2hcrz0miqpc8h0y0f3v7aw  my-web.3  nginx  node3  Running        Running about a minute ago

    pic1
    你可以在运行着附加有网络的服务的节点上查看这个网络的详情:

    1. $ docker network inspect <NETWORK>

    这个网络信息包括了该节点上附加到该网络的容器的列表。例如:

    1. $ docker network inspect my-network
    2. [
    3.     {
    4.         "Name": "my-network",
    5.         "Id": "273d53261bcdfda5f198587974dae3827e947ccd7e74a41bf1f482ad17fa0d33",
    6.         "Scope": "swarm",
    7.         "Driver": "overlay",
    8.         "EnableIPv6": false,
    9.         "IPAM": {
    10.             "Driver": "default",
    11.             "Options": null,
    12.             "Config": [
    13.                 {
    14.                     "Subnet": "10.0.9.0/24",
    15.                     "Gateway": "10.0.9.1"
    16.                 }
    17.             ]
    18.         },
    19.         "Internal": false,
    20.         "Containers": {
    21.             "404d1dec939a021678132a35259c3604b9657649437e59060621a17edae7a819": {
    22.                 "Name": "my-web.1.63s86gf6a0ms34mvboniev7bs",
    23.                 "EndpointID": "3c9588d04db9bc2bf8749cb079689a3072c44c68e544944cbea8e4bc20eb7de7",
    24.                 "MacAddress": "02:42:0a:00:09:03",
    25.                 "IPv4Address": "10.0.9.3/24",
    26.                 "IPv6Address": ""
    27.             }
    28.         },
    29.         "Options": {
    30.             "com.docker.network.driver.overlay.vxlanid_list": "257"
    31.         },
    32.         "Labels": {}
    33.     }
    34. ]

    在上面的示例中,my-web服务的容器my-web.1.63s86gf6a0ms34mvboniev7bs附加到该节点的my-network网络。

    使用swarm模式的service discovery

    默认情况下,当你创建一个服务并附加到一个网络时,swarm就给服务分配一个VIP。VIP根据服务名称映射到DNS别名。在该网络的容器之间通过gossip来共享DNS映射信息,所以在该网络的容器能通过服务名称来访问彼此。
    你不需要公开特定于服务的端口,以使服务可用于同一覆盖网络上的其他服务。 swarm的内部负载均衡会自动将请求分发到服务VIP。
    你可以使用如下命令来查看服务的VIP:

    1. $ docker service inspect \
    2.   --format='{{json .Endpoint.VirtualIPs}}' \
    3.   my-web
    4.  
    5. [{"NetworkID":"7m2rjx0a97n88wzr4nu8772r3" "Addr":"10.0.0.2/24"}]

    下面的示例展示如何添加一个busybox服务到与nginx服务相同的网络,以及busybox服务使用DNS名称my-web访问nginx服务:
    1.在管理节点,部署busybox服务到与my-web同一个网络:

    1. $ docker service create \
    2.   --name my-busybox \
    3.   --network my-network \
    4.   busybox \
    5.   sleep 3000

    2.查看哪个节点运行着my-busybox服务:

    1. $ docker service ps my-busybox
    2.  
    3. ID                         NAME          IMAGE    NODE   DESIRED STATE  CURRENT STATE          ERROR
    4. 1dok2cmx2mln5hbqve8ilnair  my-busybox.1  busybox  node1  Running        Running 5 seconds ago

    3.登录上一步查询到的node1节点,在busybox容器中打开一个可交互的shell:

    1. $ docker exec -it my-busybox.1.1dok2cmx2mln5hbqve8ilnair /bin/sh

    你可以将容器名称推断为 + 。 或者,你可以在运行任务的节点上运行docker ps。
    4.在busybox容器内部,查询my-web服务的VIP:

    1. $ nslookup my-web
    2.  
    3. Server:    127.0.0.11
    4. Address 1: 127.0.0.11
    5.  
    6. Name:      my-web
    7. Address 1: 10.0.9.2 ip-10-0-9-2.us-west-2.compute.internal

    5.在busybox容器内部,查询的DNS记录来找出my-web服务的所有容器IP地址:

    1. $ nslookup tasks.my-web
    2.  
    3. Server:    127.0.0.11
    4. Address 1: 127.0.0.11
    5.  
    6. Name:      tasks.my-web
    7. Address 1: 10.0.9.4 my-web.2.6b3q2qbjveo4zauc6xig7au10.my-network
    8. Address 2: 10.0.9.3 my-web.1.63s86gf6a0ms34mvboniev7bs.my-network
    9. Address 3: 10.0.9.5 my-web.3.66u2hcrz0miqpc8h0y0f3v7aw.my-network

    6.在busybox容器内,执行wget来访问my-web服务的nginx web server:

    1. $ wget -O- my-web
    2.  
    3. Connecting to my-web (10.0.9.2:80)
    4. <!DOCTYPE html>
    5. <html>
    6. <head>
    7. <title>Welcome to nginx!</title>
    8. ...snip...

    通过访问服务的VIP,swarm负载均衡自动将HTTP请求路由可用的容器中。 它使用轮循的方式来平均地分发请求。

    使用DNS轮循请求

    你可以配置服务直接使用DNS轮循而不用VIP,在创建服务的时候设置–endpoint-mode dnsrr。在你要使用你自己的负载均衡器时可能会用此方法。
    下面的示例展示一个服务使用dnsrr endpoint模式:

    1. $ docker service create \
    2.   --replicas 3 \
    3.   --name my-dnsrr-service \
    4.   --network my-network \
    5.   --endpoint-mode dnsrr \
    6.   nginx

    当你查询服务名称的DNS记录时,DNS服务会返回所有该服务容器的IP地址:

    1. $ nslookup my-dnsrr-service
    2. Server:    127.0.0.11
    3. Address 1: 127.0.0.11
    4.  
    5. Name:      my-dnsrr
    6. Address 1: 10.0.9.8 my-dnsrr-service.1.bd3a67p61by5dfdkyk7kog7pr.my-network
    7. Address 2: 10.0.9.10 my-dnsrr-service.3.0sb1jxr99bywbvzac8xyw73b1.my-network
    8. Address 3: 10.0.9.9 my-dnsrr-service.2.am6fx47p3bropyy2dy4f8hofb.my-network
    标签:Swarm 发布于:2019-11-20 05:59:36