プログラムを中心とした個人的なメモ用のブログです。 タイトルは迷走中。
内容の保証はできませんのであしからずご了承ください。

2022/04/22

[Docker] Swarm モードに入門してみた

event_note2022/04/22 0:59

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 モードの停止方法)を別記事に書きました。