AWS Elastic Beanstalk + docker + playframeworkで動作環境を作ってみました。
1. AWS Elastic Beanstalk
Elastic Beanstalkは、WEB環境を簡単にスケーラブルに作れるAWSのプロダクトのようですがWebサービスを構築する上でどのサービスを選択すればよいかの調査のため試してみました。
ブロクに載せていますが、現時点で最善策を調べきれずに書いているのでもっと良いやり方があるかもしれませんがお許しください。
1-1. Elastic Beanstalkのアプリケーションの作成
Elastic Branstalkの環境を作ります。目的がウェブなのでウェブサーバー環境を選びました。
環境の作成では、ホスト名、プラットフォームを設定します。アプリケーションコードは新規に作成するのであれば「サンプルアプリケーション」から作成して上書くのがお勧めです。
作成が完了するとaws cliからログインしてdockerイメージをpushする手順が表示されます。
2. AWS ECR
Dockerのデプロイは、Dockerfileをアップロードするか、Dockerrun.aws.jsonという定義ファイルをアップロードします。
しかし、Dockerfileとデプロイアーカイブをどう配置したらうまく起動してくれるのかわからなくAWS Elastic Container Registoryを使いました。
AWSコンソールから、ECRはECS(Elastic Container Service)の中にあります。
リポジトリを作成します。
リポジトリを作成するとaws cliを使ってecrにログインする方法とdockerイメージの作り方、pushコマンドが表示されます。
参考URL: https://qiita.com/kazuyoshikakihara/items/f87b4b377b5844f09614
3. AWS s3
DockerのデプロイアーカイブをDockerfileと一緒にあげる方法がわからなかったのでDockerイメージをECRに登録しました。
ECRのイメージをDockerrun.aws.jsonに記述するのですが認証情報をs3に置かなければなりません。
ECRのログイン情報がaws cliにてECRにログインしていれば次のファイルに格納されています。
~/.docker/config.json
参考にしたブログではaws cliでs3を作っていました。
3-1. S3 Bucket を作成する
$ aws --region us-west-2 s3 mb s3://kaorunix-docker-auth
3-2. S3 Bucket に認証情報をアップする
$ aws --region us-west-2 s3 cp ~/.docker/config.json s3://kaorunix-docker-auth/playsample-docker-auth.txt
3-3. IAM roleにポリシーを追加
Elastic BeanstalkインスタンスにS3へのアクセスを許す必要があります。
マネージドポリシーの AmazonS3ReadOnlyAccess をアタッチします。
AWSコンソールでIAM、ロールを開く
Elastic Beanstalkを作成するときに作成したロールサービスのロール(arn:aws:iam::xxxxxxxxxxx:role/aws-elasticbeanstalk-service-role)を選択。ポリシーを選択してアタッチします。
参考URL: https://inokara.hateblo.jp/entry/2016/01/16/191633
4. playframeworkが中で動くdockerイメージ作成
稼働したElastic Beanstalkを置き換えるdokcerイメージを作成します。
4-1. playframeworkの実行アーカイブを作る
実際はプロジェクトを作って実装してからですが、お試しなのでプロジェクト作成しただけでDockerイメージ作ってしまいます。
ただし、いくつか設定をしないと動かないところがあったので載せておきます。
application.confの設定
play.http.secret.keyはここに書く必要があるのかわかりませんが次のコマンドで更新しました。起動時に秘密鍵がないと起動できませんでした。
$ sbt playUpdateSecret
また、接続元ホストの設定を allowed = ["."]
と記載しないと 502 Bad Request
が返りました。
play.http.secret.key="xxxxx"
play.filters.hosts {
allowed = ["."]
}
playプロジェクトのリリースアーカイブを作る
playプロジェクトのディレクトリで次のコマンドを実行し、リリースアーカイブを作る。
$ sbt dist
リリースアーカイブが次のパスにできるので、任意のディレクトリで展開します。
プロジェクトディレクトリ/target/universal/playsample-1.0-SNAPSHOT.zip
Dockerfile作成
リリースアーカイブを展開し、展開したディレクトリに次のDockerfileを作成。
FROM openjdk:8u151-jre
COPY . /root/
RUN chmod +x /root/bin/playsample
CMD ["/root/bin/playsample", "-Dplay.http.secret.key=P0Bz?>b;hYPO8cC=u:sfFacry_x5qVpdh`SpaHEvtYNtQM]YdZfwU<eIM1qVTMfy", "-Dhttp.port=80"]
Dockerfileの意味は以下の通り。
- playflameworkが動くようにjavaの入ったDockerイメージを元にする。
FROM openjdk:8u151-jre
- アーカイブしたファイル群をDockerイメージの中にコピー
COPY . /root/
- 実行権限をつける
RUN chmod +x /root/bin/playsample
- playframework playsampleプロジェクトを常駐プロセスとして起動する。
CMD ["/root/bin/playsample", "-Dplay.http.secret.key=xxxxxxx", "-Dhttp.port=80"]
Dockerfileを準備したら1-1で示されたコマンドを順に実行します。
aws cliでECRにログインします。
$(aws ecr get-login --no-include-email --region us-west-2)
Dockerイメージを作成します。
$ docker build -t astrolab-work .
Dockerをリモートのリポジトリにpushできるようにタグをつけます。
$ docker tag playsample:latest xxxxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/playsample:latest
ECRへのpush
$ docker push xxxxxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/playsample:latest
5. AWS Elastic Beanstalkへのデプロイ
5-1. Dockerrun.aws.configの作成
次のような内容で作成
{
"AWSEBDockerrunVersion": "1",
"Authentication": {
"Bucket": "kaorunix-docker-auth",
"Key": "playsample-docker-auth.txt"
},
"Image": {
"Name": "xxxxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/playsample:latest",
"Update": "true"
},
"Ports": [
{
"ContainerPort": "80"
}
],
"Volumes": [
{
"HostDirectory": "/tmp",
"ContainerDirectory": "/tmp/tmp"
}
],
"Logging": "/var/log/play"
}
各説明
Elastic BeanstalkからECRへのアクセス権を記載したファイルの指定。s3のバケットとファイル名で指定する。
"Authentication": {
"Bucket": "kaorunix-docker-auth",
"Key": "playsample-docker-auth.txt"
},
ECRのリポジトリ名を指定する。
"Image": {
"Name": "xxxxxxxxxx.dkr.ecr.us-west-2.amazonaws.com/playsample:latest",
"Update": "true"
},
予想だが、EC2のボリュームをDocker内にマウントできるのではないだろうか。
"Volumes": [
{
"HostDirectory": "/tmp",
"ContainerDirectory": "/tmp/tmp"
}
],
ログ出力するパスを指定していると思うが、今回ログ出力設定を行っていないので出力されていない。また、設定するとeb cliでログにアクセスできると予想する。
"Logging": "/var/log/play"
5-2. Elastic Beanstalkアプリにアップロードする
AWSコンソールより、デプロイ先のアプリケーション名、環境名を辿り次の画面に移動する。
アップロードとデプロイボタンを押下し、選択ボタンを押下するとファイルを選択するダイアログが開くのでDockerrun.aws.configファイルを選択する。
バージョンは任意の作成したDockerアプリケーションのバージョンなどを入れる。
しばらくデプロイ中の状態になり、完了したら画面上部にあるURLをクリックすると次の画像のようにDockerで動いているアプリケーションが表示される。
ec2またはDockerへの接続
1. eb cliの設定
ebをインストールして設定を実施。
参考URL https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/eb-cli3-configuration.html
ebのsshの設定をする。次のコマンドを実行し、質問のなかでsshのキーを紐づける。
$ eb ssh —setup
キーを紐づけるとsshで接続できるようになりました。
ssh -i ${KEY} ${EC2 hostname}
2. dockerへの接続
dockerは、ec2の中で実行されているのでログインできれば普通にdockerのコマンドが実行できる。