本文借助一个示例来解释创建一个多主机网络的基础。Docker Engine通过overlay网络驱动支持多主机网络开箱即用。不像bridge网络,在你创建一个overlay网络时需要一些前提条件:
或
overlay网络和swarm模式
使用运行在swarm模式的docker engine,你可以在管理节点上创建一个overlay网络。
overlay网络只在依赖其的服务的swarm节点上可用。当你创建一个使用overlay网络的服务时,管理节点自动扩展overlay网络到运行服务的节点上。
下面的示例展示如何创建一个网络并在swarm管理节点上设置它用于一个服务:
- # Create an overlay network `my-multi-host-network`.
- $ docker network create
- –driver overlay
- –subnet 10.0.9.0/24
- my-multi-host-network
- 400g6bwzd68jizzdx5pgyoe95
- # Create an nginx service and extend the my-multi-host-network to nodes where
- # the service’s tasks run.
- $ docker service create –replicas 2 –network my-multi-host-network –name my-web nginx
- 716thylsndqma81j6kkkb5aus
swarm的overlay网络在不受管理的容器上不可用。
使用外部键值存储的overlay网络
要使用带外部键值存储的docker engine,你需要满足如下条件:
虽然体验使用键值存储的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。
- $ docker-machine create -d virtualbox mh-keystore
当你配置一个新的主机时,该进程会自动添加一个Docker Engine到这个主机。意味着我们不手动安装Consul,而是使用从docker hub的consul镜像创建一个实例。
3.进入mh-keystore主机。
- $ eval "$(docker-machine env mh-keystore)"
4.在mh-keystore主机启动一个progrium/consul容器。
- $ docker run -d
- -p "8500:8500"
- -h "consul"
- progrium/consul -server -bootstrap
5.执行docker ps命令来查看consul容器。
- $ docker ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 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。
- $ docker-machine create
- -d virtualbox
- –swarm –swarm-master
- –swarm-discovery="consul://$(docker-machine ip mh-keystore):8500"
- –engine-opt="cluster-store=consul://$(docker-machine ip mh-keystore):8500"
- –engine-opt="cluster-advertise=eth1:2376"
- mhs-demo0
以上的命令中,–cluster-store选项告知Engine键值存储的位置。$(docker-machine ip mh-keystore)变量是取得Consul服务器的IP地址。–cluster-advertise选项这台主机的网络地址。
2.创建另一台主机并增加到swarm集群。
- $ docker-machine create -d virtualbox
- –swarm
- –swarm-discovery="consul://$(docker-machine ip mh-keystore):8500"
- –engine-opt="cluster-store=consul://$(docker-machine ip mh-keystore):8500"
- –engine-opt="cluster-advertise=eth1:2376"
- mhs-demo1
3.列出所有的主机来确认它们都处于运行状态。
- $ docker-machine ls
- NAME ACTIVE DRIVER STATE URL SWARM
- default – virtualbox Running tcp://192.168.99.100:2376
- mh-keystore * virtualbox Running tcp://192.168.99.103:2376
- mhs-demo0 – virtualbox Running tcp://192.168.99.104:2376 mhs-demo0 (master)
- mhs-demo1 – virtualbox Running tcp://192.168.99.105:2376 mhs-demo0
这个时候你已经在你的网络配置了一组主机。下面将准备使用这些主机为你的容器创建一个多主机网络。
创建overlay网络
1.进入swarm master主机。
- $ eval $(docker-machine env –swarm mhs-demo0)
2.使用docker info命令来查看swarm。
- $ docker info
- Containers: 3
- Images: 2
- Role: primary
- Strategy: spread
- Filters: affinity, health, constraint, port, dependency
- Nodes: 2
- mhs-demo0: 192.168.99.104:2376
- └ Containers: 2
- └ Reserved CPUs: 0 / 1
- └ Reserved Memory: 0 B / 1.021 GiB
- └ 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
- mhs-demo1: 192.168.99.105:2376
- └ Containers: 1
- └ Reserved CPUs: 0 / 1
- └ Reserved Memory: 0 B / 1.021 GiB
- └ 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
- CPUs: 2
- Total Memory: 2.043 GiB
- Name: 30438ece0915
从以上的信息我们可以得出集群运行着三个容器和master有两个镜像。
3.创建overlay网络。
- $ docker network create –driver overlay –subnet=10.0.9.0/24 my-net
你只需要在集群中的一台主机创建这个网络。在这个示例中我们在swarm master创建网络,不过你可以很容易地在任意一台主机创建。
1.检查网络是否在运行:
- $ docker network ls
- NETWORK ID NAME DRIVER
- 412c2496d0eb mhs-demo1/host host
- dd51763e6dd2 mhs-demo0/bridge bridge
- 6b07d0be843f my-net overlay
- b4234109bd9b mhs-demo0/none null
- 1aeead6dd890 mhs-demo0/host host
- d0bb78cbe7bd mhs-demo1/bridge bridge
- 1c0eb8f69ebb mhs-demo1/none null
由于你处于swarm master主机上,你会看到所有swarm节点的网络。
2.依次切换到每台swarm节点并列出网络。
- $ eval $(docker-machine env mhs-demo0)
- $ docker network ls
- NETWORK ID NAME DRIVER
- 6b07d0be843f my-net overlay
- dd51763e6dd2 bridge bridge
- b4234109bd9b none null
- 1aeead6dd890 host host
- $ eval $(docker-machine env mhs-demo1)
- $ docker network ls
- NETWORK ID NAME DRIVER
- d0bb78cbe7bd bridge bridge
- 1c0eb8f69ebb none null
- 412c2496d0eb host host
- 6b07d0be843f my-net overlay
两个节点都有一个ID 6b07d0be843f的my-net网络。你现在已经运行了一个多主机容器网络。
在你的网络上运行一个应用
一旦你的网络创建好后,你就可以在任意一台主机上启动一个容器且它自动成为网络的一部分。
1.登录入swarm master。
- $ eval $(docker-machine env –swarm mhs-demo0)
2.在mhs-demo0主机上启动一个nginx。
- $ docker run -itd –name=web –network=my-net –env="constraint:node==mhs-demo0" nginx
3.在mhs-demo1主机运行一个BusyBox实例并获取nginx服务器的主页内容。
- $ docker run -it –rm –network=my-net –env="constraint:node==mhs-demo1" busybox wget -O- http://web
- Unable to find image ‘busybox:latest’ locally
- latest: Pulling from library/busybox
- ab2b8a86ca6c: Pull complete
- 2c5ac3f849df: Pull complete
- Digest: sha256:5551dbdfc48d66734d0f01cafee0952cb6e8eeecd1e2492240bf2fd9640c2279
- Status: Downloaded newer image for busybox:latest
- Connecting to web (10.0.0.2:80)
- <!DOCTYPE html>
- <html>
- <head>
- <title>Welcome to nginx!</title>
- <style>
- body {
- width: 35em;
- margin: 0 auto;
- font-family: Tahoma, Verdana, Arial, sans-serif;
- }
- </style>
- </head>
- <body>
- <h1>Welcome to nginx!</h1>
- <p>If you see this page, the nginx web server is successfully installed and
- working. Further configuration is required.</p>
- <p>For online documentation and support please refer to
- <a href="http://nginx.org/">nginx.org</a>.<br/>
- Commercial support is available at
- <a href="http://nginx.com/">nginx.com</a>.</p>
- <p><em>Thank you for using nginx.</em></p>
- </body>
- </html>
- – 100% |*******************************| 612 0:00:00 ETA
检查外部连接
如你所看到的,Docker内置的overlay网络驱动为在同一个网络的多个主机的容器之间提供了开箱即用的连接。此外,连接到多主机网络的容器会自动的连接到docker_gwbridge网络。这个网络允许容器连接集群外部的网络。
1.登录到mhs-demo1主机。
- $ eval $(docker-machine env mhs-demo1)
2.使用docker network ls列出所有网络来查看docker_gwbridge。
- $ docker network ls
- NETWORK ID NAME DRIVER
- 6b07d0be843f my-net overlay
- dd51763e6dd2 bridge bridge
- b4234109bd9b none null
- 1aeead6dd890 host host
- e1dbd5dff8be docker_gwbridge bridge
3.在swarm master重复1和2步。
- $ eval $(docker-machine env mhs-demo0)
- $ docker network ls
- NETWORK ID NAME DRIVER
- 6b07d0be843f my-net overlay
- d0bb78cbe7bd bridge bridge
- 1c0eb8f69ebb none null
- 412c2496d0eb host host
- 97102a22e8d2 docker_gwbridge bridge
4.检查nginx容器网络接口。
- $ docker exec web ip addr
- 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
- link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
- inet 127.0.0.1/8 scope host lo
- valid_lft forever preferred_lft forever
- inet6 ::1/128 scope host
- valid_lft forever preferred_lft forever
- 22: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default
- link/ether 02:42:0a:00:09:03 brd ff:ff:ff:ff:ff:ff
- inet 10.0.9.3/24 scope global eth0
- valid_lft forever preferred_lft forever
- inet6 fe80::42:aff:fe00:903/64 scope link
- valid_lft forever preferred_lft forever
- 24: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
- link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff
- inet 172.18.0.2/16 scope global eth1
- valid_lft forever preferred_lft forever
- inet6 fe80::42:acff:fe12:2/64 scope link
- valid_lft forever preferred_lft forever
容器的eth0接口连接到my-net overlay网络,eth1连接到docker_gwbridge网络。