AWS FargateでNginxを動かしてみる

*本記事は個人の意見であり、所属する組織の見解とは関係ありません。*

![](https://cdn-images-1.medium.com/max/1600/1*GSVXxgrcREUoS_vRTbajpw.png)

こちらは[AWS Fargate Advent Calendar 2017](https://qiita.com/advent-calendar/2017/aws-fargate)の12/2分の記事です。

AWS Fargateを使うことで、コンテナを使ったアプリケーションにだけ集中して開発することができます。今日は、Amazon ECSのコンソールのFirst runチュートリアルを通して、簡単にNginxを立ち上げてみて、変更を加えてデプロイしてみましょう。

First runは以下のリンクから始められます。

- https://console.aws.amazon.com/ecs/home?region=us-east-1#/firstRun

## 1セット作成してみる

Step 1を見ると、Nginxのコンテナ定義はチュートリアルにあるのでそれを選ぶだけで簡単に作成できます。

<img width="866" alt="Screen Shot 2017-12-03 at 12.40.39 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/24676/e680fbff-df12-a754-0e03-8fd7bfc8a9d4.png">

Step 2では、サービスにApplication Load Balancerを紐付けるチェックボックスを選択します。

<img width="842" alt="Screen Shot 2017-12-03 at 12.41.07 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/24676/82d3f4d3-ace7-8fc9-b1fc-487cde49266e.png">

Step 3では、Cluster nameを適当につけます。ここでは`advent-calendar-2017`とします。

<img width="833" alt="Screen Shot 2017-12-03 at 12.41.39 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/24676/9daef658-7b86-d9e2-3530-13b5683b98be.png">

Step 4で確認したら作成します。これだけです。実際は選択した情報を元にAWS CloudFormationスタックが作成され、以下のリソースが自動的に生成されます。もちろん、Fargateを使うのでこの中にAmazon EC2インスタンスは含まれていません！

<img width="777" alt="Screen Shot 2017-12-03 at 12.48.05 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/24676/0ba8758d-0e41-80b8-4013-1e1930e29c33.png">

作成が完了したら、Load balancerのリンクを開き、DNS nameをブラウザで開くとNginxのindex.htmlが表示されます。503が返って来る場合は、タスクの起動待ちですのでしばらく待てば大丈夫です。

<img width="495" alt="Screen Shot 2017-12-03 at 12.49.10 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/24676/c8e971d7-156c-aae0-21b5-0de8a82626f8.png">

View Service => Tasksタブから、起動しているタスクの詳細を開くとLogというタブがあるので、そこを見るとNginxのアクセスログが表示されると思います。ALBからのヘルスチェックと自身のブラウザでアクセスしたログが記録されています。なお、実体はAmazon CloudWatch Logsに収集されています。

<img width="1092" alt="Screen Shot 2017-12-03 at 12.50.49 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/24676/eca08b6e-5b49-ee02-f448-5c640588e2e0.png">

以上です。とても簡単ですね！、、、だけだと面白くないので、作成したECSサービスをすこしだけいじってみましょう。

## スケールしてみる

タスクはFargateで起動されているので、数を変更してスケールさせたい時はサービスのタスク数を変更して更新するだけです。先程作成した時には1タスクになっているので、これを2にしてみましょう。サービスの画面でUpdateをクリックします。

<img width="658" alt="Screen Shot 2017-12-03 at 12.53.44 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/24676/7a2d5373-bd74-64e6-fab3-04a7a2eb9ebc.png">

Number of tasksを2に変更して、あとはNext stepを押し続け、最後にサービスを更新します。

<img width="771" alt="Screen Shot 2017-12-03 at 12.54.00 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/24676/5c574abf-5328-d8b4-724e-40c9e83e4374.png">

しばらくすると以下のようにタスクの数が増えています。ALBへの登録もサービスが自動で行ってくれますので、すぐにALBからのリクエストがバランスされます。

<img width="638" alt="Screen Shot 2017-12-03 at 12.56.50 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/24676/cf092757-d22a-cb41-d7f7-fe5431ed2e94.png">

[こちらのリンク](https://us-east-1.console.aws.amazon.com/cloudwatch/home?region=us-east-1#logEventViewer:group=/ecs/first-run-task-definition)からCloudWatch Logsの画面に行くと、2つのタスクのログをまとめて見ることができます。

<img width="1064" alt="Screen Shot 2017-12-03 at 12.58.24 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/24676/7296f66c-f991-25c0-58c6-a6f8a232146b.png">

## デプロイしてみる

いわゆるデプロイをするために、タスク定義を新たに作成してサービスを更新してみましょう。サービスの詳細画面からTask definitionのリンクをクリックし現在のタスク定義の画面に飛びます(リビジョンの数字は人によって違います)。そして、Create new revisionをクリックします。

<img width="866" alt="Screen Shot 2017-12-03 at 1.01.55 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/24676/889b8c6e-f143-bc5a-6e3b-3aa080e29860.png">

下の方にスクロールして、Container Definitionsの中にあるnginxをクリックします。すると、コンテナ定義の変更画面が出てくるので、Imageをより軽量なAlpine Linuxベースに変更するため、`nginx:alpine`にします。

<img width="891" alt="Screen Shot 2017-12-03 at 1.03.09 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/24676/9d3c9936-2fd0-27e2-1d14-7567bef02dae.png">

そのままコンテナ定義の画面を下にスクロールして、Advanced container configurationの中のEntry pointとCommandを以下の様に変更します。

- Entry point
    - `sh,-c` (コンマを忘れずに)
- Command
    - `ifconfig eth1 | grep "inet addr" | cut -d ':' -f 2 | cut -d ' ' -f 1 > /usr/share/nginx/html/index.html && exec nginx -g "daemon off;"`
    - コンテナ起動時に、Private IPアドレスをindex.htmlに書き込んでいます。

<img width="674" alt="Screen Shot 2017-12-03 at 1.04.08 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/24676/5f140519-95cd-f582-969c-7d64914c40c4.png">

コンテナ定義のUpdateをクリックして閉じ、一番下のCreateをクリックしてタスク定義を作成します。最後に、今作成したタスク定義でサービスを更新します。ActionsからUpdate Serviceを選択します。

<img width="869" alt="Screen Shot 2017-12-03 at 1.11.49 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/24676/5402064e-89a5-4d8a-ab78-6b18e6c5c677.png">

変更画面が開くと、Task Definitionが新しくなっているので、ClusterとService nameが間違っていないことを確認したらNext stepを押し続け、最後にUpdateをクリックします。

<img width="871" alt="Screen Shot 2017-12-03 at 1.13.03 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/24676/c893e093-38c0-3a86-325c-17ab06243836.png">

これによって、新旧タスクがいわゆるBlue/Greenデプロイの形で入れ替わります。デフォルトの設定では、デプロイ中も最低限100%(2タスク)を確保しつつ、最大で200%(4タスク)が同時実行されることを許容する設定にしているので、おおまかには以下の様な流れでデプロイが実行されます:

1. 新タスク定義のタスクが2つ起動する
2. 新タスク定義のタスクがALBに登録され、Healthyになる
    - この時点で、トラフィックは新旧混在状態になる
3. 旧タスク定義のタスク2つがALBから解除される
    - この時点で、トラフィックは新タスクのみになる
    - ALBのTarget GroupのDeregistration Delayがデフォルトだと300秒になっているので、ここから5分かかるが、0秒に変更すれば即座に解除される。
4. 旧タスク定義のタスク2つが削除され、サービス更新完了

ALBのDNS nameに何度かアクセスしてみると、表示されるIPアドレスが入れ替わることが分かると思います。

## 作成した環境を削除する

最後に、今作成した環境を削除しておきます。といっても簡単で、ECSのクラスタを削除すれば、関連するリソースを全て自動的に削除してくれます。具体的には、CloudFormationスタックが削除されます。

<img width="813" alt="Screen Shot 2017-12-03 at 1.26.16 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/24676/113ae4c1-0347-f816-a6ea-8197a498a075.png">

進捗も表示されるので安心です。

<img width="475" alt="Screen Shot 2017-12-03 at 1.26.36 AM.png" src="https://qiita-image-store.s3.amazonaws.com/0/24676/d406ec1a-cb60-3dbb-2c38-afd0a941a1af.png">

# まとめ

First runチュートリアルで数クリックでNginxをFargateで立ち上げた後に、スケールしたりデプロイしてみたりしました。タスクのこととサービスのことだけに集中して作業できることがお分かり頂けたかと思います。