アプリケーションのデプロイ

Swarm クラスタを構築 しましたので、投票アプリケーションを構築・デプロイする準備が整いました。

ステップ1:イメージについて学ぶ

起動するアプリケーション用コンテナのいくつかは、 Docker Hub から既存のイメージを直接取得します。カスタム・イメージを必要とする他のコンテナは、自分で構築する必要があります。どのコンテナがカスタム・イメージを使えるどうか、あるいは構築する必要があるか確認します。

  • ロードバランサ・コンテナ:作成済みイメージ( ehazlett/interlock
  • Redis コンテナ:作成済みイメージ(公式 redis イメージ)
  • Postgres ( PostgreSQL ) コンテナ:作成済みイメージ(公式 postgres イメージ)
  • Web コンテナ:カスタム・イメージを構築
  • Worker コンテナ:カスタム・イメージを構築
  • Results コンテナ:カスタム・イメージを構築

カスタム・イメージの構築に必要な Dockerfile は、 アプリケーションの GitHub 公開リポジトリ から取得できます。

  1. Swarm``manager`` ノードに ssh で接続していなければ、接続します。
  1. アプリケーションの GitHub リポジトリ をクローンします。
$ git clone https://github.com/docker/swarm-microservice-demo-v1
sudo: unable to resolve host master
Cloning into 'swarm-microservice-demo-v1'...
remote: Counting objects: 304, done.
remote: Compressing objects: 100% (17/17), done.
remote: Total 304 (delta 5), reused 0 (delta 0), pack-reused 287
Receiving objects: 100% (304/304), 2.24 MiB | 2.88 MiB/s, done.
Resolving deltas: 100% (132/132), done.
Checking connectivity... done.

このコマンドは、現在のディレクトリ直下に新しいディレクトリ階層を作成します。新しいディレクトリには投票アプリケーション・イメージの構築に必要な全てのファイルとフォルダがあります。

AWS ディレクトリにある cloudformation.json ファイルは EC2 インスタンスのデプロイに使いました。 Vagrant ディレクトリにあるファイルや命令は Vagrant を使ってアプリケーションをデプロイする時に必要となります。 results-appvote-workerweb-vote-app ディレクトリには Dockerfile が入っています。これは、 アプリケーションの各コンポーネントとして必要になるカスタム・イメージを構築するために必要なファイルです。

  1. swarm-microservice-demo-v1/web-vote-app ディレクトリに移動します。
$ cd swarm-microservice-demo-v1/web-vote-app/
  1. Dockerfile の内容を確認します。
$ cat Dockerfile
# Using official python runtime base image
FROM python:2.7
# Set the application directory
WORKDIR /app
# Install our requirements.txt
ADD requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt
# Copy our code from the current folder to /app inside the container
ADD . /app
# Make port 80 available for links and/or publish
EXPOSE 80
# Define our command to be run when launching the container
CMD ["python", "app.py"]

ご覧の通り、このイメージは公式の Python:1.7 とタグ付けされたイメージをベースにします。 /app ディレクトリに必要なファイルを追加し、依存関係のあるものをインストールし、構築コンテクストに含めるファイルをコンテナ内にコピーし、コンテナのコマンド実行時にポート 80 を公開するよう命令しています。

  1. 投票アプリケーションの他のパーツも、 results-app/Dockerfilevote-worker/Dockerfile を時間をかけて確認します。

ステップ2:カスタム・イメージの構築

  1. Swarm manager ノードに ssh で入っていなければ、入ります。
  1. DOCKER_HOST が設定されているのを確認します。
$ export DOCKER_HOST="tcp://192.168.33.11:3375"
  1. swarm-microservice-demo-v1 をクローンしたディレクトリに移動します。
  1. 各フロントエンドのノード上で web-votes-app イメージを構築します。

frontend01:

$ docker -H tcp://192.168.33.20:2375 build -t web-vote-app ./web-vote-app

frontend02:

$ docker -H tcp://192.168.33.21:2375 build -t web-vote-app ./web-vote-app

これらのコマンドは frontend01frontend02 ノード上に web-vote-app イメージを構築します。これらのコマンドを実行すると、 manager ノード上の swarm-microservice-demo-v1/web-vote-app サブディレクトリの内容が、各フロントエンドのノードにコピーされます。そして、このコマンドは各フロントエンド・ノード内でローカルにイメージを構築・保管します。

このサンプルでは -H フラグを使いイメージを取得するホストを指定します。これがこのサンプルのアーキテクチャの概念を理解する手助けになるでしょう。プロダクション環境のデプロイでは、この作業を省略し、Swarm マネージャでイメージを配布させることも可能です。マネージャはイメージを必要とする各ノード上で、個々にイメージを取得(pull)することができます。

イメージ構築には数分ほど時間がかかるかもしれません。構築完了までお待ち下さい。

  1. worker01 ノード上で vote-worker イメージを構築します。
$ docker -H tcp://192.168.33.200:2375 build -t vote-worker ./vote-worker

イメージ構築には数分ほど時間がかかるかもしれません。構築完了までお待ち下さい。

  1. store ノード上で results-app を構築します。
$ docker -H tcp://192.168.33.250:2375 build -t results-app ./results-app

アプリケーションが必要とする各カスタム・イメージを構築し、実行する各ノードのローカルに保管しました。

ステップ3:Docker Hub からイメージを取得

パフォーマンス上の理由により、それぞれのインスタンスの必要性に応じて、Docker Hub からイメージをダウンロードするのは良い方法です。そうすることで、必要とするコンテナを迅速に実行できます。

  1. Swarm manager ノードにログインします。
  1. フロントエンド・ノード で redis イメージを取得します。

frontend01:

$ docker -H tcp://192.168.33.20:2375 pull redis

frontend02:

$ docker -H tcp://192.168.33.21:2375 pull redis
  1. store ノードに postgres イメージを取得します。
$ docker -H tcp://192.168.33.250:2375 pull postgres
  1. interlock ノードに ehazlett/interlock イメージを取得します。
$ docker -H tcp://192.168.33.12:2375 pull ehazlett/interlock

クラスタ上のノードだけでなく、 interlock ノードの準備も整いました。これで次のように各ノードで必要なイメージがローカルに保管されている状態です。

../../_images/interlock.png

これで全てのイメージを構築・取得し、ローカルに保存しました。次のステップはアプリケーションの起動です。

ステップ4:投票用アプリケーションを起動

以下の手順は、投票用アプリケーションのコンテナを起動します。

  1. Swarm manager ノードに ssh 接続していなければ、接続します。
  1. interlock ノードで interlock コンテナを起動します。
$ docker -H tcp://192.168.33.12:2375 run --restart=unless-stopped -p 80:80 --name interlock -d ehazlett/interlock --swarm-url tcp://192.168.33.11:3375 --plugin haproxy start

このコマンドは interlock インスタンスのポート 80 をコンテナ内のポート 80 に割り当てます。これにより、コンテナがポート 80 (HTTP)に来たトラフィックを負荷分散できます。また、このコマンドはコンテナに対して --restart=unless-stopped ポリシーを設定しています。これはコンテナが不意に停止することがあれば、コンテナを(自動的に)再起動します。

  1. コンテナが起動していることを確認します。
$ docker -H tcp://192.168.33.12:2375 ps
  1. フロントエンド・ノード上で redis コンテナを起動します。

frontend01:

$ docker run --restart=unless-stopped --env="constraint:node==frontend01" -p 6379:6379 --name redis01 --net mynet -d redis
$ docker -H tcp://192.168.33.20:2375 ps

frontend02:

$ docker run --restart=unless-stopped --env="constraint:node==frontend02" -p 6379:6379 --name redis02 --net mynet -d redis
$ docker -H tcp://192.168.33.21:2375 ps

Swarm クラスタに対して2つのコマンドを実行します。このコマンドはノード制約(code constrains)を指定し、Swarm に frontend01frontend02 でコンテナを起動するよう指定しています。また、デバッグ目的のために各コンテナのポート 6379 を各インスタンスのポート 6379 に割り当てます。さらにコンテナに対する --restart=unless-stopped `` ポリシーと、コンテナを ``mynet オーバレイ・ネットワークに接続する設定を行っています。

  1. フロントエンド・ノード上で web-vote-app コンテナを起動します。

frontend01:

$ docker run --restart=unless-stopped --env="constraint:node==frontend01" -d -p 5000:80 -e WEB_VOTE_NUMBER='01' --name frontend01 --net mynet --hostname votingapp.local web-vote-app

frontend02:

$ docker run --restart=unless-stopped --env="constraint:node==frontend02" -d -p 5000:80 -e WEB_VOTE_NUMBER='02' --name frontend02 --net mynet --hostname votingapp.local web-vote-app

Swarm クラスタに対して2つのコマンドを実行します。このコマンドはノード制約(code constrains)を指定し、Swarm に frontend01frontend02 でコンテナを起動するよう指定しています。また、各コンテナのポート 80 を各インスタンスのポート 5000 に割り当てます。これは各ノード上のポート 5000 に接続すると、各コンテナのポート 80 に転送されます。

どちらのコンテナも mynet オーバレイ・ネットワークに接続し、どちらも votingapp-local ホスト名を持ちます。コンテナに対して --restart=unless-stopped ポリシーも指定しています。

  1. store ノード上で postgres コンテナを起動します。
$ docker run --restart=unless-stopped --env="constraint:node==store" --name pg -e POSTGRES_PASSWORD=pg8675309 --net mynet -p 5432:5432 -d postgres

このコマンドは Swarm クラスタに対して store 上でコンテナを起動します。 store ノード上のポート 5432 をコンテナ内の 5432 に割り当てて、コンテナを mynet オーバレイ・ネットワークに接続します。

プロダクションでの利用ではパスワード共有は推奨されません。

  1. worker01 ノード上で worker01 コンテナを起動します。
$ docker run --restart=unless-stopped --env="constraint:node==worker01" -d -e WORKER_NUMBER='01' -e FROM_REDIS_HOST=1 -e TO_REDIS_HOST=2 --name worker01 --net mynet vote-worker

このコマンドは Swarm マネージャに対して worker01 ノード上でコンテナを起動するよう制約(constraint)を使っています。これは環境変数を通して設定用のデータを渡しています。これは worker コンテナに対して、 frontend01frontend02 にあるキューをクリアにするよう命令しています。また、コンテナを mynet オーバレイ・ネットワークに追加し、コンテナに --restart=unless-stopped ポリシーを適用しています。

  1. store ノード上で results-app コンテナを起動します。
$ docker run --restart=unless-stopped --env="constraint:node==store" -p 80:80 -d --name results-app --net mynet results-app

このコマンドはノード制約(node constraint)によって store ノード上に results-app コンテナを起動します。 store ノードのポート 80 をコンテナ内のポート 80 に割り当てます。コンテナを mynet オーバレイ・ネットワークに接続し、 --restart=unless-stopped ポリシーをコンテナに適用します。

下図の状態となれば、これでアプリケーションのデプロイは完了です。

../../_images/fully-deployed.png

ステップ5:アプリケーションのテスト

これでアプリケーションはデプロイが終わり、実行中になりました。さぁ、テストの時間です。そのためにはウェブ・ブラウザが実行中のマシンから参照できるよう、DNS 設定を調整する必要があります。そのために「votingapp.local」DNS名を interlock ノードのパブリック IP アドレスに割り当てます。

  1. ブラウザで参照できるようにするため、ローカルのマシン上の DNS 名前解決の設定を変更します。
  • Windows マシンの場合は C:\Windows\System32\Drivers\etc\hosts file ファイルに votingapp.local <interlock-パブリックIP> の行を追加します。管理者権限でファイルを開くために C:\Windows\System32\notepad.exe を右クリックし、 管理者として実行 を選びます。メモ帳が開いたら、 ファイル開く でファイルを開き、編集します。
  • OSX マシンの場合は votingapp.local <interlock-パブリックIP>/private/etc/hosts に追加します。
  • 殆どの Linux マシン上では votingapp.local <interlock-パブリックIP>/etc/hosts に追加します。

<interlock-パブリックIP> の部分は、各自の interlock ノードの IP アドレスに置き換えてください。 AWS EC2 コンソール内の interlock EC2 インスタンスの場所からノードのパブリック IP アドレスを確認できます。

  1. 正常に名前解決できるか確認するために、自分のマシン上で ping コマンドを実行します。
ping votingapp.local
Pinging votingapp.local [54.183.164.230] with 32 bytes of data:
Reply from 54.183.164.230: bytes=32 time=164ms TTL=42
Reply from 54.183.164.230: bytes=32 time=163ms TTL=42
Reply from 54.183.164.230: bytes=32 time=169ms TTL=42
  1. ブラウザで http://votingapp.local を開きます。

ウェブページ上の文字列にご注意ください。ここに表示されているのは、どのウェブ・コンテナ・サービスに対してリクエストしているかです。これが frontend02 であれば、ウェブ・ブラウザを再読込すると、 interlock ロード・バランサは入ってきたリクエストを両方のコンテナに振り分けるのが分かります。

Interlock サービスの負荷分散に関する詳細なデータは、ブラウザで http://stats:interlock@votingapp.local/haproxy?stats を開きます。

  1. 投票します。「Dogs」を選ぶことを推奨します ;-)
  1. 投票結果を見るには、 store ノードのパブリック IP アドレスをブラウザで開きます。

次のステップ

おめでとうございます。マイクロサービスをベースとしたアプリケーションを Swarm クラスタ上に手動でデプロイできました。もちろん、すべてが上手くいくとは限りません。どのようにスケールするアプリケーションをデプロイするかを学びましたので、次は Swarm クラスタ上で大規模アプリケーション実行時のトラブルシューティング を学ぶべきでしょう。