最新的 Docker 1.9.0 在 11 月份正式推出,且多了 network 的設置,剛開始看到時似乎沒什麼新奇,在社群上看到相關的文章,在一開始 docker-swarm 在官方網站用的是 local 的環境來進行展示,參考:Install and Create a Docker Swarm。
其實已經很方便了,但尚未可以透過 docker-compose 讓設置方式一目了然,畢竟是多環境的架構,若有沒有一個很好的配置檔,在維護上將會讓人卻步,且在 docker 之間的溝通,若是不屬於同一個網域的 docker,很多地方需要手動處理。
而在 network 的出現,docker-swarm 總算可以更進一步成為維運人員的神兵利器:
- 透過 docker-machine 來控制多台 docker engine
- 透過 docker-swarm 來整合多台 docker engine 資源
- 透過 docker-compose 來配置多個 docker 之間的溝通
著實是一個重要的里程碑,個人認為是非常夢幻的組合!
本文章將針對如何搭配 network 利用 docker-swarm 控制多網路區域的 Docker 進行說明。
參考資料
Consul 搭配 Docker 之架構
使用 Consul 主要的目的是讓可能運行在不同雲端或是不在同一個網域的 Docker 可以知道彼此的位置,其架構圖如下:
如上圖所示,我們需要建置:
- Consul Key Store daemon
- Docker Swarm master
- 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 部署更方便之外,也讓配置更加容易。
嘗試看看!你將會感受到它所帶來的威力與方便性。