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

これまで ロードバランサ、ディスカバリ・バックエンド、Swarm クラスタをデプロイ しました。次は投票アプリケーションをデプロイしましょう。ここで「Docker化したアプリケーション」を起動し始めます。

次の図は最終的なアプリケーション設定であり、 voteapp オーバレイ・コンテナ・ネットワークも含みます。

../../_images/final-result.png

この手順ではコンテナをネットワークに接続します。この voteapp ネットワークは Consul ディスカバリ・バックエンドを使う全ての Docker ホスト上で利用可能です。 interlocknginxconsulswarm manager コンテナは voteapp オーバレイ・コンテナ・ネットワークの一部なのでご注意ください。

タスク1:ボリュームとネットワークのセットアップ

このアプリケーションはオーバレイ・コンテナ・ネットワークとコンテナ・ボリュームに依存します。Docker Engine は2つの機能を提供します。Swarm manager インスタンス上でどちらも作成可能です。

  1. ローカル環境を Swarm manager ホストに向けます。
$ eval $(docker-machine env manager)

クラスタ・ノード上でネットワークを作成したら、ネットワーク全体で参照可能になります。

  1. voteapp コンテナ・ネットワークを作成します。
$ docker network create -d overlay voteapp
  1. db ストアに切り替えます。
$ eval $(docker-machine env dbstore)
  1. db ストア・ノードで新しいネットワークを確認します。
$ docker network ls
NETWORK ID          NAME                DRIVER
e952814f610a        voteapp             overlay
1f12c5e7bcc4        bridge              bridge
3ca38e887cd8        none                null
3da57c44586b        host                host
  1. db-data という名称のコンテナ・ボリュームを作成します。
$ docker volume create --name db-data

タスク2:コンテナ化したマイクロサービスの起動

この時点で、マイクロサービスのコンポーネントを起動し、アプリケーションを起動する準備が整いました。アプリケーション・コンテナによっては、Docker Hub にある既存イメージを直接ダウンロードして実行できます。その他、自分でカスタマイズしたイメージを実行したい場合は、構築する必要があります。以下はどのコンテナがカスタム・イメージを使っているか、使っていないかの一覧です。

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

このセクションではクラスタ上のホストに対して、コマンドでこれらのコンテナを起動します。 Swarm マネージャに対して命令するためには、各コマンドで -H フラグを使います。

コマンドには -e も含みます。これは Swarm に制限(constraint)を指定するためです。制限はマネージャに対して、function(機能)のラベルに一致するノードの指定で使います。ラベルはノード作成時に設定します。以降のコマンド実行時に、制約の値を確認します。

  1. Postgres データベース・コンテナを起動します。
$ docker -H $(docker-machine ip manager):3376 run -t -d \
-v db-data:/var/lib/postgresql/data \
-e constraint:com.function==dbstore \
--net="voteapp" \
--name db postgres:9.4
  1. Redis コンテナを起動します。
$ docker -H $(docker-machine ip manager):3376 run -t -d \
-p 6379:6379 \
-e constraint:com.function==dbstore \
--net="voteapp" \
--name redis redis

redis の名前は重要なため、変更しないでください。

  1. ワーカ・アプリケーションを起動します。
$ docker -H $(docker-machine ip manager):3376 run -t -d \
-e constraint:com.function==worker01 \
--net="voteapp" \
--net-alias=workers \
--name worker01 docker/example-voting-app-worker
  1. results アプリケーションを起動します。
$ docker -H $(docker-machine ip manager):3376 run -t -d \
-p 80:80 \
--label=interlock.hostname=results \
--label=interlock.domain=myenterprise.com \
-e constraint:com.function==dbstore \
--net="voteapp" \
--name results-app docker/example-voting-app-result-app
  1. 各フロントエンド・ノード上に、2つの投票アプリケーションを起動します。
$ docker -H $(docker-machine ip manager):3376 run -t -d \
-p 80:80 \
--label=interlock.hostname=vote \
--label=interlock.domain=myenterprise.com \
-e constraint:com.function==frontend01 \
--net="voteapp" \
--name voting-app01 docker/example-voting-app-voting-app

そして、別のフロントエンド・ノード上で実行します。

$ docker -H $(docker-machine ip manager):3376 run -t -d \
-p 80:80 \
--label=interlock.hostname=vote \
--label=interlock.domain=myenterprise.com \
-e constraint:com.function==frontend02 \
--net="voteapp" \
--name voting-app02 docker/example-voting-app-voting-app

タスク3:作業内容の確認と /etc/hosts の更新

このステップでは、 Nginx コンテナの設定が適切に行われているかを確認します。ロードバランサの動作確認のため、ローカルの /etc/hosts ファイルを変更します。

  1. loadbalancer ノードに変更します。
$ eval $(docker-machine env loadbalancer)
  1. nginx の設定を表示し、内容を確認します。
$ docker exec interlock cat /etc/conf/nginx.conf
... 出力を省略 ...

upstream results.myenterprise.com {
    zone results.myenterprise.com_backend 64k;

    server 192.168.99.111:80;

}
server {
    listen 80;

    server_name results.myenterprise.com;

    location / {
        proxy_pass http://results.myenterprise.com;
    }
}
upstream vote.myenterprise.com {
    zone vote.myenterprise.com_backend 64k;

    server 192.168.99.109:80;
    server 192.168.99.108:80;

}
server {
    listen 80;

    server_name vote.myenterprise.com;

    location / {
        proxy_pass http://vote.myenterprise.com;
    }
}

include /etc/conf/conf.d/*.conf;
}

http://vote.myenterprise.com サイトの設定は、どちらかのフロントエンド・ノードを指し示します。 http://results.myenterprise.com にリクエストしたら、 example-voting-app-result-app が稼働している dbstore ノードに移動します。

  1. ローカルホスト上で /etc/hosts ファイルを編集し、これらサイトの名前解決の行を追加します。
  1. /etc/hosts ファイルを保存して閉じます。
  1. nginx コンテナの再起動。

現在の Interlock サーバの設定が Nginx の設定を反映していません。そのため、手動で再起動の必要があります。

$ docker restart nginx

タスク4:アプリケーションのテスト

これでアプリケーションをテストできます。

  1. ブラウザを開き、サイト http://vote.myenterprise.com に移動します。

投票ページ「Cats vs Dogs!」が画面に表示されます。

  1. 2つの選択肢のうち、どちらかに投票します。
  1. サイト http://results.myenterprise.com に移動し、結果を表示します。
  1. 他の選択肢に投票します。

投票した結果が画面上に表示されます。

追加作業:Docker Compose でデプロイ

これまでは、各アプリケーションのコンテナを個々に起動しました。しかし、複数コンテナの起動や依存関係の順番に従った起動は、とても煩雑です。例えば、データベースはワーカが起動する前に動いているべきでしょう。

Docker Compose はマイクロサービス・コンテナと依存関係を Compose ファイルで定義します。そして、Compose ファイルを使って全てのコンテナを一斉に起動します。これは追加作業(extra credit)です。

  1. 始める前に、起動した全てのコンテナを停止します。
  1. (作業対象の)ホストをマネージャに向けます。
$ DOCKER_HOST=$(docker-machine ip manager):3376
  1. Swarm 上のアプリケーション全てを一覧します。
  1. 各コンテナを停止・削除します。
  1. このチュートリアルに従って、自分で Compose ファイルの作成を試みます。

Compose ファイルはバージョン2形式を使うのがベストです。各 docker run コマンドを docker-compose.yml ファイル内のサービスに置き換えます。例えば、次のコマンドがあります。

$ docker -H $(docker-machine ip manager):3376 run -t -d \
-e constraint:com.function==worker01 \
--net="voteapp" \
--net-alias=workers \
--name worker01 docker/example-voting-app-worker

これは、次の Compose ファイルに書き換え可能です。

worker:
  image: docker/example-voting-app-worker
  networks:
    voteapp:
      aliases:
      - workers

通常、 Compose はファイルに現れる逆順でサービスの起動を試みます。そのため、あるサービスを他のサービスよりも前に実行するには、ファイル中の最後尾にサービスを記述する必要があります。アプリケーションがボリュームやネットワークを使う場合は、ファイルの末尾で宣言します。

  1. 結果が ファイル と一致しているか確認します。
  1. 問題が無ければ、システム上に docker-compose.yml ファイルを保存します。
  1. DOCKER_HOST を Swarm マネージャに向けます。
$ DOCKER_HOST=$(docker-machine ip manager):3376
  1. docker-compose.yml と同じディレクトリで、サービスを起動します。
$ docker-compose up -d
Creating network "scale_voteapp" with the default driver
Creating volume "scale_db-data" with default driver
Pulling db (postgres:9.4)...
worker01: Pulling postgres:9.4... : downloaded
dbstore: Pulling postgres:9.4... : downloaded
frontend01: Pulling postgres:9.4... : downloaded
frontend02: Pulling postgres:9.4... : downloaded
Creating db
Pulling redis (redis:latest)...
dbstore: Pulling redis:latest... : downloaded
frontend01: Pulling redis:latest... : downloaded
frontend02: Pulling redis:latest... : downloaded
worker01: Pulling redis:latest... : downloaded
Creating redis
Pulling worker (docker/example-voting-app-worker:latest)...
dbstore: Pulling docker/example-voting-app-worker:latest... : downloaded
frontend01: Pulling docker/example-voting-app-worker:latest... : downloaded
frontend02: Pulling docker/example-voting-app-worker:latest... : downloaded
worker01: Pulling docker/example-voting-app-worker:latest... : downloaded
Creating scale_worker_1
Pulling voting-app (docker/example-voting-app-voting-app:latest)...
dbstore: Pulling docker/example-voting-app-voting-app:latest... : downloaded
frontend01: Pulling docker/example-voting-app-voting-app:latest... : downloaded
frontend02: Pulling docker/example-voting-app-voting-app:latest... : downloaded
worker01: Pulling docker/example-voting-app-voting-app:latest... : downloaded
Creating scale_voting-app_1
Pulling result-app (docker/example-voting-app-result-app:latest)...
dbstore: Pulling docker/example-voting-app-result-app:latest... : downloaded
frontend01: Pulling docker/example-voting-app-result-app:latest... : downloaded
frontend02: Pulling docker/example-voting-app-result-app:latest... : downloaded
worker01: Pulling docker/example-voting-app-result-app:latest... : downloaded
Creating scale_result-app_1
  1. docker ps コマンドで Swarm クラスタ上のコマンドを確認します。
$ docker -H $(docker-machine ip manager):3376 ps
CONTAINER ID        IMAGE                                  COMMAND                  CREATED             STATUS              PORTS                            NAMES
b71555033caa        docker/example-voting-app-result-app   "node server.js"         6 seconds ago       Up 4 seconds        192.168.99.104:32774->80/tcp     frontend01/scale_result-app_1
cf29ea21475d        docker/example-voting-app-worker       "/usr/lib/jvm/java-7-"   6 seconds ago       Up 4 seconds                                         worker01/scale_worker_1
98414cd40ab9        redis                                  "/entrypoint.sh redis"   7 seconds ago       Up 5 seconds        192.168.99.105:32774->6379/tcp   frontend02/redis
1f214acb77ae        postgres:9.4                           "/docker-entrypoint.s"   7 seconds ago       Up 5 seconds        5432/tcp                         frontend01/db
1a4b8f7ce4a9        docker/example-voting-app-voting-app   "python app.py"          7 seconds ago       Up 5 seconds        192.168.99.107:32772->80/tcp     dbstore/scale_voting-app_1

サービスを手動で起動した時は、 voting-app インスタンスは2つのフロントエンド・ノード上で動作していました。今回はいくつ起動していますか?

  1. アプリケーションをスケールするため、voting-app インスタンスを追加します。
$ docker-compose scale voting-app=3
Creating and starting 2 ... done
Creating and starting 3 ... done

スケールアップ後は、クラスタ上のコンテナ一覧を再び表示します。

  1. loadbalancer ノードに変更します。
$ eval $(docker-machine env loadbalancer)
  1. Nginx サーバを再起動します。
$ docker restart nginx
  1. http://vote.myenterprise.comhttp://results.myenterprise.com を再び表示して、投票の動作を確認します。
  1. 各コンテナのログを表示できます。
$ docker logs scale_voting-app_1
 * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger pin code: 285-809-660
192.168.99.103 - - [11/Apr/2016 17:15:44] "GET / HTTP/1.0" 200 -
192.168.99.103 - - [11/Apr/2016 17:15:44] "GET /static/stylesheets/style.css HTTP/1.0" 304 -
192.168.99.103 - - [11/Apr/2016 17:15:45] "GET /favicon.ico HTTP/1.0" 404 -
192.168.99.103 - - [11/Apr/2016 17:22:24] "POST / HTTP/1.0" 200 -
192.168.99.103 - - [11/Apr/2016 17:23:37] "POST / HTTP/1.0" 200 -
192.168.99.103 - - [11/Apr/2016 17:23:39] "POST / HTTP/1.0" 200 -
192.168.99.103 - - [11/Apr/2016 17:23:40] "POST / HTTP/1.0" 200 -
192.168.99.103 - - [11/Apr/2016 17:23:41] "POST / HTTP/1.0" 200 -
192.168.99.103 - - [11/Apr/2016 17:23:43] "POST / HTTP/1.0" 200 -
192.168.99.103 - - [11/Apr/2016 17:23:44] "POST / HTTP/1.0" 200 -
192.168.99.103 - - [11/Apr/2016 17:23:46] "POST / HTTP/1.0" 200 -

このログは、ある投票アプリケーション・コンテナの状況を表示しています。

次のステップ

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