Docker-swarm 控制多網路區域的 Docker

Share This Post

最新的 Docker 1.9.0 在 11 月份正式推出,且多了 network 的設置,剛開始看到時似乎沒什麼新奇,在社群上看到相關的文章,在一開始 docker-swarm 在官方網站用的是 local 的環境來進行展示,參考:Install and Create a Docker Swarm

其實已經很方便了,但尚未可以透過 docker-compose 讓設置方式一目了然,畢竟是多環境的架構,若有沒有一個很好的配置檔,在維護上將會讓人卻步,且在 docker 之間的溝通,若是不屬於同一個網域的 docker,很多地方需要手動處理。

而在 network 的出現,docker-swarm 總算可以更進一步成為維運人員的神兵利器:

  1. 透過 docker-machine 來控制多台 docker engine
  2. 透過 docker-swarm 來整合多台 docker engine 資源
  3. 透過 docker-compose 來配置多個 docker 之間的溝通

著實是一個重要的里程碑,個人認為是非常夢幻的組合!

本文章將針對如何搭配 network 利用 docker-swarm 控制多網路區域的 Docker 進行說明。

參考資料

Consul 搭配 Docker 之架構

使用 Consul 主要的目的是讓可能運行在不同雲端或是不在同一個網域的 Docker 可以知道彼此的位置,其架構圖如下:

如上圖所示,我們需要建置:

  1. Consul Key Store daemon
  2. Docker Swarm master
  3. Docker Swarm node

過程中透過 docker-machine 來建立相關的 docker engine,並且透過 Swarm master 來分派每個 docker container 要執行的節點。

設置 Consul key-value store

第一步驟,我們需要建立 Consul Key Store daemon,透過下列指令。

docker-machine create -d virtualbox mh-keystore

接著,我們可以透過

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

讓 docker-machine 把 docker engine 控制權切換到 mh-keystore。

mh-keystore 的 docker engine 將會提供相關資訊給 cluster node 之 docker engine 以便後續控制,下面是讀取設定得語法:

docker-machine config mh-keystore

將會輸出下面資料

--tlsverify
--tlscacert="/Users/spooky/.docker/machine/certs/ca.pem" --tlscert="/Users/spooky/.docker/machine/certs/cert.pem" --tlskey="/Users/spooky/.docker/machine/certs/key.pem"
-H=tcp://192.168.99.103:2376%

透過上面的內容,我們需要建立 consul docker 並且啟動

docker $(docker-machine config mh-keystore) run -d \
    -p "8500:8500" \
    -h "consul" \
    progrium/consul -server -bootstrap

建立 cluster node 之 docker engine

為了展示,我們需要建立兩個節點,分別如下:

swarm master

docker-machine create \
-d virtualbox \
--swarm --swarm-image="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

相關屬性說明

  • --swarm-master: 指定此 docker engine 為主要 swarm 節點。
  • --swarm-discovery: 告訴 swarm 節點,可以去哪裡查看控管的節點。
  • --cluster-store: 告訴 docker engine 在 overlay network 底下 key-value store 所在位置。
  • --cluster-advertise: 則當 docker machine 建立 docker engine 時連帶 public cluster network 以便外部可以存取。

swarm node

docker-machine create -d virtualbox \
--swarm --swarm-image="swarm:1.0.0" \
--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

除了 --swarm-master 這 option 沒有之外其他都跟 swarm master 相同,運作上,一旦 swarm node 建立之後就會在 mh-keystore 進行註冊,而 swarm master 要進行資源分配時也會透過 mh-keystore 來了解目前所有節點的連接方式,以便後續進行處理。

有了 Consul 的協助,才能讓 swarm 的監控立於 local 之上,對 多網路區域 進行控管。

建立完成後,再透過 docker-machine ls 查看一下目前有的 machine 有哪些,顯示如下:

NAME          ACTIVE   DRIVER       STATE     URL                         SWARM
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

切換到 swarm master 節點,並且加上 --swarm 參數:

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

如此我們可以透過 swarm master 知道各節點的狀況,在執行 docker info 取的下面資訊:

Containers: 3
Images: 2
Role: primary
Strategy: spread
Filters: health, port, dependency, affinity, constraint
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.12-boot2docker, operatingsystem=Boot2Docker 1.9.0 (TCL 6.4); master : 16e4a2a - Tue Nov  3 19:49:22 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.12-boot2docker, operatingsystem=Boot2Docker 1.9.0 (TCL 6.4); master : 16e4a2a - Tue Nov  3 19:49:22 UTC 2015, provider=virtualbox, storagedriver=aufs
CPUs: 2
Total Memory: 2.043 GiB
Name: ca37a455e055

現在我們所在 docker-machine 是 swarm master,因此我們可以建立 overlay network,透過下面指令:

docker network create --driver overlay my-net

如此既使此 swarm 叢集下的節點不在同一個 host 也可以透過 overlay network 來進行 docker 間的溝通。

透過 docker network ls 來查詢目前 network 的配置,結果如下:

NETWORK ID          NAME                DRIVER
0c12ded9133d        my-net              overlay
398d539735a5        mhs-demo0/host      host
69c46465440e        mhs-demo0/bridge    bridge
60fb35d0f1b9        mhs-demo0/none      null
3d307d5ce727        mhs-demo1/bridge    bridge
063bc7f3af71        mhs-demo1/none      null
7439c6e27aa9        mhs-demo1/host      host

開始運行 docker

我們需要建立 client server 的架構來驗證運作狀況,首先我們需要 …

建立 web server 使用 nginx

指令如下:

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

該指令透過 --env="constraint:node==mhs-demo0" 來控制 docker 要建立的節點設為 mhs-demo0

透過 --net=my-net 來指定要建立在哪一個 network。

接著我們需要 …

建立 client 對 web 進行 request

指令如下:

docker run -it --rm --net=my-net --env="constraint:node==mhs-demo1" busybox wget -O- http://web

跟 web server 類似,透過 --env="constraint:node==mhs-demo1" 來控制 docker 要建立的節點為 mhs-demo1

設置在同一個 network 以便兩者可以進行溝通,另外因為 server 已有命名為 web 我們可以透過 http://web 來進行 request。

執行結果如下

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 ps 來查看一下目前 docker 的狀況

CONTAINER ID        IMAGE   COMMAND                  STATUS                   PORTS            NAMES
175be1c1bab0        busybox "wget -O- http://web"    Exited (0) 9 seconds ago                  mhs-demo1/busybox
ea02022ce6fb        nginx   "nginx -g 'daemon off"   Up 2 minutes             80/tcp, 443/tcp  mhs-demo0/web

可以看到從 NAMES 中可以清楚看到兩個 docker 分別跑在不同的 node 上,但彼此間溝通是沒有問題的。

使用 docker-compose 進行操作

設定檔如下

web:
  image: bfirsh/compose-mongodb-demo
  environment:
      - "MONGO_HOST=dockeradvancebook_mongo_1"
      - "constraint:node==mhs-demo0"
  ports:
      - "80:5000"
mongo:
  image: mongo

docker-compose --x-networking --x-network-driver overlay up -d

啟動完成後,再次透過 docker ps 來確認狀況,結果如下:

IMAGE                         COMMAND                PORTS                        NAMES
mongo                         "/entrypoint.sh mongo" 27017/tcp                    mhs-demo1/dockeradvancebook_mongo_1
bfirsh/compose-mongodb-demo   "/bin/sh -c 'python a" 192.168.99.104:80->5000/tcp  mhs-demo0/dockeradvancebook_web_1

如此就完成整個 demo,可以透過 http://192.168.99.104 存取執行結果。

結論

上述的 demo 雖然是在 VirtualBox 完成,但實際上可以整合多個機台的環境或是多個 cloud provider 進行 docker 部署,比如 azure + digitalocean。

透過 Consul 跟 Docker 最新特性 network 的幫忙,讓 Swarm 的控制可以立於 overlay network ,使 Docker 部署更方便之外,也讓配置更加容易。

嘗試看看!你將會感受到它所帶來的威力與方便性。

Subscribe To Our Newsletter

Get updates and learn from the best

More To Explore

Do You Want To Boost Your Business?

drop us a line and keep in touch