Docker Swarmで複数Dockerホストからクラスタを作る
Docker Machineを使ってVirtualbox, AWS, ESXiにDockerホストを構築するでは、Docker machineによりVirtualBox上にDockerホストを構築した。Dockerホストを複数起動しているとそれらを1つのリソースプールとして扱いたいケースが当然出て来る。そこで、今回はDocker Swarmを使ってVirtualBox上にDocker Machineで構築した複数のDockerホストからクラスタを作ってみる。
Docker Swarmとは
Docker Swarmとは、複数のDockerホストを1つのリソースプールとして束ねて、どのコンテナをどのホスト上で起動するかスケジューリング(配置決定)するツールである。Docker Swarmを使う場合、Dockerホストはクラスターを管理するSwarm Managerとクラスターを形成するSwarmノードにいずれかに属し、クラスタへの命令はSwarm Manager経由で行われる。
この辺を解りやすく説明されているスライドがあるので、詳しくはこちらを見て頂きたい。
[slideshare id=53220740&doc=introductiontodockerswarmdistribution-150926102344-lva1-app6892]
使用感をとりあえずみたいという人は動画もある。
準備
前準備として、Docker Toolboxをインストールしておく。まだインストールしていない場合は、Docker ToolboxでMac OSXにDocker環境を最速で構築するを参考にインストールする。
Docker Swarmによるクラスタ形成
Discovery backend
Docker SwarmではSwarmノード(束ねられるDockerホスト)をDocker Swarm discovery で管理する。つまり、Swarm Managerはノードの情報を持っていない。Discovery backendはetcd、consul、Zookeeperなどを利用して自前で用意することも可能だが、ここではDocker HubがホスティングしているTokenベースのDiscovery backendを利用することとする。
Cluster-idの発行
Docker HubがホスティングしているDiscovery backendを利用するにはcluster-idの発行が必要である。このcluster-idはswarm create
を実行すると生成される。ここでは、以下のようにdummy-vmというDockerホストを構築してその上のコンテナ内でcluster-idを生成する。
まず、dummy-vmという名前のDockerホストを作る。
➤ docker-machine create -d virtualbox dummy-vm
作成したDockerホストの環境情報をshellに読み込ませる。
➤ eval “$(docker-machine env local)”
swarm create
コマンドを実行してcluster-idを発行する。
➤ docker run swarm create Unable to find image ‘swarm:latest’ locally latest: Pulling from library/swarm2bc79aec8ea0: Pull complete dc2fb86a875a: Pull complete 435e648d0f23: Pull complete e16042a92d05: Pull complete 045bd7b00b5b: Pull complete 3caea1253d76: Pull complete 2b4c55187a27: Pull complete 6b40fe7724bd: Pull complete Digest: sha256:51a30269d3f3aaa04f744280e3c118aea032f6df85b49819aee29d379ac313b5 Status: Downloaded newer image for swarm:latest ff6fd6b7850bab731b5af5ba2e3120d3 #cluster-id(機密情報として扱うこと)
cluster-idが手に入ったらdummy-vmは必要ないので削除する。
➤ docker-machine rm dummy-vm
途中でeval "$(docker-machine env local)"
を実行したが、この手順を踏まないとdummy-vmの環境情報がshellに読み込まれないため、docker runがdummy-vmに向けて実行出来ない。
➤ docker-machine env dummy-vm export DOCKER_TLS_VERIFY="1" export DOCKER_HOST="tcp://192.168.99.100:2376" export DOCKER_CERT_PATH="/Users/takanabe/.docker/machine/machines/dummy-vm" export DOCKER_MACHINE_NAME="dummy-vm" # Run this command to configure your shell: # eval "$(docker-machine env dummy-vm)" # eval "$(docker-machine env dummy-vm)"を実行していないケース ➤ docker run swarm create Cannot connect to the Docker daemon. Is the docker daemon running on this host?
クラスタを作る(Swarm Manager、ノードの構築)
cluster-idが取得できたらいよいよクラスタを作る。下図のようなSwarm Manager(swarm-mng-vm01)×1、Swarmノード(swarm-node-vm01,02)×2の構成を取ってみる。[1]
まずはSwarm Managerを構築する。通常のDockerホスト生成のコマンドに--swarm
、--swarm-master
、--swarm-discovery
を付与するだけ。この時、先ほど取得したcluster-idを--swarm-discovery
で利用する。
➤ docker-machine create \ -d virtualbox \ --swarm \ --swarm-master \ --swarm-discovery token://ff6fd6b7850bab731b5af5ba2e3120d3 \ swarm-mng-vm01
SwarmノードはManagerから--swarm-master
を除いたものを実行するだけでOK。
➤ docker-machine create \ -d virtualbox \ --swarm \ --swarm-discovery token://ff6fd6b7850bab731b5af5ba2e3120d3 \ swarm-node-vm-01 ➤ docker-machine create \ -d virtualbox \ --swarm \ --swarm-discovery token://ff6fd6b7850bab731b5af5ba2e3120d3 \ swarm-node-vm-02
これでクラスタが作られた。
クラスタを操作する
クラスタを操作するにはMangerの環境情報を取得する必要がある。
➤ eval $(docker-machine env --swarm swarm-mng-vm01)
こうすることで、通常のdockerコマンドがdocker deamonではなくdocker swarm managerを経由される。試しに、クラスタ情報とクラスタ内のコンテナの状態を取得する。
➤ docker info Containers: 6 Images: 5 Role: primary Strategy: spread Filters: health, port, dependency, affinity, constraint Nodes: 3 swarm-mng-vm01: 192.168.99.100:2376 └ Containers: 2 └ Reserved CPUs: 0 / 1 └ Reserved Memory: 0 B / 1.021 GiB └ Labels: executiondriver=native-0.2, kernelversion=4.1.13-boot2docker, operatingsystem=Boot2Docker 1.9.1 (TCL 6.4.1); master : cef800b - Fri Nov 20 19:33:59 UTC 2015, provider=virtualbox, storagedriver=aufs swarm-node-vm-01: 192.168.99.101:2376 └ Containers: 2 └ Reserved CPUs: 0 / 1 └ Reserved Memory: 0 B / 1.021 GiB └ Labels: executiondriver=native-0.2, kernelversion=4.1.13-boot2docker, operatingsystem=Boot2Docker 1.9.1 (TCL 6.4.1); master : cef800b - Fri Nov 20 19:33:59 UTC 2015, provider=virtualbox, storagedriver=aufs swarm-node-vm-02: 192.168.99.102:2376 └ Containers: 2 └ Reserved CPUs: 0 / 1 └ Reserved Memory: 0 B / 1.021 GiB └ Labels: executiondriver=native-0.2, kernelversion=4.1.13-boot2docker, operatingsystem=Boot2Docker 1.9.1 (TCL 6.4.1); master : cef800b - Fri Nov 20 19:33:59 UTC 2015, provider=virtualbox, storagedriver=aufs CPUs: 3 Total Memory: 3.064 GiB Name: e5063deb85f9 ➤ docker ps -a 946d3aa59df9 swarm:latest "/swarm join --advert" 4 minutes ago Up 8 minutes 2375/tcp swarm-node-vm-02/swarm-agent 622d96847028 swarm:latest "/swarm join --advert" 8 minutes ago Up 16 minutes 2375/tcp swarm-node-vm-01/swarm-agent da2e32a08de5 swarm:latest "/swarm join --advert" 12 minutes ago Up 18 minutes 2375/tcp swarm-mng-vm01/swarm-agent e5063deb85f9 swarm:latest "/swarm manage --tlsv" 12 minutes ago Up 18 minutes 2375/tcp, 192.168.99.100:3376->3376/tcp swarm-mng-vm01/swarm-agent-master
続いて、Swarmノード上に以下のようにコンテナを作ってみる。
いつものようにコンテナを作成するコマンドを実行するだけ。
➤ docker run –name hello01 hello-world ➤ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6e5c4966d8c2 hello-world “/hello” 4 minutes ago Exited (0) 4 minutes ago swarm-node-vm-02/hello01 946d3aa59df9 swarm:latest “/swarm join –advert” 8 minutes ago Up 8 minutes 2375/tcp swarm-node-vm-02/swarm-agent 622d96847028 swarm:latest “/swarm join –advert” 16 minutes ago Up 16 minutes 2375/tcp swarm-node-vm-01/swarm-agent da2e32a08de5 swarm:latest “/swarm join –advert” 18 minutes ago Up 18 minutes 2375/tcp swarm-mng-vm01/swarm-agent e5063deb85f9 swarm:latest “/swarm manage –tlsv” 18 minutes ago Up 18 minutes 2375/tcp, 192.168.99.100:3376->3376/tcp swarm-mng-vm01/swarm-agent-masterうん、swarm-node-vm02上にコンテナができてる。2つ追加してみる。
# hello02コンテナの作成 ➤ docker run --name hello02 hello-world ➤ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cb91261de325 hello-world "/hello" 10 seconds ago Exited (0) 9 seconds ago swarm-node-vm-01/hello02 6e5c4966d8c2 hello-world "/hello" 5 minutes ago Exited (0) 5 minutes ago swarm-node-vm-02/hello01 946d3aa59df9 swarm:latest "/swarm join --advert" 9 minutes ago Up 9 minutes 2375/tcp swarm-node-vm-02/swarm-agent 622d96847028 swarm:latest "/swarm join --advert" 17 minutes ago Up 17 minutes 2375/tcp swarm-node-vm-01/swarm-agent da2e32a08de5 swarm:latest "/swarm join --advert" 19 minutes ago Up 19 minutes 2375/tcp swarm-mng-vm01/swarm-agent e5063deb85f9 swarm:latest "/swarm manage --tlsv" 19 minutes ago Up 19 minutes 2375/tcp, 192.168.99.100:3376->3376/tcp swarm-mng-vm01/swarm-agent-master # hello03コンテナの作成 ➤ docker run --name hello03 hello-world ➤ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 364d42fa440e hello-world "/hello" 3 seconds ago Exited (0) 2 seconds ago swarm-mng-vm01/hello03 cb91261de325 hello-world "/hello" 2 minutes ago Exited (0) 2 minutes ago swarm-node-vm-01/hello02 6e5c4966d8c2 hello-world "/hello" 7 minutes ago Exited (0) 7 minutes ago swarm-node-vm-02/hello01 946d3aa59df9 swarm:latest "/swarm join --advert" 11 minutes ago Up 11 minutes 2375/tcp swarm-node-vm-02/swarm-agent 622d96847028 swarm:latest "/swarm join --advert" 19 minutes ago Up 19 minutes 2375/tcp swarm-node-vm-01/swarm-agent da2e32a08de5 swarm:latest "/swarm join --advert" 21 minutes ago Up 21 minutes 2375/tcp swarm-mng-vm01/swarm-agent e5063deb85f9 swarm:latest "/swarm manage --tlsv" 21 minutes ago Up 21 minutes 2375/tcp, 192.168.99.100:3376->3376/tcp swarm-mng-vm01/swarm-agent-master
ちゃんとswarm-node-vm01,02上にコンテナができてる。docker info
で確認したように現在のコンテナスケジューリングはデフォルトのSpread Strategyに従っている。スケジューリングの設定を変更したい場合はStrategyとFilterを変更すること。
参考
公式ドキュメント
- Docker Swarm
- Docker Swarm : Get Started with Docker Swarm
- Docker Swarm discovery
- Docker Swarm strategies
- Docker Swarm filters
他ユーザ使用感
[1] 厳密にはSwarm MasterもSwarm Agentもコンテナで起動される。