< lcn home

Docker Swarmとは?

Table of contents
This is the block containing the component that will be injected inside the Rich Text. You can hide this block if you want.

Docker Swarmは、複数のノード(物理マシンまたは仮想マシン)をひとつの統合システムとして管理するためのコンテナオーケストレーションツールであり、Dockerにネイティブに組み込まれたアプリケーションモードの一部として提供されています。

Swarmを構成する各ノードは互いに接続されており、物理的なマシンでも仮想マシンでも構いません。その役割に応じて、ノードは次の2種類に分類されます。

  • マネージャーノード(Manager nodes): Swarm全体を制御する「Swarmマネージャー」プロセスを実行します。 これは、Swarmモードで発行されたコマンドを処理し、クラスタの理想的な状態(desired state)実際の状態(actual state)を同期させる役割を担います。
  • ワーカーノード(Worker nodes): システムの実際のワークロード(コンテナ)を実行するノードです。
Docker Swarm mode architecture


これらは、Raftコンセンサスや分散ステートなどの技術を含む**分散システムをオーケストレーションするためのツール群「Swarmkit」**によって実現されます。SwarmkitはDockerに統合されています。

Docker Swarmを使う理由


DockerをSwarmモードを使わずに実行する場合と比べて、Docker Swarm は本番環境でのワークロード実行においていくつかの利点を提供します。

利点

高可用性:Docker Swarmは、複数のノードとワーカーノードからなる「Swarm構成」により、高可用な環境を実現します。 SwarmkitのRaftコンセンサスアルゴリズムを使用して、ノード間の信頼性の高い通信とフォールトトレランス(障害耐性)を確立します。 高可用な環境を構築するには、少なくとも 3つのマネージャーノード が必要で、1ノードの障害に耐えられる構成になります。 推奨構成は 7つのマネージャーノード で、最大3ノードの同時障害に対応可能です。

負荷分散:複数のワーカーノードが存在するため、Swarm内でアプリケーションの複数インスタンスをデプロイできます。 マネージャーノードによる内部ロードバランシング機構によって、リクエストがワーカーノード間に均等に分配されます。 また、Swarmマネージャーはヘルスチェックやレディネスチェックを通じて、サービスが正常に稼働していることを監視します。

シンプルさ: Dockerのエコシステムは、運用の俊敏性、移植性、コスト効率を高めます。 特にDocker SwarmモードはDocker本体に統合されているため、追加のツールを導入する必要がありません。 Docker CLI(コマンドラインインターフェース)には、Swarmモード・非Swarmモードの両方でアプリやコンテナを簡単に管理するためのコマンドとオプションが含まれています。 また、学習コストが高いKubernetes(K8s)と比較して、Docker Swarmモードは導入・運用がより簡単 です。

一般的なユースケース

Docker Swarmモードは、小規模から中規模のデプロイ構成 に適しています。たとえば、1つのデータベース、Webアプリ、キャッシュサービス、いくつかのバックエンドサービスで構成される小規模なアプリケーションスタックなどが該当します。

一方で、より大規模なデプロイでは、保守性、カスタマイズ性、災害復旧(DR)対応 といった要件において制約が生じる可能性があります。また、自動化や複雑な障害耐性よりも、サービスの高可用性や自動負荷分散を優先したい場合 にもDocker Swarmは適しています。

総じて、組織がコンテナ環境への移行を検討している場合、管理と運用がシンプルなDocker Swarmは導入しやすい選択肢 となります。


なぜ他のコンテナオーケストレーターではなく Docker Swarm を使うのか?

前述のとおり、Docker Swarm を使用する主な利点の一つは、より高度なコンテナオーケストレーションツールである Kubernetes(K8s)と比べて学習コストが低いことです。Docker をインストールするだけで、必要なツールやサービスが利用可能になります。複数ノードを立ち上げたい場合は、VirtualBox や Vagrant を使って簡単に環境を構築でき、いくつかのコマンドを実行するだけでクラスターを作成できます。さらに、Docker に備わっている既存のオプションを利用する以外に特別な設定変更を行う必要もありません。

また、運用環境でも、比較的管理が容易な構成(例えば 3〜10 ノードで 100 コンテナ未満の稼働)であれば、Docker Swarm を使用することが可能です。しかし、より大規模なワークロードになると、Docker Swarm はすぐに K8s に劣るようになります。K8s にはその規模に対応した優れたツール、サポート、そしてドキュメントが揃っているためです。

基本概念

Docker Swarm モードで作業する際に理解しておくべき主要な概念には、次のようなものがあります。

Swarm(スウォーム)

Swarm は、信頼性の高い運用を実現するために互いに連携するノード群で構成されます。ノードを Swarm(群)として構成することで、ノードが合意形成(コンセンサス)を行い、単一障害点(Single Point of Failure)のリスクを軽減できます。任意の時点で、マネージャーノードの中から 1 つのリーダーノードが選出され、Swarm 全体に関する重要な意思決定を行います。もしリーダーノードが利用不能になった場合は、残りのノードが合意のもとで新しいリーダーを選出し、障害が発生したノードの役割を引き継ぎます。

Node(ノード)

ノードとは、Swarm モードで動作する Docker Engine のインスタンスを 1 つ実行している物理または仮想マシンのことです。設定に応じて、このインスタンスは ワーカーノード(worker node) または マネージャーノード(manager node) として動作します。

  • ワーカーノード は、デプロイメントやサービスなどのワークロードを受け入れて実行する役割を担います。
  • マネージャーノード は Swarm の制御プレーン(control plane)として機能し、サービスのオーケストレーション、コンセンサスへの参加、ワークロードのスケジューリングなどを担当します。

高可用性と信頼性を確保するためには、これら両方のタイプのノードを十分な数だけ配置することが重要です。

サービスとタスク

Swarm 内で実行されるワークロードや処理は、2 種類に分けられます。

サービス(Service) は、特定の条件に基づいてデプロイされるコンテナの定義です。Swarm モードでは、各ノードに 1 つずつインスタンスを実行する グローバルサービス(global service)(例:監視やログ収集コンテナ)や、複数インスタンスを展開してスパイク的な負荷に対応する レプリケートサービス(replicated service) をデプロイできます。Swarm にデプロイされたサービスは、docker service scale コマンドを使ってスケールアップ/スケールダウンが可能であり、同じクラスター内の任意のノードから内部 DNS 解決を通じてアクセスできます。

タスク(Task) は、特定のノードに割り当てられる単一のワークロード定義です。タスクを Docker Swarm に送信すると、そのタスクは 1 つのノード上で実行されます。同じ ID を持つタスクを他のノードで実行することはできません。タスクを作成するには、まず希望するデプロイメント内容を定義した サービス を作成すれば、対応するタスクが自動的に生成され、実際の処理を実行します。

タスクにはライフサイクル上の状態が割り当てられており、たとえば以下のような状態を取ります:

  • NEW:新しく作成された状態
  • PENDING:割り当て待ちの状態
  • COMPLETE:正常に完了した状態

Load Balancing(ロードバランシング)

ロードバランシングとは、サービスへのリクエストの流れを均等に分散させる仕組みのことです。

たとえば、スーパーボウルの時期のようにアクセスが急増し、多くの人が同じウェブサイトを訪れる状況では、アクセスを複数のウェブサイトインスタンスに分散する必要があります。こうすることで、すべての訪問者が同等のサービス品質を体験できるようにします。Docker Swarm では、自動ロードバランシング機能 が標準で組み込まれており、追加の設定なしで利用できます。また、HAProxy や NGINX などの外部ロードバランサーに対して、サービスのポートを簡単に公開できる仕組みも備えています。

ユースケース例

Swarm を使った実験を行うには、少なくとも 1 つのマネージャーノード2 つのワーカーノード が必要です。ここでは、そのために用意された簡単な Vagrantfile を利用します。このファイルは 4 台の仮想マシン(VM)を起動し、初期化スクリプトの中で Docker を自動的にインストールするようになっています。

まず、仮想マシンを起動します。

$ vagrant up


すべてのマシンの準備が整ったら、マネージャーノードに参加します。

$ vagrant status
Current machine states:

manager                   running (virtualbox)
worker01                  running (virtualbox)
worker02                  running (virtualbox)
worker03                  running (virtualbox)

$ vagrant ssh manager
vagrant@manager:~$ docker info

Swarmの作成

マネージャーノードで次のコマンドを実行し、Docker Swarm を初期化します。

vagrant@manager:~$ docker swarm init --listen-addr 10.10.10.2:2377 --advertise-addr 10.10.10.2:2377
Swarm initialized: current node (r9xym5ymmzmm7e7ux3f4sxcs9) is now a manager.

ここでは、マネージャーノードのプライベート IP アドレス(10.10.10.2)を使用しています。これは、ワーカーノードの IP アドレス一覧(10.10.10.21、10.10.10.22、10.10.10.23)と同じネットワーク内にあります。

この Swarm にワーカーノードを追加するには、次のコマンドを実行します。

$ docker swarm join --token SWMTKN-1-4w74yys9pihkl9qhmdrk0zlqtca9xrihan36cktdt2du251qxm-bw60iu884vettl2ay65m0y1uy 10.10.10.2:2377
This node joined a swarm
as a worker.Code language: JavaScript (javascript)

最初のマネージャーノードを作成した際に、ジョイントークンが表示されました。各ワーカーノード(worker01、worker02、worker03)で同じコマンドを使用するようにしてください。

最後に、マネージャーノードからノードの一覧を確認します。

vagrant@manager:~$ docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
r9xym5ymmzmm7e7ux3f4sxcs9 *   manager    Ready     Active         Leader           20.10.12
r1l8jn1ot24hfzs0f7e9te5u3     worker01   Ready     Active                          20.10.12
wi7uq4jpcoh8rd7hlej6xuc4b     worker02   Ready     Active                          20.10.12
p7paeu2d72rqu4dr1dllvcdys     worker03   Ready     Active                          20.10.12

ここまでは順調です。

Swarmにサービスをデプロイ

Swarm にサービスをデプロイするには、docker service コマンドを使用してコンテナアプリケーションをプッシュします。replicaの数や、Swarm 外部に公開するサービスのポートなどのパラメータを指定することもできます。

Swarm と同じネットワーク内から、以下のコマンドを実行して NGINX コンテナをすべてのノードに分散配置します。

vagrant@manager:~$ docker service create --name my_nginx --replicas 8 --publish published=8080,target=80 nginx

各ノード内で実行中のコンテナを確認し、localhost:8080 にアクセスできることを確認します。

vagrant@worker02:~$ docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED              STATUS              PORTS     NAMES
de396992a942   nginx:latest   "/docker-entrypoint.…"   About a minute ago   Up About a minute   80/tcp    my_nginx.2.enp8yy55f0j1u1y8tm44lpxjq
935eea500ce6   nginx:latest   "/docker-entrypoint.…"   About a minute ago   Up About a minute   80/tcp    my_nginx.6.f8zl2oh530rvfe15cr6fcmae0
Code language: JavaScript (javascript)

Docker Swarm モードで稼働中の NGINX スタートアップページ

また、デプロイしたいサービスを記述した yml 仕様ファイルを使用して、docker stack コマンドを実行することもできます。たとえば、先ほどのコマンドは次の仕様と同等です。

# Dockerfile
version: '3.7'
services:
 my_nginx:
   image: nginx:latest
   deploy:
     replicas: 8
   ports:
     - "8080:8080"
Code language: PHP (php)vagrant@manager:~$ docker stack deploy -c stack.yml my_nginx
vagrant@manager:~$ docker stack services my_nginx
ID             NAME                MODE         REPLICAS   IMAGE          PORTS
l8op85m1kaoy   my_nginx_my_nginx   replicated   8/8        nginx:latest   *:8080->8080/tcp

他の役立つコマンド

Swarm モードでは、いくつかの便利なコマンドを使用できます。ここではその一部を簡単に見てみましょう。

ノードの状態を確認する:ノード情報を確認するには、docker node inspect コマンドを使用します。

vagrant@manager:~$ docker node inspect worker02
[
   {
       "ID": "wi7uq4jpcoh8rd7hlej6xuc4b",
       "Version": {
           "Index": 35
       },
       "CreatedAt": "2023-02-15T12:28:39.485382607Z",
       "UpdatedAt": "2023-02-16T10:16:47.28165702Z",
Code language: JavaScript (javascript)

マネージャーノードをワーカーノードに降格させる: docker node demote <manager_node_id> コマンドを使用すると、マネージャーをワーカーに降格させることができます。

ワーカーノードをマネージャーノードに昇格させる: 逆に、docker node promote コマンドを使用すると、ワーカーノードをマネージャーノードに昇格させることができます。

vagrant@manager:~$ docker node promote worker01
Node worker01 promoted to a manager in the swarm.

vagrant@manager:~$ docker node ls
ID                            HOSTNAME   STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
r9xym5ymmzmm7e7ux3f4sxcs9 *   manager    Ready     Active         Leader           20.10.12
r1l8jn1ot24hfzs0f7e9te5u3     worker01   Ready     Active         Reachable        20.10.12
wi7uq4jpcoh8rd7hlej6xuc4b     worker02   Ready     Active                          20.10.12
p7paeu2d72rqu4dr1dllvcdys     worker03   Ready     Active                          20.10.12

Draining a node(ノードのドレイン: ノードをドレインするとは、Swarm エンジンがそのノードで稼働中のコンテナを他のワーカーノードへ移動させることを意味します。これは、ノードのアップグレードを予定している場合や、新しいワークロードを受け入れる前にノードの健全性を確認したい場合に便利です。

vagrant@manager:~$ docker node update  --availability drain worker02
vagrant@manager:~$ docker node inspect worker02 --format '{{ .Spec.Availability }}'
Drain
Code language: JavaScript (javascript)

次のコマンドを実行すると、ノードを再びアクティブな状態に戻すことができます。

vagrant@manager:~$ docker node update  --availability active worker02
worker02

まとめ

以上で、Docker Swarm モードとその運用機能の概要説明は終了です。

Docker Swarm は、そのシンプルさ自動ロードバランシング機能、そしてスムーズなセットアップによって、K8s に対する魅力的な代替手段となります。Docker Swarm モードは Docker に組み込まれているため、追加の技術を学ばなくてもすぐに試すことができます。総じて、Docker Swarm モードは高可用性を備えたレプリケートサービスのデプロイを、より簡単かつ効率的に行うことを可能にします。

FAQs

No items found.

セキュリティ専門家とともに、
クラウドを防御する正しい方法を試してみよう