Dockerチュートリアルを日本語で説明(第3章)
第2章はコンテナについてのチュートリアルでしたが、
今回はサービスについてのチュートリアルです。
なにをするかというと、
第2章で作成したコンテナをいくつか複製して、それらで負荷分散ネットワークを構築します。
見かけ上、アプリケーションの実行結果は変わりませんが、負荷分散ネットワークを構築することで、第2章だけのものよりも、高負荷のアクセスに耐えたりすることができるようになります。
先に結論をいうと、これを実現するためにはdocker-compose.yml
を書き特定のコマンドで実行することで簡単に構築することができます。
- Docker勉強し始めたい方
- 公式の方でやってみたけどあまり理解できなくて困っている方
第3章の位置付け
第2章でも紹介した通りDockerでのアプリケーション開発では次の3層構造を意識します。 第3章では中間層の「Service」に着目します。
Service層は何のために位置付けられているかというと、
作ったアプリケーションの負荷を計測したり、負荷分散をおこなうなどアプリケーションの中でコンテナがどのように振る舞うかを決めるためにあります。
Serviceについて
Serviceは1つのコンテナ(image)のみを実行することができます。
そしてimageをどのように実行するかを決めることができます。
例えば、
- どのポートを使用するか
- あるサービスが必要なキャパシティを満たすためには、いくつコンテナを複製すべきか
など考える際有効です。
サービスのスケーリングをしたい場合は実行するコンテナインスタンスの数を変更することで対応できます。
それでは本題に入っていきます。
上で述べたことはdocker-compose.yml
により定義することで実現することができます。
docker-compose.yml
docker-compose.yml
はDockerコンテナがproductionでどのように振る舞うべきかを定義するYAMLファイルです。
まず次のdocker-compose.yml
をどこでもいいので作成してください。
docker-compose.yml↓
version: "3" services: web: # サービス名をwebとする # 第2章で作成したimageのリポジトリに設定 image: <username>/get-started:part2 #pullしたいリポジトリを指定 deploy: replicas: 5 #webと名付けたimageのインスタンスを5つ用意 resources: limits: cpus: "0.1" # 1つのインスタンスにつきCPUは10%まで使用可能 memory: 50M # 1つのインスタンスにつきメモリは50MBまで使用可能 restart_policy: condition: on-failure ports: # ポート指定 webの80ポートをホスト(自分のマシン)の4000ポートに割り当てる - "4000:80" networks: - webnet # webnetと呼ばれる負荷分散ネットワークに指定 networks: webnet:
docker-compose.ymlのimage: <username>/get-started:part2
の<username>
を自分の環境に合わせて書き換えてください(第2章で設定しました)。
このYAMLはソースのコメントにも補足してありますが、次のことをDockerに伝えます。
image:
で指定したリポジトリから第2章でアップロードしたimageをpullする。replicas
で指定される数分(今回は5つ)、imageのインスタンス(imageのコピーみたいなもの)を実行する。それぞれのインスタンスにつき、自分のPCのCPUの10%まで、メモリの50MBまで使用可能(limits:
で指定)。- コンテナ終了時にステータスが
on-failure
だった場合、コンテナを再起動(restart_policy
で設定)。 web
(imageのサービス名)の80ポートをホスト(自分のマシン)の4000ポートに割り当てるwebnet
と呼ばる負荷分散ネットワークを通じてweb
のコンテナをポート80に共有する。webnet
をdefaultで定義する(webnet:の欄を空欄に)。defaultだと負荷分散オーバーレイネットワークとなります。
実際にこの負荷分散アプリケーションを動かしてみる
一連の流れは、
docker swarm init
(swarm
については第4章で詳しく勉強します)docker stack deploy -c docker-compose.yml getstartedlab
で実行。そのとき、この負荷分散アプリケーションにgetstartedlab
と名前付けする。
この2つで負荷分散アプリケーションを実行することができます。
実際にやっていきます。
$ docker swarm init 実行結果↓ Swarm initialized: current node (bb7teuxa2thm4viwok5656dbz) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-0mub34dni79swd1yizk96yr0wxz3k1ba3dwd6254vbbokxo137-4pxnqgbp9189gujxcd8wpqr97 192.168.65.3:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
$ docker stack deploy -c docker-compose.yml getstartedlab 実行結果↓ Creating network getstartedlab_webnet Creating service getstartedlab_web
これで負荷分散アプリケーションを実行することができました。 実行したService(負荷分散アプリケーション)のIDや名前等は次のコマンドでみることができます。
$ docker service ls 実行結果↓ ID NAME MODE REPLICAS IMAGE PORTS y56sievmxu2a getstartedlab_web replicated 5/5 <username>/get-started:part2 *:4000->80/tcp
サービスgetstartedlab_webで実行している1つのコンテナを「タスク(task)」と呼びます。タスクはユニークなIDを与えられており、タスクはgetstartedlab_web.数字
で名前づけられます。タスクは次のコマンドで確認できます。
$ docker service ps getstartedlab_web 実行結果↓ ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS nl2g7hvtdi8i getstartedlab_web.1 <username>/get-started:part2 linuxkit-025000000001 Running Running 7 minutes ago m49n4b57eeak getstartedlab_web.2 <username>/get-started:part2 linuxkit-025000000001 Running Running 7 minutes ago 9uzg797m8g9y getstartedlab_web.3 <username>/get-started:part2 linuxkit-025000000001 Running Running 7 minutes ago hzts1lw84gmr getstartedlab_web.4 <username>/get-started:part2 linuxkit-025000000001 Running Running 7 minutes ago uqz4dwzereid getstartedlab_web.5 <username>/get-started:part2 linuxkit-025000000001 Running Running 7 minutes ago
アプリケーションで実行されているコンテナをリストアップするために次のコマンドを入力します。
$ docker container ls -q 実行結果↓ 9aaca126702d dc6c04cd7d0f 3916b7b57456 86eb305ca950 4577652260b6
任意のブラウザでhttp://localhost:4000/にアクセスしてください。
第2章と同じアプリケーションを動かしているため、同様な見た目が得られると思います。
次にブラウザを更新してみてください。
するとHostnameの欄の値が変わると思います。
Hostnameの値の変わり方は5通りです。
この結果からわかるように、同じ結果を出力しているように見えて、それを出力しているhostが異なるのは負荷分散の恩恵です。
replicas
で設定した数通りのhostによって負荷分散をできています。
また負荷分散アプリケーションのスケールを変更したい場合は、docker-compose.yml
のreplicas
の値を任意の値に書き換えて、
再び、docker stack deploy -c docker-compose.yml getstartedlab
を実行すれば可能です。
試しにreplicas
の値を5から8に変更しスケールアウトしてみましょう。
$ docker stack deploy -c docker-compose.yml getstartedlab 実行結果↓ Updating service getstartedlab_web (id: y56sievmxu2a1utk7h0zn8pn1)
実行結果の通り、Serviceの設定がアップデートされましたね。
また、
$ docker container ls -q 実行結果↓ 2f7d8d74eef5 f60847282801 6c9af7c20321 96a2cce21a3b bf2968c19aa4 3d19166e560d b8c2baf1cf51 513adc5f9d54
上記コマンドの実行結果より、8つのインスタンスが動いていることがわかります。
このようにアプリケーションのスケールアウトも簡単にできます。
アプリケーションを停止させる
アプリケーションを停止させるためにはdocker stack rm <アプリケーション名>
を実行します。
今回はアプリケーション名をgetstartedlab
にしていたので、
$ docker stack rm getstartedlab 実行結果↓ Removing service getstartedlab_web Removing network getstartedlab_webne
のように停止します。
普段からLinuxやMax、Unixを使用しているのであれば、rm
というコマンドを使用するのでわかりやすいのではないでしょうか。
またSwarm
というものも動作しているので
$ docker swarm leave --force 実行結果↓ Node left the swarm.
でswarmに対するコマンドも実行します。
まとめ
内容をもう一度まとめておきます。
今回はService層の役割を学ぶために、
負荷分散アプリケーションを作成しました。
第2章で作成したfriendlyhelloイメージのコンテナに
複製やネットワーク構成等の振る舞いの仕方をdocker-compose.yml
で命令することで負荷分散アプリケーションを実現しました。
- 第3章の位置付け
- docker-compose.ymlについて
- 負荷分散アプリケーションの実行
- 負荷分散アプリケーションのスケールアウト
- 負荷分散アプリケーションの停止
Dockerの勉強頑張りましょう!!
コンテナについては第2章はこちらから。
第4章は出来次第更新