swarm

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を生成する。

20151123_create_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/swarm

2bc79aec8ea0: 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]

20151123_create_cluster

まずは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ノード上に以下のようにコンテナを作ってみる。 20151123_create_containers

いつものようにコンテナを作成するコマンドを実行するだけ。

➤  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を変更すること。

参考

公式ドキュメント

他ユーザ使用感

[1] 厳密にはSwarm MasterもSwarm Agentもコンテナで起動される。