AWS ECS × New RelicによるコンテナのAPM監視

# はじめに
『 ECS(AWSのコンテナマネジメントサービス)で起動したコンテナ上のアプリケーションをNew Relicで監視する 』をゴールとして、実施手順について解説したいと思います。ECSとALBの連携により、コンテナ起動に伴う各AWSサービスへの諸々の設定(サーバプールへの追加、ポートの払い出しetc..)を自動で行えるよう設定していきます。また、コンテナそれぞれにNew Relic Agentを手動でインストールするのは手間なので、起動時に自動でインストール実行できるよう、Dockerに仕込みたいと思います。[New Relic](https://newrelic.nissho-ele.co.jp/)アカウントをお持ちでない方は[こちら](https://contacts.nissho-ele.co.jp/newrelic_signup.html)よりどうぞ。

# 1. コンテナの作成
## ①. Dockerfileの作成
はじめにDockerfileを作成します。今回用意したDockerfileでは、起動時に下記2点を実行します。
1. HTTPサービスの起動及び監視対象PHPファイルの追加
2. New Relic APM Agentをインストールまで行う

```bash:Dockerfile
### CentOS Imageのダウンロード
FROM centos:centos6
### httpdのインストール、監視対象PHPファイルのアップロード##
RUN yum -y install httpd php
ADD phpinfo.php /var/www/html
### New Relic APM Agentのインストールおよびライセンスキーの設定
RUN rpm -Uvh http://yum.newrelic.com/pub/newrelic/el5/x86_64/newrelic-repo-5-3.noarch.rpm
RUN yum -y install newrelic-php5
RUN newrelic-install install
RUN sed -E -i 's/REPLACE_WITH_REAL_KEY/"Your New Relic APM License Key"/' /etc/php.d/newrelic.ini
### httpdの起動
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
```
## ②. コンテナイメージのビルド
次にコンテナイメージをビルドします。

```
# docker build -t nr-test-rp1 .
# docker images
```
コンテナを起動し、ビルドしたイメージが正常に動作することを確認します。

```
# docker run -d -p 8080:80 nr-test-rp1
# docker exec -it nr-test-rp1 bash
```

# 2. ALBの設定
AWS側でALBの設定を行います。
ALBと3で解説するECSの連携により、Auto Port Mapping機能が使用できます。
同機能により、ALB及びECSに対する下記設定を動的に行うことができます。

- EC2ホストインスタンスの空きポートを動的にコンテナポートにマッピング
- ECSが起動したコンテナをALBの負荷分散ターゲットとしてグルーピング
- ALBに対してヘルスチェック/リスナー/ターゲットグループを自動設定

ALBの構成要素は下記のとおりです。それぞれ設定していきます。

- リスナー
- ターゲットグループ
- ヘルスチェック

***サービス > EC2 > ロードバランサー***を選択し、『ロードバランサーの作成』を押下します。

![SnapCrab_NoName_2017-4-27_15-53-34_No-00.png "ELB作成"](https://qiita-image-store.s3.amazonaws.com/0/150903/1967891b-085e-2f54-b910-3992eb50ce5b.png)


***Application Load Balancer***のラジオボタンを選択し、『次へ』を押下します。

![SnapCrab_NoName_2017-4-27_15-54-44_No-00.png "ALB設定"](https://qiita-image-store.s3.amazonaws.com/0/150903/edd68c40-d18f-bb01-2f80-c0064ecba045.png)

***ステップ1: ロードバランサーの設定***にて、下記の項目を設定します。

- 名前
- スキーマ
- IPアドレスタイプ
- リスナー
- アベイラビリティゾーン

![SnapCrab_NoName_2017-4-27_16-1-8_No-00.png "ALB設定"](https://qiita-image-store.s3.amazonaws.com/0/150903/69c837f3-e571-1e8b-b388-10bcf928faea.png)


***ステップ2: セキュリティ設定の構成***ではそのままページ下部の『次の手順』を押下します。


***ステップ3: セキュリティグループの設定***を行います。同ステップでは、ALB用のセキュリティグループを作成するため、HTTPの使用ポートである80番ポートを送信元:any(0.0.0.0/0)として設定します。(送信元については、今回テスト用としてany設定しておりますが、環境に適した任意の送信元を指定ください。)設定後、ページ下部の『次の手順』を押下します。
![SnapCrab_NoName_2017-4-27_16-41-3_No-00.png "ALB設定"](https://qiita-image-store.s3.amazonaws.com/0/150903/373c20bc-46fe-e616-b827-28821cd091b8.png)

![SnapCrab_NoName_2017-4-27_16-4-7_No-00.png "ALB設定"](https://qiita-image-store.s3.amazonaws.com/0/150903/3b2f0e45-4828-3f93-09c8-3c39fe678dcb.png)

***ステップ4: ルーティングの設定***を行います。ターゲットグループ及びヘルスチェックの設定を行います。設定後、ページ下部の『次の手順』を押下します。

![SnapCrab_NoName_2017-4-27_16-22-1_No-00.png "ALB設定"](https://qiita-image-store.s3.amazonaws.com/0/150903/0f39b101-dee8-fcbc-7147-813b1061773a.png)

***ステップ5: ターゲットの登録***ではターゲットインスタンスの登録を行わなず、そのままページ下部の『次の手順』を押下します。

***ステップ6: 確認***で設定内容を確認し、問題なければページ下部の『作成』を押下します。

これでALBの作成は完了です。

# 3. ECSの設定
ECSの構成要素は下記のとおりです。

- ***ECRリポジトリ***...コンテナイメージをアップロードするリポジトリ
- ***クラスタ***...コンテナのホストEC2インスタンスの指定&クラスタリング設定を行う
- ***タスク定義***...クラスタ上で起動するコンテナ=タスクに対して、リソース分配や使用ポートなどの起動設定を行う定義
- ***サービス***...サービス単位でコンテナを複数台起動することが可能、ALB/AutoScalingの設定が可能

## ①. リポジトリの設定 & Docker Imageのアップロード
はじめに、ローカルで作成したコンテナイメージをAWS上にアップロードするため、ECSリポジトリを作成します。
***サービス > EC2 Container Service > リポジトリ*** を選択し、『リポジトリの作成』を押下します。

![SnapCrab_NoName_2017-4-27_16-41-3_No-00.png "ECS-リポジトリ作成"](https://qiita-image-store.s3.amazonaws.com/0/150903/46128c1d-7cd5-dc4c-f8df-56dfe0cf4ead.png)

***ステップ1: リポジトリの設定***にて、リポジトリ名を設定し、ページ下部の『次のステップ』を押下します。

![SnapCrab_NoName_2017-4-27_16-42-22_No-00.png "ECS-リポジトリ設定"](https://qiita-image-store.s3.amazonaws.com/0/150903/45c06e7c-0789-7265-8e4f-34548b59434f.png)


***ステップ2: Docker イメージの構築、タグ付け、プッシュ***にて、ローカルから作成したECRリポジトリへのログイン、コンテナイメージのプッシュに関するコマンドが表示されるので、同表示に従い、コマンドを実行します。

![SnapCrab_NoName_2017-4-27_16-43-33_No-00.png "ECS-リポジトリ設定"](https://qiita-image-store.s3.amazonaws.com/0/150903/5f2a4439-701d-f1f9-45fb-a5e978d9275b.png)

コマンド実行後、レポジトリにイメージが追加されていることを確認します。

![SnapCrab_NoName_2017-5-23_13-18-20_No-00.png "ECS-リポジトリ設定"](https://qiita-image-store.s3.amazonaws.com/0/150903/7da44d12-9514-1fe0-0e12-297470e7fac2.png)

## ②. クラスタの設定
コンテナを搭載するホストEC2インスタンスの指定&クラスタリング設定を行います。

***サービス > ECS > クラスター***を選択し、『クラスターの作成』を押下します。

![SnapCrab_NoName_2017-5-23_13-28-0_No-00.png "ECS-クラスタ設定"](https://qiita-image-store.s3.amazonaws.com/0/150903/9107a934-601f-6e88-a8b3-f7d0c455001f.png)

***クラスターの作成***にて、下記の項目を設定し、『作成』を押下します。

- クラスター名
- EC2インスタンスタイプ
- インスタンス数
- リスナー
- キーペア(ホストEC2にSSHアクセスしたい場合に設定)

- VPC(ALBに設定したものと同じVPCを指定)
- サブネット(同上)
- セキュリティグループ(新規)
- セキュリティグループのインバウンドルール(CIDR:0.0.0.0/0 , ポート:80)
- IAMロール(ecsInstaceRoleポリシーが付与された既存のロール or 新しいロールの作成を選択。新しいロールの作成を選択した場合、ロールが自動作成される)

![SnapCrab_NoName_2017-5-23_13-37-22_No-00.png  "ECS-クラスタ設定"](https://qiita-image-store.s3.amazonaws.com/0/150903/2bd91fb6-c508-db8d-5fb2-caf145f139fb.png)
![SnapCrab_NoName_2017-5-23_13-45-57_No-00.png  "ECS-クラスタ設定"](https://qiita-image-store.s3.amazonaws.com/0/150903/f71eee4e-7d55-1b20-1b74-e92f61e5c7cb.png)

作成後、下記の通りクラスタが追加されていることを確認します。

![SnapCrab_NoName_2017-5-23_13-53-41_No-00.png  "ECS-クラスタ設定"](https://qiita-image-store.s3.amazonaws.com/0/150903/1c25c3a6-db79-c4aa-abde-86e7870590b7.png)

動的ポートマッピング使用時には、ALB間の通信において、EC2ホストに割当られるポートレンジを全て許可しておく必要があるため、クラスタ配下のEC2ホストに設定されたセキュリティグループを編集します。

***サービス > EC2 > インスタンス***にて当該EC2ホストを選択、『説明』タブのセキュリティグループのリンクをクリックします。

当該セキュリティグループの『インバウンド』タブにある『編集』を押下し、ソースを2で設定したALBのセキュリティグループとした全ポート許可のルールを追加します。

![SnapCrab_NoName_2017-5-23_15-2-55_No-00.png "ECS-クラスタ設定"](https://qiita-image-store.s3.amazonaws.com/0/150903/57073274-7663-260d-a1f9-9acdff95a7f0.png)


## ②. タスク定義の作成
コンテナの起動設定を定義するため、タスク定義を作成します。

***サービス > ECS > タスク定義***を選択し、『新しいタスクの定義』を押下します。

![SnapCrab_NoName_2017-5-23_14-18-40_No-00.png "ECS-タスク定義"](https://qiita-image-store.s3.amazonaws.com/0/150903/f9010c51-bf38-bc93-609b-d478bd22a6c9.png)

***タスク定義名***を入力し、『コンテナの追加』を押下します。

***コンテナの追加***画面にて、下記の項目を設定し、『追加』を押下します。

- コンテナ名
- イメージ
- メモリ制限 (割り当てるメモリ量)
- ポートマッピング (Auto Port Mapping利用時はホストのポート番号を0に設定)

![SnapCrab_NoName_2017-5-23_14-30-2_No-00.png "ECS-タスク定義"](https://qiita-image-store.s3.amazonaws.com/0/150903/5ca95034-ef25-83b7-dd26-51cfb1a6c358.png)

コンテナの追加後、『作成』を押下します。

![SnapCrab_NoName_2017-5-23_14-35-36_No-00.png "ECS-タスク定義"](https://qiita-image-store.s3.amazonaws.com/0/150903/8b247fa7-2a3f-0c54-ea57-08106578d002.png)

## ③. サービスの作成
はじめにECSサービス用のIAMロールを作成します。
***サービス > IAM > ロール***を選択し、『新しいロールの作成』を押下します。
ロールタイプでAmazon EC2 Container Service Roleを選択します。

![SnapCrab_NoName_2017-5-25_13-55-18_No-00.png "ECS-IAMロール作成"](https://qiita-image-store.s3.amazonaws.com/0/150903/4ad3e1b4-dd99-fb5c-0a43-65a8e67a8077.png)

ポリシーもそのままAmazonEC2ContainerServiceRoleをアタッチします。

![SnapCrab_NoName_2017-5-25_13-56-29_No-00.png "ECS-IAMロール作成"](https://qiita-image-store.s3.amazonaws.com/0/150903/8b2e090c-cc1d-7eb2-4865-a3d23b2b9a6e.png)

ロール名を入力し、『ロールの作成』を押下します。

![SnapCrab_NoName_2017-5-25_14-0-0_No-00.png "ECS-IAMロール作成"](https://qiita-image-store.s3.amazonaws.com/0/150903/b60f0d97-c150-1509-a6ed-c5503a9d1bdc.png)

次にECSにてサービスを作成していきます。
***サービス > ECS > クラスター***を選択し、『サービス』タブの『作成』を押下します。

![SnapCrab_NoName_2017-5-23_15-12-31_No-00![SnapCrab_NoName_2017-5-25_13-55-18_No-00.png "ECS-サービス作成"](https://qiita-image-store.s3.amazonaws.com/0/150903/745045c2-e48c-92eb-994b-4520d9cf97c3.png)
.png](https://qiita-image-store.s3.amazonaws.com/0/150903/596db206-f7fa-0d02-337d-8d94afa82533.png)

***サービスの作成***画面にて、下記の項目を設定し、『追加』を押下します。

- タスク定義(3-②で作成したタスク定義を指定)
- サービス名
- タスクの数(起動するコンテナ数を指定)

![SnapCrab_NoName_2017-5-23_15-16-50_No-00.png "ECS-サービス作成"](https://qiita-image-store.s3.amazonaws.com/0/150903/fcca8bc6-3897-ee40-aadc-577ac368ede3.png)

次に画面下部に移動し、『ELBの設定』を押下します。

![SnapCrab_N![SnapCrab_NoName_2017-5-23_15-12-31_No-00.png "ECS-サービス作成"](https://qiita-image-store.s3.amazonaws.com/0/150903/3d7e0f3f-09db-993e-d1b5-d8e3b1de9e56.png)
oName_2017-5-23_15-26-41_No-00.png "ECS-サービス作成"](https://qiita-image-store.s3.amazonaws.com/0/150903/c0f54381-ee79-d4a8-acc3-843348d6774e.png)

下記項目を設定します。

- ELBタイプ(Application Load Balancerを選択)
- サービス用のIAMロール(作成したECSサービス用のIAMロールを指定)
- ELB名(2で作成したALBを指定)

***負荷分散用のコンテナ***という項目では、3-②で作成したコンテナを選択し、『ELBの追加』を押下します。

下記項目を設定し、『保存』を押下します。

- リスナーポート(80:HTTPを指定)
- ターゲットグループ(2で作成したターゲットグループを指定)

![SnapCrab_NoName_2017-5-23_16-3-1_No-00.png "ECS-サービス作成"](https://qiita-image-store.s3.amazonaws.com/0/150903/19d06aca-0375-ff63-2d8a-4a7cbdb65426.png)

作成したサービス画面でタスクが3台『Running』ステータスで起動していることを確認します。

![SnapCrab_NoName_2017-5-23_16-9-10_No-00.png "ECS-サービス作成"](https://qiita-image-store.s3.amazonaws.com/0/150903/975179d9-9ba1-43f4-3a79-51a08ddfb85b.png)

# 4. 挙動確認
## ①. アクセス確認
***サービス > EC2 > ロードバランサ―***の『説明』タブにてALBのDNSを確認します。
ブラウザにhttp://"ALBのDNS"/phpinfo.phpを入力し、アクセスできることを確認します。

## ②. New Relicからの監視確認
NewRelicのAPM画面でコンテナ上で起動するアプリケーションが追加されたことを確認します。

![SnapCrab_NoName_2017-5-23_16-18-14_No-00.png  "New Relic画面"](https://qiita-image-store.s3.amazonaws.com/0/150903/82f26e3a-d50e-ce87-3623-4a13032ee03e.png)

当該アプリケーションを選択し、『Overview』画面下部に3台ホストが表示されることを確認します。

![SnapCrab_NoName_2017-5-23_16-15-50_No-00.png](https://qiita-image-store.s3.amazonaws.com/0/150903/af244ec8-02fb-fc02-2651-676bfca45d44.png)