Docker をプロダクションで使っていくにあたり、コンテナの管理やアップデートをどうしようかと考えていました。
最初はこれを機に Kubernetes を使ってみようかと思ったのですが、学習コストが高いうえに、対象が小さなシステムなのでちょっと大仰すぎるなぁと思ってたところ、Docker 自体に Swarm モードというオーケストレーション機能が含まれていることを知ったので、そちらを試しに使ってみることにしました。
というわけで、以下のチュートリアルを少しやってみました。
手順としては上記をなぞるだけになるかもしれませんが、自分にとってわかりにくかったところや、他のサイトで調べたりしたことなどを補足しながら書いていこうと思います。
一応、Swarm のドキュメントは以下になります。
ちなみに Kubernetes と Docker Swarm の比較は以下のページがとても参考になりました。
環境
- Ubuntu 20.04
- Docker 20.10.7
- Ubuntu 20.04 on WSL2 on Windows10
- Docker 20.10.10
Docker はインストール済みの前提です。
Docker がインストールされていれば Swarm モードも使えます。
チュートリアルでは Docker ホストは3つありますが、用意できなかったので Ubuntu と WSL2 上の Ubuntu の2つでやりました。
概要
Docker Swarm モードは manager
ノードと worker
ノードから構成されます。
ノードというのは Docker のホスト(Docker エンジンが動作している環境)の単位になります。
- manager ノードはクラスタを管理するノード
- worker ノードはコンテナを稼働させるノード
- manager ノードは worker ノードを兼ねることもできる
Swarm モードの有効化
Swarm モードを有効化するには docker swarm init
を実行します。
このコマンドを実行すると manager ノードが作成されるので、manager ノードを作成したいマシン上で実行します。
$ docker swarm init
Swarm initialized: current node (z9voajpw84i4jk2fomqwsmnc7) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-23t6ldii7xxyyol2ulu0qddlqgwp3i1xpckiij2yjpintebbjq-bw598idhl229sykrhyiykviiw 192.168.1.10:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
出力結果には worker ノードを manager ノードに登録するためのコマンドが表示されます(後述)。
また、1つのマシンに複数のIPアドレスが割り当てられている場合、以下のように --advertise-addr
オプションで他のノードとの通信に使用するIPアドレスを指定することもできます。
$ docker swarm init --advertise-addr 192.168.1.10
確認
Swarm モードが有効になっているかどうかは docker info
で確認できます。
$ docker info
抜粋ですが、以下のような出力が確認できます。
Swarm: active
NodeID: z9voajpw84i4jk2fomqwsmnc7
Is Manager: true
ClusterID: 61lmt9ptc8jyphn725cj96vxj
Managers: 1
Nodes: 1
ノードに関する情報は docker node ls
で確認できます。
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
z9voajpw84i4jk2fomqwsmnc7 * manager1 Ready Active Leader 20.10.7
worker ノードの作成
worker ノードの作成には docker swarm init
を実行したときの出力結果に表示されたコマンドを使います。
manager ノードを作成したマシンとは別のマシンで以下のコマンドを実行します。
$ docker swarm join --token SWMTKN-1-23t6ldii7xxyyol2ulu0qddlqgwp3i1xpckiij2yjpintebbjq-bw598idhl229sykrhyiykviiw 192.168.1.10:2377
This node joined a swarm as a worker.
もし上記のコマンドが分からない場合は、docker swarm join-token worker
で確認できます。
$ docker swarm join-token worker
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-23t6ldii7xxyyol2ulu0qddlqgwp3i1xpckiij2yjpintebbjq-bw598idhl229sykrhyiykviiw 192.168.1.10:2377
尚、既に worker ノードを作成済みであったり、manager ノードを作成しているマシンで docker swarm join
を実行した場合、以下のエラーが表示されます。
Error response from daemon: This node is already part of a swarm. Use "docker swarm leave" to leave this swarm and join another one.
確認
先ほどと同じように docker node ls
で確認できます。
尚、このような Swarm を管理するコマンドは manager ノードが動作しているマシンでのみ実行可能です。
$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
hqi4gtcdh4a7ya8myg0x0my37 worker1 Ready Active 20.10.12
z9voajpw84i4jk2fomqwsmnc7 * manager1 Ready Active Leader 20.10.7
サービスのデプロイ
ノードを作成したので、そこにサービスを追加していきます。
まずは manager ノードにサービスを追加します。
上述したように、manager ノードは worker ノードも兼ねることができるので、サービスを動かすこともできます。
manager ノードが動作しているマシンで docker service create
を実行します。
$ docker service create --replicas 1 --name helloworld alpine ping docker.com
84aq1iszx44xq2f3cmohfl2tu
verall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
ここでは、alpine
のベースイメージで helloworld
という名前のコンテナを作成し、コンテナ内で ping docker.com
というコマンドを実行しています。--replicas 1
はコンテナの数です。
確認
docker service ls
で実行中のサービスを確認できます。
$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
84aq1iszx44x helloworld replicated 1/1 alpine:latest
サービスの詳細を調べる
別記事に書きました。
サービスのスケール
Swarm で実行しているサービスをスケールするには、docker service scale <サービスID>=<タスク数>
を実行します。
尚、サービス内で実行中のコンテナを「タスク」(task)と呼ぶそうです。
$ docker service scale helloworld=5
helloworld scaled to 5
overall progress: 5 out of 5 tasks
1/5: running [==================================================>]
2/5: running [==================================================>]
3/5: running [==================================================>]
4/5: running [==================================================>]
5/5: running [==================================================>]
verify: Service converged
確認
docker service ps <サービスID>
で確認すると、インスタンスが合計5つになったのが分かります。
タスク(コンテナ)は Swarm のノード間で分散されています。
また、各ノードで docker ps
を実行することでコンテナの情報が確認できます。
サービスの削除
$ docker service rm helloworld
helloworld
確認
docker service ls
で helloworld サービスが削除されたのを確認できます。
$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
docker service inspect
で調べようとしてもそんなサービスはないと言われます。
$ docker service inspect helloworld
[]
Status: Error: no such service: helloworld, Code: 1
docker ps
でタスク(コンテナ)も削除されたことを確認できます。
ノードの削除
とりあえずここまでやってみました。
チュートリアルでは次はローリングアップデートとなっていますが、そこはまた今度にします。
尚、上記サービスは削除しましたが、ノードは残ったままです。
ノードの削除方法(Swarm モードの停止方法)を別記事に書きました。