この記事では、複数のDockerコンテナで構成される環境を構築するための設定例を具体的に解説します。ワークショップのフォローアップではありますが、一般的な事柄を扱いますので、ワークショップに参加されていない方にもお読み頂ける内容です。
前回の記事: JAWS DAYS 2017 ワークショップ Docker on Elastic Beanstalk 〜Days after tomorrow〜 (2)
梅雨ですね
こんにちは。Emotion Techの子安です。ずいぶん前から梅雨入りしたのに全然雨が降らないなと思っていたら、最近ようやく梅雨らしくなってきましたね。良いお湿りです。
前回のつづき
さて、前々回・前回とdocker-compose.ymlを見てきました。今回はいよいよElastic BeanstalkへデプロイするためのDockerrun.aws.jsonを見ていきます。それと併せて、Dockerネットワークについて少し解説します。
Elastic Beanstalk と Dockerrun.aws.json
繰り返しになりますが、Elastic Beanstalkはdocker-compose.ymlを一切参照しません。Elastic BeanstalkでDockerコンテナをデプロイするためにはDockerrun.aws.jsonを使います。AWSの公式ドキュメントは このあたり です。
ところで、Elastic BeanstalkではDockerのための環境として「単一のコンテナをデプロイする環境」と「複数のコンテナをデプロイする環境」が提供されており、今回は「複数のコンテナをデプロイする環境」の方を利用します。同じDockerのための環境でも「単一」環境と「複数」環境では、Elastic Beanstalkの裏側の仕組みが大きく異なります。
- 「単一」環境: DockerデーモンがインストールされたEC2
- 「複数」環境: ECS
従って、今回解説するDockerrun.aws.jsonの定義内容も、ECS由来の設定が大部分を占めます。今から敢えて「単一」環境を選ぶメリットは特に無いため、事情がなければ「複数」環境を選択することをお勧めします。
さて本題に戻ります。リポジトリの Dockerrun.aws.json を参照ください。この
Dockerrun.aws.jsonを、docker-compose.yml とざっと見比べてみましょう。・・・なんとなく、対応する記述が多いことに気づかれると思います。同じ構成のコンテナを起動しようとしているわけですから、勢い似た記述になると言えば当然ですが、言葉の使い方もほぼ同じですので、対応関係さえ分かれば理解は容易なのではないでしょうか。
それでも異なる点が3つほどあります。
memory
"memory": 256,
最初はこの部分ですね。これはコンテナに割り当てるメモリの最大値を指定するものです。Dockerrun.aws.jsonでは必須の設定となっており、省略できません。複数のコンテナを安定して稼働させるためには、メモリ管理は必須というわけです。docker-compose.ymlでも同様の設定が可能ですが、オプションとなっており今回は簡単のために省略しています。
links
"links": [
"app"
],
次はこの部分でしょう。これは具体的には web
コンテナから app
コンテナへの通信を可能にするというネットワーク上の(レガシーな)設定です。そして今回唯一、Dockerrun.aws.jsonとdocker-compose.ymlとの間で、根本的に異なる設定でもあります。具体的な違いについては後述しますので、今のところDockerrun.aws.jsonではこのようにコンテナ同士の通信を設定するものだと思ってください。
mountPoints
"mountPoints": [
{
"sourceVolume": "web-conf",
"containerPath": "/etc/nginx/conf.d",
"readOnly": true
},
...(中略)...
"volumes": [
{
"name": "web-conf",
"host": {
"sourcePath": "/var/app/current/web/conf.d"
}
},
最後にこの部分です。これはホストからコンテナへのボリュームマウントを設定しており、具体的にはホスト側のディレクトリ /var/app/current/web/conf.d
をコンテナ側のディレクトリ /etc/nginx/conf.d
にマウントしています。そしてElastic Beanstalkでは、デプロイしたアプリケーションバンドルが /var/app/current
に展開されます。つまり記述の仕方と指定しているディレクトリパスは異なりますが、docker-compose.ymlでやっていたことと本質的には同様のことを設定しています。
Dockerネットワーク
先述したネットワーク設定の違いについて見ておきましょう。
Dockerrun.aws.jsonで設定しているネットワーク
"links": [
"app"
],
Dockerで利用できるネットワークのうち、最初期からあるものが bridge
という名前のブリッジネットワークです(ホストOS上のインターフェース名は docker0
)。2017年6月現在でもデフォルトのネットワークとして、例えばdockerコマンドでネットワークを指定しないで起動したコンテナなどは、このネットワーク bridge
に接続されます。
links
は、ネットワーク bridge
に接続されたコンテナ同士の名前解決をするための設定です。 links
を設定したコンテナでは、リンク先のコンテナが /etc/hosts
に登録され、またIPアドレスやポートを指す幾つかの環境変数が設定されます。
docker-compose.ymlで設定しているネットワーク
docker-compose.ymlのネットワーク設定を再掲します。
networks:
- eb.workshop
...(中略)...
networks:
eb.workshop: {}
前々回も触れたとおり、docker-compose.ymlでは eb.workshop
という名前のネットワークを定義し、そこに各コンテナを接続するという内容になっています。ネットワークに接続された各コンテナは、サービスとしての名前でもある web
app
などで互いに通信可能となります。内部的にはDNSが設定されて名前解決が行われます。このネットワーク機能はDockerバージョン1.10から導入されました。
docker-compose.ymlでも設定次第で links
を利用することは可能ですが、廃止の可能性があるレガシーな機能とされています。
まとめ
今回で、複数のDockerコンテナで構成される環境を構築するための設定の解説は終了です。3つの記事を通して、具体的なdocker-compose.ymlやDockerrun.aws.jsonの設定を一つずつ見てきました。参考になれば幸いです。
すべてのリソースはGitHubリポジトリ elastic-beanstalk-workshop にあり、設定ファイルやワークショップの手順書も入っています。コンテナの起動はもちろん、コンテナの中で操作するコマンドなどもREADMEに記載していますので、興味のある方は是非触れてみてください。