プロダクション用の Swarm クラスタ構築

高い可用性を持つ Docker Swarm クラスタのデプロイ方法を紹介します。この例では Amazon Web Services (AWS) をプラットフォームとして使いますが、他のプラットフォーム上でも Docker Swarm クラスタを同じようにデプロイできます。この例では、以下の手順で進めます。

一般的な Swarm の導入方法については Swarm を検証環境で試すには をご覧ください。

動作条件

  • Amazon Web Services (AWS) アカウント
  • 以下の AWS 機能やツールに慣れている:
    • エラスティック・クラウド(EC2)ダッシュボード
    • バーチャル・プライベート・クラウド(VPC)ダッシュボード
    • VPC セキュリティ・グループ
    • EC2 インスタンスに SSH で接続

ステップ1:ネットワーク・セキュリティのルールを追加

AWS は VPC ネットワークに対して許可するネットワーク通信を「セキュリティ・グループ」で指定します。初期状態の default セキュリティ・グループは、インバウンドの通信を全て拒否し、アウトバンドの通信を全て許可し、インスタンス間の通信を許可するルール群です。

ここに SSH 接続とコンテナのイメージを取得(インバウンド)する2つのルールを追加します。このルール設定は Engine 、Swarm 、 Consul のポートを少々は守ります。プロダクション環境においては、セキュリティ度合いによって更に制限するでしょう。Docker Engine のポートを無防備にしないでください。

AWS のホーム・コンソール画面から、以下の作業を進めます:

  1. VPC - 独立したクラウドリソース をクリックします。

VPC ダッシュボードが開きます。

  1. セキュリティグループ をクリックします。
  1. default セキュリティ・グループを選び、 default VPC にセキュリティ・グループを関連付けます。
  1. 以下の2つのルールを追加します。
タイプ プロトコル ポート範囲 送信元
SSH TCP 22 0.0.0.0/0
HTTP TCP 80 0.0.0.0/0

SSH 接続はホストに接続するためです。HTTP はコンテナ・イメージをホストにダウンロードするためです。

ステップ2:インスタンス作成

このステップではデフォルトのセキュリティ・グループで5つの Linux ホストを作成します。作業は3種類のノードをデプロイする例です

ノードの説明 名前
Swarm のプライマリとセカンダリ・マネージャ manager0 , manager1
Swarm ノード node0 , node1
ディスカバリ・バックエンド consul0

インスタンスの作成は、以下の手順で進めます。

  1. EC2 ダッシュボードを開き、各 EC2 インスタンスを同時に起動します。
  • ステップ1 では : Amazon マシン・イメージ (AMI)を選択 します。 Amazon Linux AMI を探します。
  • ステップ5 では: インスタンスにタグ を付けます。各インスタンスの Value に名前を付けます。
    • manager0
    • manager1
    • consul0
    • node0
    • node1
  • ステップ6 では: セキュリティ・グループを設定 します。 既存のセキュリティグループ から「default」を探します。
  1. インスタンスの起動を確認します。

ステップ3:各ノードに Engine をインストール

このステップでは、各ノードに Docker Engine をインストールします。Engine をインストールすることで、Swarm マネージャは Engine CLI と API を経由してノードを割り当てます。

SSH で各ノードに接続し、以下の手順を進めます。

  1. yum パッケージを更新します。

「y/n/abort」プロンプトに注意します。

$ sudo yum update
  1. インストール用スクリプトを実行します。
$ curl -sSL https://get.docker.com/ | sh
  1. Docker Engine が Swarm ノードのポート 2375 で通信可能な指定で起動します。
$ sudo docker daemon -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock
  1. Docker Engine が正常にインストールされたことを確認します。
$ sudo docker run hello-world

「Hello World」メッセージが画面に表示され、エラーではない文字列が表示されます。

  1. ec2-user に root 権限を与えます。
$ sudo usermod -aG docker ec2-user
  1. logout を実行します。

トラブルシューティング

  • docker コマンドを実行してもホスト上で docker が動作しているかどうか訊ねる表示が出るのは、ユーザが root 権限を持っていない可能性があります。そうであれば、 sudo を使うか、ユーザに対して root 権限を付与します。
  • この例では、Docker Engine が動作するインスタンスを元にし、他のインスタンス用に使う AMI イメージを作成しません。作成したとしても問題になるでしょう。
  • ホスト上で docker run コマンドを実行しても Docker Hub に接続できない場合は、コンテナ・イメージの取得に失敗するでしょう。そのような場合、VPC に関連付けられているセキュリティ・グループのルールを参照し、インバウンドの通信(例: HTTP/TCP/80/0.0.0.0.0/0)が許可されているか確認します。また、 Docker Hub ステータス・ページ でサービスが利用可能かどうか確認します。

ステップ4:ディスカバリ・バックエンドのセットアップ

ここでは最小のディスカバリ・バックエンドを作成します。Swarm マネージャとノードは、このバックエンドをクラスタ上のメンバを認識するために使います。また、Swarm マネージャはコンテナを実行可能なノードがどれかを識別するためにも使います。

簡単さを保つために、Swarm マネージャが動いているホストのうちどれか1つで consul デーモンを起動します。

  1. 始めるにあたり、以下のコマンドをテキスト・ファイルにコピーしておきます。
$ docker run -d -p 8500:8500 --name=consul progrium/consul -server -bootstrap
  1. SSH で manager0consul0 インスタンスに接続します。
$ ifconfig
  1. 出力結果から inet addreth0 にある IP アドレスをコピーします。
  1. SSH で manager0consul0 インスタンスに接続します。
  1. 手順1で実行したコマンドを、コマンドラインに貼り付けます。
$ docker run -d -p 8500:8500 --name=consul progrium/consul -server -bootstrap

consul ノードを立ち上げて実行することで、クラスタ用のディスカバリ・バックエンドを提供します。このバックエンドの信頼性を高めるには、3つの consul ノードを使った高可用性クラスタを作成する方法があります。詳細情報へリンクを、このページの一番下をご覧ください(consul ノードのクラスタを作成する前に、VPC セキュリティ・グループに対し、必要なポートに対するインバウンド通信を許可する必要があります)。

ステップ5:Swarm クラスタの作成

ディスカバリ・バックエンドを作った後は、Swarm マネージャを作成できます。このステップでは高い可用性を持つ設定のため、2つの Swarm マネージャを作成します。1つめのマネージャを Swarm の プライマリ・マネージャ (primary manager) とします。ドキュメントのいくつかはプライマリを「マスタ」と表現していますが、置き換えてください。2つめのマネージャは レプリカ(replica) を提供します。もしもプライマリ・マネージャが利用できなくなれば、クラスタはレプリカからプライマリ・マネージャを選出します。

  1. 高可用性 Swarm クラスタのプライマリ・マネージャを作成するには、次の構文を使います。
$ docker run -d -p 4000:4000 swarm manage -H :4000 --replication --advertise <manager0_ip>:4000  consul://<consul_ip>

特定のマネージャは「manager0 & consul0」インスタンスの consul ノードでもあるので、 <manager0_ip><consul_ip> を同じ IP アドレスに書き換えます。例:

$ docker run -d -p 4000:4000 swarm manage -H :4000 --replication --advertise 172.30.0.161:4000  consul://172.30.0.161:8500
  1. docker ps を入力します。

出力結果から Swarm クラスタと consul コンテナが動いているのを確認します。それから manager0consul0 インスタンスから切断します。

  1. manager1 インスタンスに接続し、 ifconfig で IP アドレスを取得します。
$ ifconfig
  1. 以下のコマンドを実行し、セカンダリ Swarm マネージャを起動します。

コマンドを実行前に <manager1_ip> の部分は書き換えてください。実行例:

$ docker run -d swarm manage -H :4000 --replication --advertise <manager1_ip>:4000  consul://172.30.0.161:8500
  1. docker ps を実行し、 swarm コンテナの実行を確認します。
  1. node0node1 に接続し、それぞれをクラスタに追加(join)します。
  1. ifconfig コマンドでノードの IP アドレスを確認します。
  1. 各コンテナで、次の構文を使って Swarm コンテナを起動します。
$ docker run -d swarm join --advertise=<node_ip>:2375 consul://<consul_ip>:8500

実行例:

$ docker run -d swarm join –advertise=172.30.0.69:2375 consul://172.30.0.161:8500

あなたの小さな Swarm クラスタが起動し、複数のホスト上で実行中になりました。信頼性や収容能力を高めるには、Swarm マネージャやノードを更に追加し、ディレクトリ・バックエンドの可用性を高めることも可能です。

ステップ6:Swarm と通信

Swarm API を使って Swarm と通信し、マネージャとノードに関する情報を取得できます。Swarm API はスタンダード Docker API とよく似ています。この例では SSL を使って manager0consul0 ホストに再び接続します。そしてコマンドを Swarm マネージャに対して割り当てます。

  1. クラスタ内のマスタとノードの情報を取得します。
$ docker -H :4000 info

出力結果から、マスタの役割がプライマリ( Role: primary )であることと、各ノードの情報が分かります。

  1. Swarm 上でアプリケーションを実行します。
$ docker -H :4000 run hello-world
  1. Swarm ノード上でアプリケーションが動いているのを確認します。

    $ docker -H :4000 ps

ステップ7:Swarm のフェイルオーバをテスト

レプリカ・インスタンスへの継承を確認するために、プライマリ・マネージャをシャットダウンします。これが選出のきっかけとなり、レプリカがプライマリ・マネージャになります。停止したマネージャを再び起動したら、今度はこちらがレプリカになります。

  1. manage0 インスタンスに SSH 接続します。
  1. swarm コンテナのコンテナ ID もしくはコンテナ名を取得します。
$ docker ps
  1. プライマリ・マスタをシャットダウンするため、 <id_name> の部分をコンテナ ID あるいはコンテナ名に置き換えます(例: 「8862717fe6d3」または「trusting_lamarr」)。
$ docker rm -f <id_name>
  1. swarm マスタを起動します。例:
$ docker run -d -p 4000:4000 swarm manage -H :4000 --replication --advertise 172.30.0.161:4000  consul://172.30.0.161:237
  1. Engine デーモンのログを確認します。 <id_name> は新しいコンテナ ID かコンテナ名に置き換えます。
$ sudo docker logs <id_name>

出力から次のような2つのエントリが確認できます。

time="2016-02-02T02:12:32Z" level=info msg="Leader Election: Cluster leadership lost"
time="2016-02-02T02:12:32Z" level=info msg="New leader elected: 172.30.0.160:4000"
  1. クラスタのマスタとノードに関する情報を取得するには、次のように実行します。
$ docker -H :4000 info

master1 ノードに接続し、 infologs コマンドを実行できます。そうすると、新しいリーダーが適切なエントリを返します。