Docker用户指南(12) – 多主机网络

本文借助一个示例来解释创建一个多主机网络的基础。Docker Engine通过overlay网络驱动支持多主机网络开箱即用。不像bridge网络,在你创建一个overlay网络时需要一些前提条件:

  • 运行在swarm模式的docker engine
  • 使用一个键值存储的集群
  • overlay网络和swarm模式

    使用运行在swarm模式的docker engine,你可以在管理节点上创建一个overlay网络。
    overlay网络只在依赖其的服务的swarm节点上可用。当你创建一个使用overlay网络的服务时,管理节点自动扩展overlay网络到运行服务的节点上。
    下面的示例展示如何创建一个网络并在swarm管理节点上设置它用于一个服务:

    1. # Create an overlay network `my-multi-host-network`.
    2. $ docker network create \
    3.   --driver overlay \
    4.   --subnet 10.0.9.0/24 \
    5.   my-multi-host-network
    6.  
    7. 400g6bwzd68jizzdx5pgyoe95
    8.  
    9. # Create an nginx service and extend the my-multi-host-network to nodes where
    10. # the service's tasks run.
    11. $ docker service create --replicas 2 --network my-multi-host-network --name my-web nginx
    12.  
    13. 716thylsndqma81j6kkkb5aus

    swarm的overlay网络在不受管理的容器上不可用。

    使用外部键值存储的overlay网络

    要使用带外部键值存储的docker engine,你需要满足如下条件:

  • 一个键值存储。docker支持Consul, Etcd和ZooKeeper(分布式存储)键值存储。
  • 集群的主机能够访问键值存储。
  • 正确地配置集群中的每台主机的engine daemon。
  • 由于键值存储使用主机名辨别集群成员,集群中的主机必须有一个唯一的主机名。
  • 虽然体验使用键值存储的docker多主机网络不强制使用Docker Machine和Docker Swarm,本示例使用它们来说明如何架设这样的一个多主机网络。
    我们将使用Machine来创建键值存储和主机集群。此示例创建一个swarm集群。

    注意:运行在swarm模式的docker engine与使用外部键值存储的网络不兼容。

    前提条件

    在开始之前,确保你的系统安装有最新版本的docker engine和docker machine。此示例也依赖VirtualBox。如果你在Mac或Windows安装了Docker Toolbox,这些应该都安装好了。

    配置一个键值存储

    overlay网络需要一个键值存储。这个键值存储维护关于网络状态的信息,包括发现(discovery),网络,endpoints,ip地址等。Docker支持Consul, Etcd和ZooKeeper键值存储。本示例使用Consul。
    1.登录进安装有Docker Engine, Docker Machine和VirtualBox的系统。
    2.配置一个VirtualBox机器,名称为mh-keystore。

    1. $ docker-machine create -d virtualbox mh-keystore

    当你配置一个新的主机时,该进程会自动添加一个Docker Engine到这个主机。意味着我们不手动安装Consul,而是使用从docker hub的consul镜像创建一个实例。
    3.进入mh-keystore主机。

    1. $  eval "$(docker-machine env mh-keystore)"

    4.在mh-keystore主机启动一个progrium/consul容器。

    1. $  docker run -d \
    2.      -p "8500:8500" \
    3.      -h "consul" \
    4.      progrium/consul -server -bootstrap

    5.执行docker ps命令来查看consul容器。

    1. $ docker ps
    2.  
    3.  CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                                                            NAMES
    4.  4d51392253b3        progrium/consul     "/bin/start -server -"   25 minutes ago      Up 25 minutes       53/tcp, 53/udp, 8300-8302/tcp, 0.0.0.0:8500->8500/tcp, 8400/tcp, 8301-8302/udp   admiring_panini

    创建一个swarm集群

    在本步骤中,将使用docker-machine来配置你网络的主机。在这时候你实际上还没有创建网络,只是在VirtualBox创建了几个主机。其中一个主机作为swarm master,然后创建每一个主机。最后传递overlay网络驱动需要的参数到那主机的Engine。
    1.创建一个swarm master。

    1. $ docker-machine create \
    2.  -d virtualbox \
    3.  --swarm --swarm-master \
    4.  --swarm-discovery="consul://$(docker-machine ip mh-keystore):8500" \
    5.  --engine-opt="cluster-store=consul://$(docker-machine ip mh-keystore):8500" \
    6.  --engine-opt="cluster-advertise=eth1:2376" \
    7.  mhs-demo0

    以上的命令中,–cluster-store选项告知Engine键值存储的位置。$(docker-machine ip mh-keystore)变量是取得Consul服务器的IP地址。–cluster-advertise选项这台主机的网络地址。
    2.创建另一台主机并增加到swarm集群。

    1. $ docker-machine create -d virtualbox \
    2.      --swarm \
    3.      --swarm-discovery="consul://$(docker-machine ip mh-keystore):8500" \
    4.      --engine-opt="cluster-store=consul://$(docker-machine ip mh-keystore):8500" \
    5.      --engine-opt="cluster-advertise=eth1:2376" \
    6.    mhs-demo1

    3.列出所有的主机来确认它们都处于运行状态。

    1. $ docker-machine ls
    2.  
    3.  NAME         ACTIVE   DRIVER       STATE     URL                         SWARM
    4.  default      -        virtualbox   Running   tcp://192.168.99.100:2376
    5.  mh-keystore  *        virtualbox   Running   tcp://192.168.99.103:2376
    6.  mhs-demo0    -        virtualbox   Running   tcp://192.168.99.104:2376   mhs-demo0 (master)
    7.  mhs-demo1    -        virtualbox   Running   tcp://192.168.99.105:2376   mhs-demo0

    这个时候你已经在你的网络配置了一组主机。下面将准备使用这些主机为你的容器创建一个多主机网络。

    创建overlay网络

    1.进入swarm master主机。

    1. $ eval $(docker-machine env --swarm mhs-demo0)

    2.使用docker info命令来查看swarm。

    1. $ docker info
    2.  
    3.  Containers: 3
    4.  Images: 2
    5.  Role: primary
    6.  Strategy: spread
    7.  Filters: affinity, health, constraint, port, dependency
    8.  Nodes: 2
    9.  mhs-demo0: 192.168.99.104:2376
    10.  └ Containers: 2
    11.  └ Reserved CPUs: 0 / 1
    12.  └ Reserved Memory: 0 B / 1.021 GiB
    13.  └ Labels: executiondriver=native-0.2, kernelversion=4.1.10-boot2docker, operatingsystem=Boot2Docker 1.9.0 (TCL 6.4); master : 4187d2c - Wed Oct 14 14:00:28 UTC 2015, provider=virtualbox, storagedriver=aufs
    14.  mhs-demo1: 192.168.99.105:2376
    15.  └ Containers: 1
    16.  └ Reserved CPUs: 0 / 1
    17.  └ Reserved Memory: 0 B / 1.021 GiB
    18.  └ Labels: executiondriver=native-0.2, kernelversion=4.1.10-boot2docker, operatingsystem=Boot2Docker 1.9.0 (TCL 6.4); master : 4187d2c - Wed Oct 14 14:00:28 UTC 2015, provider=virtualbox, storagedriver=aufs
    19.  CPUs: 2
    20.  Total Memory: 2.043 GiB
    21.  Name: 30438ece0915

    从以上的信息我们可以得出集群运行着三个容器和master有两个镜像。
    3.创建overlay网络。

    1. $ docker network create --driver overlay --subnet=10.0.9.0/24 my-net

    你只需要在集群中的一台主机创建这个网络。在这个示例中我们在swarm master创建网络,不过你可以很容易地在任意一台主机创建。
    1.检查网络是否在运行:

    1. $ docker network ls
    2.  
    3.  NETWORK ID          NAME                DRIVER
    4.  412c2496d0eb        mhs-demo1/host      host
    5.  dd51763e6dd2        mhs-demo0/bridge    bridge
    6.  6b07d0be843f        my-net              overlay
    7.  b4234109bd9b        mhs-demo0/none      null
    8.  1aeead6dd890        mhs-demo0/host      host
    9.  d0bb78cbe7bd        mhs-demo1/bridge    bridge
    10.  1c0eb8f69ebb        mhs-demo1/none      null

    由于你处于swarm master主机上,你会看到所有swarm节点的网络。
    2.依次切换到每台swarm节点并列出网络。

    1. $ eval $(docker-machine env mhs-demo0)
    2.  
    3.  $ docker network ls
    4.  
    5.  NETWORK ID          NAME                DRIVER
    6.  6b07d0be843f        my-net              overlay
    7.  dd51763e6dd2        bridge              bridge
    8.  b4234109bd9b        none                null
    9.  1aeead6dd890        host                host
    10.  
    11.  $ eval $(docker-machine env mhs-demo1)
    12.  
    13.  $ docker network ls
    14.  
    15.  NETWORK ID          NAME                DRIVER
    16.  d0bb78cbe7bd        bridge              bridge
    17.  1c0eb8f69ebb        none                null
    18.  412c2496d0eb        host                host
    19.  6b07d0be843f        my-net              overlay

    两个节点都有一个ID 6b07d0be843f的my-net网络。你现在已经运行了一个多主机容器网络。

    在你的网络上运行一个应用

    一旦你的网络创建好后,你就可以在任意一台主机上启动一个容器且它自动成为网络的一部分。
    1.登录入swarm master。

    1. $ eval $(docker-machine env --swarm mhs-demo0)

    2.在mhs-demo0主机上启动一个nginx。

    1. $ docker run -itd --name=web --network=my-net --env="constraint:node==mhs-demo0" nginx

    3.在mhs-demo1主机运行一个BusyBox实例并获取nginx服务器的主页内容。

    1. $ docker run -it --rm --network=my-net --env="constraint:node==mhs-demo1" busybox wget -O- http://web
    2.  
    3.  Unable to find image 'busybox:latest' locally
    4.  latest: Pulling from library/busybox
    5.  ab2b8a86ca6c: Pull complete
    6.  2c5ac3f849df: Pull complete
    7.  Digest: sha256:5551dbdfc48d66734d0f01cafee0952cb6e8eeecd1e2492240bf2fd9640c2279
    8.  Status: Downloaded newer image for busybox:latest
    9.  Connecting to web (10.0.0.2:80)
    10.  <!DOCTYPE html>
    11.  <html>
    12.  <head>
    13.  <title>Welcome to nginx!</title>
    14.  <style>
    15.  body {
    16.          width: 35em;
    17.          margin: 0 auto;
    18.          font-family: Tahoma, Verdana, Arial, sans-serif;
    19.  }
    20.  </style>
    21.  </head>
    22.  <body>
    23.  <h1>Welcome to nginx!</h1>
    24.  <p>If you see this page, the nginx web server is successfully installed and
    25.  working. Further configuration is required.</p>
    26.  
    27.  <p>For online documentation and support please refer to
    28.  <a>nginx.org</a>.<br/>
    29.  Commercial support is available at
    30.  <a>nginx.com</a>.</p>
    31.  
    32.  <p><em>Thank you for using nginx.</em></p>
    33.  </body>
    34.  </html>
    35.  -                    100% |*******************************|   612   0:00:00 ETA

    检查外部连接

    如你所看到的,Docker内置的overlay网络驱动为在同一个网络的多个主机的容器之间提供了开箱即用的连接。此外,连接到多主机网络的容器会自动的连接到docker_gwbridge网络。这个网络允许容器连接集群外部的网络。
    1.登录到mhs-demo1主机。

    1. $ eval $(docker-machine env mhs-demo1)

    2.使用docker network ls列出所有网络来查看docker_gwbridge。

    1. $ docker network ls
    2.  
    3.  NETWORK ID          NAME                DRIVER
    4.  6b07d0be843f        my-net              overlay
    5.  dd51763e6dd2        bridge              bridge
    6.  b4234109bd9b        none                null
    7.  1aeead6dd890        host                host
    8.  e1dbd5dff8be        docker_gwbridge     bridge

    3.在swarm master重复1和2步。

    1. $ eval $(docker-machine env mhs-demo0)
    2.  
    3.  $ docker network ls
    4.  
    5.  NETWORK ID          NAME                DRIVER
    6.  6b07d0be843f        my-net              overlay
    7.  d0bb78cbe7bd        bridge              bridge
    8.  1c0eb8f69ebb        none                null
    9.  412c2496d0eb        host                host
    10.  97102a22e8d2        docker_gwbridge     bridge

    4.检查nginx容器网络接口。

    1. $ docker exec web ip addr
    2.  
    3.  1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
    4.  link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    5.  inet 127.0.0.1/8 scope host lo
    6.      valid_lft forever preferred_lft forever
    7.  inet6 ::1/128 scope host
    8.      valid_lft forever preferred_lft forever
    9.  22: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default
    10.  link/ether 02:42:0a:00:09:03 brd ff:ff:ff:ff:ff:ff
    11.  inet 10.0.9.3/24 scope global eth0
    12.      valid_lft forever preferred_lft forever
    13.  inet6 fe80::42:aff:fe00:903/64 scope link
    14.      valid_lft forever preferred_lft forever
    15.  24: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    16.  link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
    17.  inet 172.18.0.2/16 scope global eth1
    18.      valid_lft forever preferred_lft forever
    19.  inet6 fe80::42:acff:fe12:2/64 scope link
    20.      valid_lft forever preferred_lft forever

    容器的eth0接口连接到my-net overlay网络,eth1连接到docker_gwbridge网络。

    标签:Docker 发布于:2019-11-20 02:39:18