Posted at

Docker ComposeをDockerのswarm modeで使えるようになったので試してみた

More than 1 year has passed since last update.

先日リリースされたDocker 1.13で、swarm mode上でのdocker composeが使えるようになったのでさっそく試しました。


何が嬉しいのか

まず、1.12でdockerにビルトインのswarm modeが追加されました。

その時はクラスタをサクッと作れて嬉しいぞ!と歓喜したものです。

しかし、使ってるとservice作るのがめんどくせえ…、とすぐになりました。

そうです。

docker-composeだと各サービスを宣言的に書けるのですが、これがswarm modeのクラスタを対象としていませんでした。

/(^o^)\ナンテコッタイ

serviceをコンスタントに再現可能にするためには職人によるシェルスクリプトを残すなどの工夫が必要になります。

それはそれでまあ別にいいんですが…。

まあでもツラいです。

そこで1.13ですよ。

docker-composeによる宣言的なサービスオプションの定義をswarm modeのクラスタ上で展開できます。

これで必要な定義をdocker-composeで管理できます。

スクリプトを管理するよりか差分など見やすくなるはずです。


ちょっと用語説明

ざっくりこんな感じ


  • スタック: docker-composeで管理するサービスのまとまり

  • マネージャノード: クラスタをコントロールするノード。通常だとワーカーノードも兼ねてます。

  • ワーカーノード: コンテナを実行するノード。

  • サービス: コンテナによって実現されるあるプロセス

  • タスク: 動いてるコンテナ


Swarm ModeでDocker Composeを使ってみる


docker-compose.yml

まずはcomposeファイルを用意しましょう。

swarm modeで使うにはスキーマバージョンを3にする必要があります。

version: '3' # ←コレ

services:
hogehoge:...

公式リファレンスにもバージョン3についての記述があるので読んどくといいです。

基本は23にすれば動きます。


クラスタ作成

適当にdocker swarm initdocker swarm joinで複数ノードのクラスタ構成してください。

以前に書いた記事を参考にしてもいいかも。

今回は以下の構成にしています。


  • manager node: 1

  • worker node: 3


composeファイル

こんな感じにしました。

公式のRedmineイメージを参考(パクった)にしました。

portainerはswarm modeにも対応したコンテナ管理画面です。

今回はついでに入れてみました。

Redmine2台、MariaDB1台、Fluentdでログ収集コンテナを各ワーカーに1台、Portainerを特定のマネージャノードに1台という構成です。

見てもらえばわかるかもしれませんが、この設定だとFluentdはまともにログ収集してくれないので適当に設定してください。

DBも永続化とか全く考えてないのでそこら辺は適当に設定してください。

version: '3'

services:
redmine:
image: redmine
ports:
- 3000:3000
environment:
- REDMINE_DB_MYSQL=db
- REDMINE_DB_PASSWORD=example
depends_on:
- db
restart: always
deploy:
replicas: 2
placement:
constraints:
- node.role == worker
db:
image: mariadb
environment:
- MYSQL_ROOT_PASSWORD=example
- MYSQL_DATABASE=redmine
restart: always
deploy:
placement:
constraints:
- node.role == worker

logger:
image: fluent/fluentd
deploy:
mode: global
restart: always

portainer_master:
image: portainer/portainer
ports:
- "9000:9000"
privileged: true
volumes:
- /var/run/docker.sock:/var/run/docker.sock
command: -H unix:///var/run/docker.sock
deploy:
mode: global
placement:
constraints:
- node.name == manager-node

docker composeの記述を説明していきます。


deploy

ここがswarm modeで動かす時のキモです。

バージョン3からserviceセクションの下にdeployが追加されています。

詳細は公式見ましょう。

よく使うのはここら辺です。

services:

hoge:
deploy:
mode: global
replicas: 10
placement:
constraints:
- node.role == worker
update_config:
parallelism:



  • mode:



    • global いわゆるサイドカーと言うやつです。


    • replicated 普通のクラスタ内のノードにデプロイされるやつ。指定しないとコレ




  • placement



    • constraints docker service createの時に指定できるタスクを実行させるノードを制限するオプション


      • workerノードでだけ動かしたいとか、ノードのラベル別に実行するタスクを分けたいとかの時に使うのでわりと使います






  • update_config docker service createとかで指定するオプションと同じです。



    • parallelism デプロイ済みのスタックをUpdateするときに同時に何個ずつ実行するか



その他、restart_policyとかresourcesとかlabelがあります。


デプロイする

$ docker stack deploy redmine --compose-file docker-compose.yml

これでいけます。

実行してしばらくしたら全部起動すると思うので、確認してみましょう。

redmineがスタック名です。


stack list

$ docker stack ls 

NAME SERVICES
redmine 4


service list

$ docker service list

ID NAME MODE REPLICAS IMAGE
0hvtsyxf9w0u redmine_db replicated 1/1 mariadb:latest
5ms7e2obo0rt redmine_logger global 4/4 fluent/fluentd:latest
fqqumdfkrhmn redmine_portainer_master global 1/1 portainer/portainer:latest
uem99z2hr2km redmine_redmine replicated 2/2 redmine:latest

こっちのコマンドでも結果は同じです。

$ docker stack services redmine 

ID NAME MODE REPLICAS IMAGE
0hvtsyxf9w0u redmine_db replicated 1/1 mariadb:latest
5ms7e2obo0rt redmine_logger global 4/4 fluent/fluentd:latest
fqqumdfkrhmn redmine_portainer_master global 1/1 portainer/portainer:latest
uem99z2hr2km redmine_redmine replicated 2/2 redmine:latest


stack ps

ここまで来るとどのノードでどのコンテナが動いてるのか気になるのが人情ってもんです。

docker stack ps redmine

これだとUpdateとか失敗を繰り返してるとわけのわからないことになるのでフィルターをしましょう。

$ docker stack ps redmine --filter desired-state=Running

ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
aylrotce96e7 redmine_portainer_master.xkugj8va2mj7zvhy0h4405ken portainer/portainer:latest instance-group-1-1f68 Running Running 49 minutes ago
jf0v0z827qy3 redmine_logger.xkugj8va2mj7zvhy0h4405ken fluent/fluentd:latest instance-group-1-1f68 Running Running about an hour ago
iadivx4e7m7x redmine_logger.nc1inf0awkwscvqt3s4plvjy6 fluent/fluentd:latest instance-group-1-c6k3 Running Running about an hour ago
imata0rft454 redmine_logger.v9h0jiug1yxrm4jc2b2sxua7e fluent/fluentd:latest instance-group-1-x511 Running Running about an hour ago
kgyuz26ptxim redmine_logger.l73tho1n0stdz5swgu76n3dlp fluent/fluentd:latest instance-group-1-vt0t Running Running about an hour ago
w7idyw298gz3 redmine_redmine.1 redmine:latest instance-group-1-vt0t Running Running about an hour ago
kutu765y02xc redmine_db.1 mariadb:latest instance-group-1-c6k3 Running Running about an hour ago
u7xmk4ouxku8 redmine_redmine.2 redmine:latest instance-group-1-vt0t Running Running about an hour ago

これで稼働中のコンテナとどこのノードで動いてるのかが見れます。


Portainer

ちなみに、ブラウザで確認したい場合は、今回はportainerを動かしてるのでこちらでも見れます。

http://{manager node}:9000/

Swarmのノード一覧見たり

スクリーンショット 2017-01-24 16.06.32.png

サービスのリストを見たり、この画面でスケールさせたりできます。

スクリーンショット 2017-01-24 16.40.24.png

サービスの詳細も見れます。

Environment variablesとかLabelsとかはこの画面でもいじくれます。

Update Configの値もここでいじくれますね。

下の方にタスクのリストがあるんですが、Runningのやつだけ出したりフィルタできないのでちょっと不便。

スクリーンショット 2017-01-24 16.44.03.png


サービスの内容を変更する

再度stack deployすればUpdateされます。


まとめ

そんなわけで、1.13からはComposeで定義してそれを使ってサクッとクラスタ上でコンテナを動かせるようになりました。

ワンタイムのコンテナバッチの実行とかはSwarm Modeが対応してないのでまだできませんが、たしかIssuesあがってたと思うのでそのうちできるようになるかな、と思います。

やったね!