先日リリースされた Docker 1.12 から Docker Swarm が本体に同梱されるようになった。 この Docker Swarm というのは、複数の Docker ホストを束ねて使えるようにするオーケストレーションツールになっている。 今回は、その Docker Swarm がどういったものなのかを一通り触って試してみることにする。
今回使った環境は次の通り。 CentOS 7 を Docker ホストの OS に使う。
$ cat /etc/redhat-release CentOS Linux release 7.2.1511 (Core) $ uname -r 3.10.0-327.el7.x86_64
なお、Docker ホストは 3 台構成で、それぞれ node1, node2, node3 と呼ぶことにする。 各ノードはお互いに通信する必要があるので IP アドレスを 192.168.33.11, 192.168.33.12, 192.168.33.13 と振っておく。
ただ、この初期構築は結構めんどくさい。 なので、今回は Vagrant で途中まで自動化したものも用意した。 具体的には Docker のインストールと必要なポートを開けるところまで。
Vagrantfile for Docker Swarm · GitHub
使い方は次の通り。
$ git clone https://gist.github.com/1dc33c45e47c75d03408a44e63c7daa7.git vagrant-docker-swarm $ cd vagrant-docker-swarm $ vagrant up
以下は手動で構築する場合の手順になっている。 また、上記で構築できるのは Docker のインストールまで。 だから、クラスタの構築やサービスの定義はいずれにせよ手動で実施する必要がある。
初期設定
それでは各ホストを手動で構築していこう。 まずはホスト名を設定する。
$ sudo hostname node1.example.com $ cat << 'EOF' | sudo tee /etc/hostname > /dev/null node1.example.com EOF
上記で設定する値 (nodeX) は各ホストごとに異なるので注意してほしい。
通信用のポートを開ける
次に Docker Swarm がクラスタ内で通信するのに使うポートを開ける。 具体的には 2377/TCP, 7946/TCP, 4789/TCP, 7946/UDP, 4789/UDP を開ける必要がある。
ただし、ひとつ注意点があって CentOS7 標準の firewalld ではなく iptables を直接使う必要があるようだ。
そこで、まずは firewalld のサービスを止める。
$ sudo systemctl stop firewalld
$ sudo systemctl disable firewalld
そして、代わりに iptables をインストールする。
$ sudo yum -y install iptables-services
$ sudo systemctl start iptables
$ sudo systemctl enable iptables
必要なポートを開けていこう。 先ほど挙げたポート以外に 80/TCP も開けている。 これは後ほど Docker コンテナ内で立ち上げるサービスへのアクセスに使う。
$ for i in 80 2377 7946 4789; do sudo iptables -I INPUT -j ACCEPT -p tcp --dport $i; done; $ for i in 7946 4789; do sudo iptables -I INPUT -j ACCEPT -p udp --dport $i; done;
ポートを開けることができたら設定を保存しておく。
$ sudo service iptables save
Docker をインストールする
次に Docker 本体をインストールする。
その前に、まずはパッケージを最新の状態にしておこう。
$ sudo yum -y update
次に Docker の提供するリポジトリを yum に登録する。 CentOS7 が標準で使える Docker は、公式が提供するそれよりも古いため。
$ cat << 'EOF' | sudo tee /etc/yum.repos.d/docker.repo > /dev/null [dockerrepo] name=Docker Repository baseurl=https://yum.dockerproject.org/repo/main/centos/7/ enabled=1 gpgcheck=1 gpgkey=https://yum.dockerproject.org/gpg EOF
一旦 yum のキャッシュをクリアする。
$ sudo yum clean all
そして Docker 本体をインストールする。 Docker Swarm はバージョン 1.12 から本体に同梱されるようになった。 そのため、これだけで使えるようになる。
$ sudo yum -y install docker-engine
インストールできたら Docker のサービスを起動する。
$ sudo systemctl start docker
$ sudo systemctl enable docker
インストールできたら docker version コマンドを実行しよう。 次のようにクライアントとサーバの両方でエラーが出ていなければ問題ない。
$ sudo docker version Client: Version: 1.12.0 API version: 1.24 Go version: go1.6.3 Git commit: 8eab29e Built: OS/Arch: linux/amd64 Server: Version: 1.12.0 API version: 1.24 Go version: go1.6.3 Git commit: 8eab29e Built: OS/Arch: linux/amd64
ついでに Docker コンテナが実行できることも確認しておこう。 hello-world イメージを使って、次のようなメッセージになれば大丈夫。
$ sudo docker run hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world c04b14da8d14: Pull complete Digest: sha256:0256e8a36e2070f7bf2d0b0763dbabdd67798512411de4cdcf9431a1feb60fd9 Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker Hub account: https://hub.docker.com For more examples and ideas, visit: https://docs.docker.com/engine/userguide/
上記の作業をすべての Docker ホストで実行しよう。 そして、先ほど紹介した Vagrantfile で実行できるのは、ここまで。
また、次の作業からは各 Docker ホストで実行する内容が異なる。
クラスタを作る
さて、ここからはいよいよ Docker Swarm の機能を使っていく。 各ホストで実行する内容が異なるのでターミナルの先頭にノード名を記述することにする。
まずは Docker ホストを束ねたクラスタを作る。 クラスタにはマネージャとワーカというふたつの役割がある。 ワーカは Docker コンテナが動作するだけの Docker ホストになっている。 マネージャは、それに加えてクラスタの管理などを行う。
今回は node1 をマネージャにして、その他のホスト node2 と node3 をワーカにしてクラスタを組んでみよう。
まずはマネージャとして動作する node1 で docker swarm init コマンドを実行する。 これでクラスタを作成できる。 オプションの --listen-addr と --advertise-addr にはクラスタの通信で使う IP アドレスとポートを指定する。
node1 $ sudo docker swarm init --listen-addr 192.168.33.11:2377 --advertise-addr 192.168.33.11:2377 Swarm initialized: current node (37v1n4u827kqfv2iwuh0u395r) is now a manager. To add a worker to this swarm, run the following command: docker swarm join \ --token SWMTKN-1-1q6s0gycuxtt3hjqlrd02pmnu555fju2m62vx0ivvmnytbp9hs-83fccs5u4bb9lsb40fo9gbd69 \ 192.168.33.11:2377 To add a manager to this swarm, run the following command: docker swarm join \ --token SWMTKN-1-1q6s0gycuxtt3hjqlrd02pmnu555fju2m62vx0ivvmnytbp9hs-c2co7kyo54yc9z3vnvz0ykbhf \ 192.168.33.11:2377
何やら色々と表示されているけど、これは他のノードがクラスタに参加するためのコマンドになっている。 このトークンを知らないとクラスタには参加できないというわけ。
トークンにはマネージャ用とワーカ用のふたつがある。 つまりマネージャもワーカも複数台をクラスタに追加できるということ。
クラスタに参加しているノードの状態は docker node ls コマンドで確認できる。 今はクラスタを作成した直後なので、参加しているノードは node1 だけ。
node1 $ sudo docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS 37v1n4u827kqfv2iwuh0u395r * node1.example.com Ready Active Leader
クラスタにノードを追加する
先ほど作ったクラスタにノードを追加しよう。 追加するには、先ほどクラスタを作成したときに表示されたコマンドを使う。
まずは node2 をクラスタに参加させる。
node2 $ sudo docker swarm join --token SWMTKN-1-1q6s0gycuxtt3hjqlrd02pmnu555fju2m62vx0ivvmnytbp9hs-83fccs5u4bb9lsb40fo9gbd69 192.168.33.11:2377 This node joined a swarm as a worker.
そして node3 も同じようにクラスタに参加させる。
node3 $ sudo docker swarm join --token SWMTKN-1-1q6s0gycuxtt3hjqlrd02pmnu555fju2m62vx0ivvmnytbp9hs-83fccs5u4bb9lsb40fo9gbd69 192.168.33.11:2377 This node joined a swarm as a worker.
上記が実行できたら node1 で再び docker node ls コマンドを実行してみよう。 今度は 3 台が表示されるはず。
node1 $ sudo docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS 33mmomv1up2azt0e38h959a48 node2.example.com Ready Active 37v1n4u827kqfv2iwuh0u395r * node1.example.com Ready Active Leader 5opby7sfnpovoqshnjkymxe0s node3.example.com Ready Active
動作確認用の Docker イメージをダウンロードする
次に Docker Swarm の動作を確認するための Docker イメージをダウンロードしよう。 このイメージは Docker コンテナの ID を HTTP (80/TCP) で返すだけのシンプルなものになっている。
https://hub.docker.com/r/momijiame/greeting/
なぜ、このようなものが必要かというと Docker Swarm にはロードバランス機能が備わっているため。 詳しくは後述するが、クラスタ内で動作する各コンテナにアクセスを振り分けることができる。 そこで、アクセス先のコンテナを確認するために上記のようなイメージを用意した。
このイメージを、それぞれの Docker ホストでダウンロードしておこう。 一応、これはやらなくても必要なときにダウンロードされるので動作はする。 とはいえ、あらかじめやっておいたほうが必要な時間の短縮につながるはず。
まずは node1 でダウンロードする。 バージョン (タグ) が複数あるのは、あとで Docker Swarm のローリングアップデート機能を試すため。
node1 $ sudo docker pull momijiame/greeting:1.0 node1 $ sudo docker pull momijiame/greeting:2.0 node1 $ sudo docker pull momijiame/greeting:latest
同じように node2 でもダウンロードする。
node2 $ sudo docker pull momijiame/greeting:1.0 node2 $ sudo docker pull momijiame/greeting:2.0 node2 $ sudo docker pull momijiame/greeting:latest
そして node3 でもダウンロードする。
node3 $ sudo docker pull momijiame/greeting:1.0 node3 $ sudo docker pull momijiame/greeting:2.0 node3 $ sudo docker pull momijiame/greeting:latest
サービスを定義する
さて、ここまでで Docker Swarm を使う準備が整った。 次はクラスタに対してサービスを定義する。 サービスというのは、ようするにクラスタの上で提供してほしい機能をいう。 これは、例えば HTML の静的なホスティングかもしれないし、Rails のアプリケーションだったりするかもしれない。 その内容は、サービスで使う Docker イメージに依存する。
それでは docker service create コマンドを使ってサービスを定義しよう。 名前は helloworld にする。 --replicas オプションは、いくつの Docker ホスト上でコンテナを動作させたいかを表している。 -p オプションは docker run コマンドのときと同じように、提供するポートフォワーディングの設定だ。 そして最後がサービスで使用する Docker イメージになっている。 この他にもオプションは多数あるけど、ここで使うのは上記だけ。
node1 $ sudo docker service create --name helloworld --replicas=2 -p 80:8000 momijiame/greeting:1.0 f44y32qiu9mlma2gcffi0o4xs
docker service ls コマンドでクラスタが提供しているサービスが見られる。
node1 $ sudo docker service ls ID NAME REPLICAS IMAGE COMMAND f44y32qiu9ml helloworld 2/2 momijiame/greeting:1.0
上記は概要なので、より詳しい内容は docker service inspect コマンドを使おう。
node1 $ sudo docker service inspect --pretty helloworld ID: f44y32qiu9mlma2gcffi0o4xs Name: helloworld Mode: Replicated Replicas: 2 Placement: UpdateConfig: Parallelism: 1 On failure: pause ContainerSpec: Image: momijiame/greeting:1.0 Resources: Ports: Protocol = tcp TargetPort = 8000 PublishedPort = 80
サービスの稼働状況を調べるには docker service ps コマンドを使うと良い。
$ sudo docker service ps helloworld ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 7uaq5jpd7zu3wx4y0t4qrxzqr helloworld.1 momijiame/greeting:1.0 node3.example.com Running Running 42 seconds ago 634or7vt454kja1xyzb5fxcqb helloworld.2 momijiame/greeting:1.0 node2.example.com Running Running 41 seconds ago
上記は helloworld サービスにおいて Docker コンテナが node2 と node3 で実行されていることを表している。
アクセス
さて、これだけでコンテナが各 Docker ホスト上にばらまかれて稼働し始めている。 実際にコンテナにアクセスしてみよう。 アクセスする先はポートフォワーディングをしている Docker ホストになる。
また、アクセスする先の IP アドレスは、コンテナが実際に稼働している Docker ホストを意識する必要がない。 なぜなら、クラスタ内のどの Docker ホストにアクセスしても、そのアクセスは実際に稼働している Docker ホストに振り分けられる。 また、アクセス内容もロードバランシングされる。
実際に curl コマンドを使って Docker ホストにアクセスしてみよう。
$ curl http://192.168.33.11 Hello, 1cfe277ecd10
これで、ロードバランス先のコンテナの ID が得られる。
続けて実行すると、ラウンドロビン方式でアクセスがロードバランスされていることが見て取れる。
$ curl http://192.168.33.11 Hello, 094ab7b026d0 $ curl http://192.168.33.11 Hello, 1cfe277ecd10 $ curl http://192.168.33.11 Hello, 094ab7b026d0
オートヒーリング
さて、Docker Swarm には一部のコンテナが落ちたときに別の場所で上げなおす機能もある。
例えば node2 で稼働しているコンテナを docker kill コマンドで止めてみよう。
node2 $ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1cfe277ecd10 momijiame/greeting:1.0 "/usr/local/bin/gunic" 4 minutes ago Up 4 minutes 8000/tcp helloworld.2.634or7vt454kja1xyzb5fxcqb node2 $ sudo docker kill 1cfe277ecd10 1cfe277ecd10
そして node1 で docker service ps コマンドを実行してサービスの稼働状況を確認する。 すると、node2 で動作していたコンテナがシャットダウンした代わりに node3 で新しいコンテナが動き始めている。
node1 $ sudo docker service ps helloworld ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 7uaq5jpd7zu3wx4y0t4qrxzqr helloworld.1 momijiame/greeting:1.0 node3.example.com Running Running 4 minutes ago 9eeuo9ug1og7txh2stq4m8css helloworld.2 momijiame/greeting:1.0 node1.example.com Running Running 5 seconds ago 634or7vt454kja1xyzb5fxcqb \_ helloworld.2 momijiame/greeting:1.0 node2.example.com Shutdown Failed 10 seconds ago "task: non-zero exit (137)"
node3 で確認すると、たしかにコンテナが生まれている。
node3 $ sudo docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 15d48e89915a momijiame/greeting:1.0 "/usr/local/bin/gunic" 30 seconds ago Up 27 seconds 8000/tcp helloworld.2.9eeuo9ug1og7txh2stq4m8css
レプリカ数を増やす
同時に稼働するコンテナ数 (レプリカ) を動的に増減させることもできる。 これには docker service scale コマンドを使う。
ここでは数を 2 から 3 に増やしてみよう。
node1 $ sudo docker service scale helloworld=3 helloworld scaled to 3
先ほどと同じように docker service ps コマンドを使って状況を確認しよう。 すると、すべてのノードでコンテナが稼働しはじめたことがわかる。
node1 $ sudo docker service ps helloworld ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 7uaq5jpd7zu3wx4y0t4qrxzqr helloworld.1 momijiame/greeting:1.0 node3.example.com Running Running 5 minutes ago 9eeuo9ug1og7txh2stq4m8css helloworld.2 momijiame/greeting:1.0 node1.example.com Running Running about a minute ago 634or7vt454kja1xyzb5fxcqb \_ helloworld.2 momijiame/greeting:1.0 node2.example.com Shutdown Failed about a minute ago "task: non-zero exit (137)" 43gr58ha2a2f44eyy146wccvi helloworld.3 momijiame/greeting:1.0 node2.example.com Running Running 11 seconds ago
ちなみに、レプリカ数はクラスタのノード数よりも増やすことができる。 その場合は、ひとつのノードで複数のコンテナが起動することになる。
ローリングアップデート
Docker Swarm には、サービスで使うイメージを順番に更新する機能もある。 更新している最中は、そこにアクセスが振り分けられることがない。
試しに helloworld サービスで使うイメージのタグを 1.0 から 2.0 に変更してみよう。 これには docker service update コマンドを使う。
node1 $ sudo docker service update --image momijiame/greeting:2.0 helloworld
helloworld
実行してから docker service ps コマンドを使うと、タグ 1.0 を使っていたコンテナはシャットダウンされている。 そして、代わりにタグ 2.0 を使ったコンテナが各ノードで稼働し始めていることがわかる。
node1 $ sudo docker service ps helloworld ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 5qg8rxo0sw6ywsgs1jkdf22lo helloworld.1 momijiame/greeting:2.0 node1.example.com Running Running 25 seconds ago 7uaq5jpd7zu3wx4y0t4qrxzqr \_ helloworld.1 momijiame/greeting:1.0 node3.example.com Shutdown Shutdown 28 seconds ago dr9wpc6kpftiet87m1y60nkpg helloworld.2 momijiame/greeting:2.0 node3.example.com Running Running 22 seconds ago 9eeuo9ug1og7txh2stq4m8css \_ helloworld.2 momijiame/greeting:1.0 node1.example.com Shutdown Shutdown 24 seconds ago 634or7vt454kja1xyzb5fxcqb \_ helloworld.2 momijiame/greeting:1.0 node2.example.com Shutdown Failed 8 minutes ago "task: non-zero exit (137)" 5sffoje8rnjg2uhpowoutvxk1 helloworld.3 momijiame/greeting:2.0 node2.example.com Running Running 28 seconds ago 43gr58ha2a2f44eyy146wccvi \_ helloworld.3 momijiame/greeting:1.0 node2.example.com Shutdown Shutdown 35 seconds ago
もちろんサービスの提供は継続している。
node1 $ curl http://192.168.33.11 Hello, 330a354fa8ea node1 $ curl http://192.168.33.11 Hello, cfd58c37c40d node1 $ curl http://192.168.33.11 Hello, 189668ee58a6
ちなみに、各ノードの更新間隔を指定することもできる。 これには docker service update コマンドで --update-delay オプションを指定する。 これはサービスを定義するときに指定することもできる。
$ sudo docker service update --update-delay 1m helloworld helloworld
更新間隔を 1 分に広げてイメージを変更してみよう。
$ sudo docker service update --image momijiame/greeting:latest helloworld helloworld
すると node1 が即座に更新される。
$ sudo docker service ps helloworld ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 8co9b2rt9a5u1q1xnpkmnr4xo helloworld.1 momijiame/greeting:latest node3.example.com Running Running 2 seconds ago 5qg8rxo0sw6ywsgs1jkdf22lo \_ helloworld.1 momijiame/greeting:2.0 node1.example.com Shutdown Shutdown 3 seconds ago 7uaq5jpd7zu3wx4y0t4qrxzqr \_ helloworld.1 momijiame/greeting:1.0 node3.example.com Shutdown Shutdown 8 minutes ago dr9wpc6kpftiet87m1y60nkpg helloworld.2 momijiame/greeting:2.0 node3.example.com Running Running 8 minutes ago 9eeuo9ug1og7txh2stq4m8css \_ helloworld.2 momijiame/greeting:1.0 node1.example.com Shutdown Shutdown 8 minutes ago 634or7vt454kja1xyzb5fxcqb \_ helloworld.2 momijiame/greeting:1.0 node2.example.com Shutdown Failed 16 minutes ago "task: non-zero exit (137)" 5sffoje8rnjg2uhpowoutvxk1 helloworld.3 momijiame/greeting:2.0 node2.example.com Running Running 8 minutes ago 43gr58ha2a2f44eyy146wccvi \_ helloworld.3 momijiame/greeting:1.0 node2.example.com Shutdown Shutdown 9 minutes ago
この状態では新しいコンテナの node1 と、古いコンテナの node2 にアクセスが振り分けられているようだ。 コンテナの更新中の node3 にはアクセスが振り分けられない。
$ curl http://192.168.33.11 Hello, e1c8d02b9b98 $ curl http://192.168.33.11 Hello, 189668ee58a6 $ curl http://192.168.33.11 Hello, e1c8d02b9b98 $ curl http://192.168.33.11 Hello, 189668ee58a6
しばらくすると node3 の更新がおわる。
$ sudo docker service ps helloworld ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 8co9b2rt9a5u1q1xnpkmnr4xo helloworld.1 momijiame/greeting:latest node3.example.com Running Running about a minute ago 5qg8rxo0sw6ywsgs1jkdf22lo \_ helloworld.1 momijiame/greeting:2.0 node1.example.com Shutdown Shutdown about a minute ago 7uaq5jpd7zu3wx4y0t4qrxzqr \_ helloworld.1 momijiame/greeting:1.0 node3.example.com Shutdown Shutdown 9 minutes ago dr9wpc6kpftiet87m1y60nkpg helloworld.2 momijiame/greeting:2.0 node3.example.com Running Running 9 minutes ago 9eeuo9ug1og7txh2stq4m8css \_ helloworld.2 momijiame/greeting:1.0 node1.example.com Shutdown Shutdown 9 minutes ago 634or7vt454kja1xyzb5fxcqb \_ helloworld.2 momijiame/greeting:1.0 node2.example.com Shutdown Failed 17 minutes ago "task: non-zero exit (137)" 4jwq9mphyed0zzc4pvaxrxu4i helloworld.3 momijiame/greeting:latest node1.example.com Running Preparing 1 seconds ago 5sffoje8rnjg2uhpowoutvxk1 \_ helloworld.3 momijiame/greeting:2.0 node2.example.com Shutdown Shutdown 1 seconds ago 43gr58ha2a2f44eyy146wccvi \_ helloworld.3 momijiame/greeting:1.0 node2.example.com Shutdown Shutdown 10 minutes ago
この状況では新しいコンテナの node1 と node3 にアクセスが振り分けられている。 更新中の node2 にはアクセスが振り分けられない。
$ curl http://192.168.33.11 Hello, 0734903b8f27 $ curl http://192.168.33.11 Hello, e1c8d02b9b98 $ curl http://192.168.33.11 Hello, 0734903b8f27 $ curl http://192.168.33.11 Hello, e1c8d02b9b98
そして、さらにしばらくするとすべてのコンテナの更新がおわる。
$ sudo docker service ps helloworld ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 8co9b2rt9a5u1q1xnpkmnr4xo helloworld.1 momijiame/greeting:latest node3.example.com Running Running 2 minutes ago 5qg8rxo0sw6ywsgs1jkdf22lo \_ helloworld.1 momijiame/greeting:2.0 node1.example.com Shutdown Shutdown 2 minutes ago 7uaq5jpd7zu3wx4y0t4qrxzqr \_ helloworld.1 momijiame/greeting:1.0 node3.example.com Shutdown Shutdown 11 minutes ago 838oiqxd69e5xkf12inr4hnfw helloworld.2 momijiame/greeting:latest node2.example.com Running Preparing 1 seconds ago dr9wpc6kpftiet87m1y60nkpg \_ helloworld.2 momijiame/greeting:2.0 node3.example.com Shutdown Shutdown 2 seconds ago 9eeuo9ug1og7txh2stq4m8css \_ helloworld.2 momijiame/greeting:1.0 node1.example.com Shutdown Shutdown 10 minutes ago 634or7vt454kja1xyzb5fxcqb \_ helloworld.2 momijiame/greeting:1.0 node2.example.com Shutdown Failed 18 minutes ago "task: non-zero exit (137)" 4jwq9mphyed0zzc4pvaxrxu4i helloworld.3 momijiame/greeting:latest node1.example.com Running Running about a minute ago 5sffoje8rnjg2uhpowoutvxk1 \_ helloworld.3 momijiame/greeting:2.0 node2.example.com Shutdown Shutdown about a minute ago 43gr58ha2a2f44eyy146wccvi \_ helloworld.3 momijiame/greeting:1.0 node2.example.com Shutdown Shutdown 11 minutes ago
この状況では、すべてのコンテナにアクセスが振り分けられる。
$ curl http://192.168.33.11 Hello, 5df4881d10a3 $ curl http://192.168.33.11 Hello, 0734903b8f27 $ curl http://192.168.33.11 Hello, e1c8d02b9b98
サービスを削除する
最後に、サービスが不要になったら docker service rm コマンドで削除しよう。
$ sudo docker service rm helloworld helloworld
まとめ
Docker 1.12 からオーケストレーションツールの Docker Swarm が本体に同梱されるようになった。 運用に必要そうな機能も一通り揃っていて、単独ですぐに使い始められるところが魅力的だと感じた。