Get started with Docker Part 4: Swarms

Dodkcer Get Started 隨手記。

Part 4: Swarms

這個 part 會 deploy app 到 cluster 並執行在多個 machine 上。

Linux 要先安裝 Docker Machine

Swarm

A swarm is a group of machines that are running Docker and joined into a cluster.

swarm 是一群 cluster 中跑著 Docker 的機器。機器加入 cluster 後,在上面執行的 Docker command 由 swarm manager 在 cluster 中執行。

The machines in a swarm can be physical or virtual. After joining a swarm, they are referred to as nodes.

一台加入 swarm 的機器稱為 node。

swarm 中只有 swarm manager 可以執行 command、讓其他機器加入 swarm 當 worker。worker 就只是執行,不能叫其他人做事或讓其他機器加入 swarm。swarm manager 可以用多種策略來執行 container。

平常 Docker 是在 single-host mode 執行,轉成 swarm mode 才能使用 swarm 相關功能。讓一台機器變成 swarm manager 後,Docker 會將 command 執行在它管理的 swarm 上,而非只在目前的機器。

Set up swarm

docker swarm init 把一台機器變成 swarm manager,再到其他要當 worker 的機器上執行 docker swarm join

接下來用 VM 建個 cluster。

因為用 VM,Linux 上要先裝 VirtualBox

使用 docker-machine 產生兩台 VM:

1
2
$ docker-machine create --driver virtualbox myvm1
$ docker-machine create --driver virtualbox myvm2

列出 VM:

1
2
3
4
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
myvm1 - virtualbox Running tcp://192.168.99.100:2376 v19.03.1
myvm2 - virtualbox Running tcp://192.168.99.101:2376 v19.03.1

接下來讓 myvm1 當 swarm manager、myvm2 當 worker。

透過 docker-machine ssh <vm> "<command>" 可以在 VM 上執行指令:

1
$ docker-machine ssh myvm1 "docker swarm init --advertise-addr <myvm1 ip>"

上面指令會得到將 worker 加入此 swarm 的 command,到 myvm2 上執行:

1
$ docker-machine ssh myvm2 "docker swarm join --token <token> <swarm manager ip>:<port>"

port 預設是 2377。

myvm1 看 node:

1
$ docker-machine ssh myvm1 "docker node ls"

最後 node 離開 swarm:

1
$ docker-machine ssh myvm2 "docker swarm leave"

docker-machine shell

docker-machine ssh 打起來很長,VM 也無法 access VM host 的檔案。用 docker-machine env <machine> 設定可以讓 shell 直接跟 VM 溝通:

1
2
3
4
5
6
7
$ docker-machine env myvm1
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.99.100:2376"
export DOCKER_CERT_PATH="/home/cjw/.docker/machine/machines/myvm1"
export DOCKER_MACHINE_NAME="myvm1"
# Run this command to configure your shell:
# eval $(docker-machine env myvm1)

執行 eval $(docker-machine env myvm1),接著用 docker-machine ls 確認目前 shell active 的 machine(ACTIVE column):

1
2
3
4
$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
myvm1 * virtualbox Running tcp://192.168.99.100:2376 v19.03.1
myvm2 - virtualbox Running tcp://192.168.99.101:2376 v19.03.1

之後執行 docker 指令都是在 myvm1 上執行囉!比較方便而且可以 access 到 VM host 的檔案。要換到別的 machine 就再執行一次 docker-machine env <machine><machine> 換掉即可。

在 swarm manager 上 deploy app

跟 part 3 一樣,只是 part 3 是把本機直接變成 swarm manager,現在 swarm manager 是 myvm1(把它當作遠端)。

一樣用 docker stack deploy -c docker-compose.yml <stack_name> 來 deploy app。跟 part 3 不同的是現在 service 會分別開在 myvm1myvm2 上:

1
2
3
4
5
6
7
$ docker service ps getstartedlab_web
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
hprga9r6s5se getstartedlab_web.1 cjwind/get-started:part2 myvm2 Running Running 18 minutes ago
n1bc2c2xosal getstartedlab_web.2 cjwind/get-started:part2 myvm1 Running Running 18 minutes ago
rbkv7bctikfq getstartedlab_web.3 cjwind/get-started:part2 myvm2 Running Running 18 minutes ago
mr1o60i52f6u getstartedlab_web.4 cjwind/get-started:part2 myvm2 Running Running 18 minutes ago
4k7ehhz2nzl3 getstartedlab_web.5 cjwind/get-started:part2 myvm1 Running Running 18 minutes ago

到這裡完成了將 app deploy 到 cluster 上,並且 service 有 load-balanced!

access swarm 上的 app

可以透過 swarm 中任何一個 node 的 IP 去 access app。這是藉由讓 node 在 ingress routing mesh 裡達到。

[source]

在 swarm mode 打開前,swarm node 間的 port 7946 TCP/UDP 以及 port 4789 UDP 要開啟,ingress network 才能運作,所以要注意 app 不能佔用這些 port。

scale up in cluster

要讓 service 使用更多 node,只要先用 docker swarm join 增加 node,再 docker stack deploy,service 就能使用增加的 node。

Cleanup

清掉 docker-machine 的環境變數:

1
$ eval $(docker-machine env -u)

結束 stack 的所有 service、刪掉 stack:

1
$ docker stack rm <stack_name>