Docker Engine の Swarm モード実行

読む時間の目安: 4 分

Docker Engine を初めてインストールして起動した状態では、Swarm モードはデフォルトで無効になっています。 Swarm モードを有効にすると、docker serviceコマンドを通じて管理される、サービスという考え方に従って操作していきます。

Engine を Swarm モードで実行するには 2 つの方法があります。

ローカルマシン上において Engine を Swarm モードで実行すれば、自分で生成したイメージや他から入手したイメージに基づいて、サービスの生成と確認を行うことができます。 本番環境においては Swarm モードにより、クラスター管理機能を有するフォールトトレラントなプラットフォームを提供し、そこにサービスを実行して利用することができます。

ここに示す手順においては Docker Engine 1.12 またはそれ以降がマシンにインストール済であって、Swarm のマネージャーノードとすることができるものとします。

準備ができていない場合は Swarm モードの重要な考え方 を一読して、Swarm モードをはじめる を試してみてください。

Swarm の生成

Swarm を生成するコマンドを実行すると、Docker Engine が Swarm モードとして起動します。

docker swarm init コマンドを実行すると、現在のノード上に、単一ノードからなる Swarm が生成されます。 Engine は以下のようにして Swarm を作り出します。

  • 現在のノードを Swarm モードに切り替えます。
  • defaultという名前の Swarm を生成します。
  • 現在のノードを、Swarm におけるマネージャーノードのリーダーとします。
  • ノードの名前をマシンホスト名にします。
  • マネージャーがアクティブなネットワークインターフェースのポート 2377 を待ち受けるように設定します。
  • 現在のノードの利用状態(availability)をActiveに設定します。これはスケジューラーからのタスク受け入れを可能にすることを意味します。
  • 内部分散データストアの利用を開始します。これは Swarm 内に Engine を参加させ、Swarm の一貫した参照を実現するとともに、すべてのサービスをここで実行します。
  • デフォルトで、自己署名のルート CA を Swarm 用に生成します。
  • Swarm への参加のために、デフォルトでワーカーノードとマネージャーノードのトークンを生成します。
  • ingressという名前の overlay ネットワークを生成し、Swarm 外部に向けてサービスポートを公開します。
  • overlay のデフォルト IP アドレスとサブネットマスクを生成します。

docker swarm initコマンドの出力結果には、Swarm にワーカーノードを参加させるための接続コマンドが表示されます。

$ docker swarm init
Swarm initialized: current node (dxn1zf6l61qsb1josjja83ngz) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join \
    --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \
    192.168.99.100:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
$ docker swarm init
Swarm が初期化されました: カレントノード (dxn1zf6l61qsb1josjja83ngz) がマネージャーになりました。

この Swarm にワーカーを追加するには、以下のコマンドを実行してください。

    docker swarm join \
    --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \
    192.168.99.100:2377

この Swarm にマネージャーを追加するには 'docker swarm join-token manager' を実行し、
以下の手順に従ってください。

デフォルトのアドレスプールの設定

Docker Swarm はグローバルスコープの(overlay)ネットワークにおいて、デフォルトのアドレスプール10.0.0.0/8を利用します。 ネットワークにサブネットが指定されていない場合、サブネットがこのプールから順次割り当てられます。 場合によっては、ネットワークに対してのデフォルトアドレスプールを別の値にしたくなることもあります。

たとえば、このデフォルトの10.0.0.0/8によるアドレス範囲が、すでにネットワーク内に割り当てたアドレス空間と衝突するとします。 そんなときに Swarm のユーザーがわざわざ--subnetコマンドを指定しなくても、ネットワークが異なるアドレス範囲を選んでくれるのがありがたいところです。

そこで独自にデフォルトのアドレスプールを設定するためには、Swarm の初期化にあたってコマンドラインオプション--default-addr-poolを使って、アドレスプールを定義することが必要です。 このオプションは CIDR 記法によりサブネットマスクを定義します。 Swarm に対する独自のアドレスプールを生成するには、最低でも 1 つのデフォルトアドレスプールの定義が必要であり、任意の定義としてデフォルトアドレスプールのサブネットマスクを指定します。 これはたとえば10.0.0.0/27においては27という値を設定するということです。

Docker は--default-addr-poolオプションによってアドレス範囲が指定されると、そこからサブネットアドレスを割り当てます。 たとえばコマンドラインから--default-addr-pool 10.10.0.0/16を指定すると、/16で示されるアドレス範囲からサブネットを割り当てていきます。 --default-addr-pool-mask-lenが指定されていないか、あるいは明示的に 24 に設定されている場合、10.10.X.0/24の形式で表わされる 256 個の/24ネットワークが作られることになります。

サブネットの範囲は--default-addr-poolにより定まります(たとえば10.10.0.0/16)。 ここで 16 というサイズは、default-addr-poolの範囲内に生成できるネットワーク数を表わします。 この--default-addr-poolオプションは、オーバーレイサブネットの利用の際には、それぞれのアドレスを設定するオプションごとに複数回指定することもあります。

コマンドの書式は以下のようになります。

$ docker swarm init --default-addr-pool <IP range in CIDR> [--default-addr-pool <IP range in CIDR> --default-addr-pool-mask-length <CIDR value>]

デフォルトアドレスプールとして、10.20.0.0 のネットワークに対し /16(クラス B)を生成するには、以下のように指定します。

$ docker swarm init --default-addr-pool 10.20.0.0/16

デフォルトアドレスプールとして10.20.0.010.30.0.0のネットワークに対し /16(クラス B)、また各ネットワークのサブネットマスクとして/26を生成するには、以下のように指定します。

$ docker swarm init --default-addr-pool 10.20.0.0/16 --default-addr-pool 10.30.0.0/16 --default-addr-pool-mask-length 26

この例からdocker network create -d overlay net1を実行すると、net1に対して割り当てられるサブネットが10.20.0.0/26になり、docker network create -d overlay net2を実行すると、net2に対して10.20.0.64/26が割り当てられます。 サブネットを使い切るまでこれが続きます。

詳しくは以下のページを参照してください。

advertise アドレスの設定

マネージャーノードは advertise アドレスを利用します。 Swarm 内の他のノードは、これを使って Swarmkit API や overlay ネットワーク機能へのアクセスができるようになります。 Swarm 上の他のノードは、マネージャーノードへはこの advertise アドレスを使ってアクセスできなければなりません。

advertise アドレスを指定しなかった場合、Docker はシステムが単一の IP アドレスを利用しているかどうかを確認します。 単一であれば、Docker はその IP アドレスを利用し、待ち受けるポートをデフォルトで2377とします。 システムに複数の IP アドレスがある場合は、適切に--advertise-addrを設定して、マネージャー間通信やオーバーレイネットワーク機能を有効にすることが必要です。

$ docker swarm init --advertise-addr <MANAGER-IP>

ノードが最初に到達したマネージャーノードのアドレスと、そのマネージャーが自分のアドレスとして把握しているアドレスが同一とならない場合は、--advertise-addrの指定が必要になります。 たとえばクラウドとして、さまざまな地域にわたる設定があったとします。 つまりホストの設定として、特定リージョン内でのアクセスに用いる内部アドレスと、そのリージョン外からアクセスするために用いる外部アドレスを持つものとします。 このような場合は外部アドレスを--advertise-addrを使って指定することで、ノードから次のノードに向けてその情報を伝えられるようになります。

advertise アドレスに関する詳細は CLI リファレンスdocker swarm initを参照してください。

join コマンドの表示と参加トークンの更新

ノードを Swarm に参加させる際にはシークレットトークンが必要になります。 このトークンは、ワーカーノード用とマネージャーノード用では異なります。 ノードは Swarm に参加する際に、参加トークン(join-token)を使うだけです。 参加トークンはローテートされますが、これが発生しても、参加済みのノードにとって参加状態には何ら影響しません。 トークンのローテートがあるので、古いトークンを使って別のノードが参加しようとしてもそれはできなくなります。

ワーカーノード用に、参加トークンの表示も込みで join コマンドを表示するには、以下を実行します。

$ docker swarm join-token worker

To add a worker to this swarm, run the following command:

    docker swarm join \
    --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \
    192.168.99.100:2377

This node joined a swarm as a worker.
$ docker swarm join-token worker

Swarm にワーカーを追加するには、以下のコマンドを実行してください。

    docker swarm join \
    --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \
    192.168.99.100:2377

このノードは Swarm に対してワーカーとして参加します。

マネージャーノード用の join コマンドとトークンを表示するには、以下を実行します。

$ docker swarm join-token manager

To add a worker to this swarm, run the following command:

    docker swarm join \
    --token SWMTKN-1-59egwe8qangbzbqb3ryawxzk3jn97ifahlsrw01yar60pmkr90-bdjfnkcflhooyafetgjod97sz \
    192.168.99.100:2377
$ docker swarm join-token manager

Swarm にマネージャーを追加するには、以下のコマンドを実行してください。

    docker swarm join \
    --token SWMTKN-1-59egwe8qangbzbqb3ryawxzk3jn97ifahlsrw01yar60pmkr90-bdjfnkcflhooyafetgjod97sz \
    192.168.99.100:2377

--quietフラグを指定するとトークンのみが表示されます。

$ docker swarm join-token --quiet worker

SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c

参加トークンの取り扱いには注意してください。 これは Swarm への参加時に必要となる機密情報です。 したがって特に、この機密情報をバージョン管理システムに含めることは、誤ったやり方になります。 それを行ってしまうと、アプリケーションコードにアクセスできる者なら誰でも、Swarm へのノード追加を自由にできてしまいます。 マネージャー用のトークンはさらに重要です。 これがあれば新たなマネージャーノードを追加して、Swarm 全体の制御を奪われてしまうということです。

参加トークンは、以下のような状況になったらローテートすることをお勧めします。

  • トークンを誤ってバージョン管理システム、グループチャット、ログに出力してしまった場合。
  • ノードが被害を受けたと疑われる場合。
  • 新たなノードが参加できない状況を確実に作り出したい場合。

さらに Swarm の参加トークンを含めた機密情報は、定期的にローテートするようにスケジュールすることが大切です。 トークンのローテートは、少なくとも 6 ヶ月に 1 回行うことをお勧めします。

swarm join-token --rotateを実行すれば、それまでのトークンを無効化して、新たなトークンを生成します。 実行にあたってはworkermanagerのいずれのノード用のトークンをローテートするかを指定します。

$ docker swarm join-token  --rotate worker

To add a worker to this swarm, run the following command:

    docker swarm join \
    --token SWMTKN-1-2kscvs0zuymrsc9t0ocyy1rdns9dhaodvpl639j2bqx55uptag-ebmn5u927reawo27s3azntd44 \
    192.168.99.100:2377
$ docker swarm join-token  --rotate worker

Swarm にワーカーを追加するには、以下のコマンドを実行してください。

    docker swarm join \
    --token SWMTKN-1-2kscvs0zuymrsc9t0ocyy1rdns9dhaodvpl639j2bqx55uptag-ebmn5u927reawo27s3azntd44 \
    192.168.99.100:2377

さらに詳しく

guide, swarm mode, node