概要
Terraform でAWS(ALB~ECS~RDS)環境構築します。
● 「ECS(Elastic Container Service)」
● 「オートスケーリング&ヒーリング」
● 「Docker」
● 「Kong(APIゲートウェイOSS)」
等に触れてみましょう。
このハンズオンで体験できること
- STEP ①: Terraform でAWS(ALB~ECS~RDS)環境構築
- STEP ②: DockerがインストールされたEC2 インスタンス上(@NATインスタンス)にて、いろいろなコンテナをpullして動かしてみる
- STEP ③: Apache Bench で負荷をかけるとコンテナがオートスケーリングする
- STEP ④: 2台の内1台が削除されると自動的に1台新規追加される(オートヒーリング)
- STEP ⑤: APIゲートウェイOSS 『Kong』 にてAPIを作成してみる
- STEP ⑥: 【おまけ】早く終わって時間の余った人向け(その1)OSS『c3vis』でECSのリソース状況を可視化してみよう
- STEP ⑦: 【おまけ】早く終わって時間の余った人向け(その2)OSS『Prometheus』でECSのリソース状況を可視化してみよう
STEP ①: Terraformを実行し、今回のAWS環境を構築
(1)Terraformのインストール
ダウンロードサイトからダウンロード
●【Windowsの場合】
Download Terraform - Terraform by HashiCorp
ダウンロードした zip を解凍し、『terraform.exe』をパスの通っている場所(今回はC:\Windowsにしました)に配置します。
(私の場合は、Downloadsフォルダに解凍後、PowerShellを管理者権限で起動し、mvコマンドで移動させました・・)

PowerShell、(またはgitbash等)を立ち上げて、terraform -v と入力し、バージョンが表示されればOK

●【Macの場合】
Download Terraform - Terraform by HashiCorp
ダウンロードした zip を解凍し、『terraform』をパスの通っている場所(今回は**/usr/local/bin/**にしました)に配置します。
terraform -v と入力し、バージョンが表示されればOK

(2)今回の環境を構築するTerraformファイル一式をダウンロード & 好きな場所に解凍
HaraShun/terraform-sample: terraform examples
(3)AWS アクセスキー/シークレットアクセスキーをセットし、Terraform実行
AWSマネジメントコンソールにて、terraform という名のキーペアを作成

**terraform-sample/terraform-kong-ecs**フォルダに移動し、
variables.tf ファイルにて作成したキーペア名 terraform を明記

**terraform_copy.tfvars**ファイルを → terraform.tfvars ファイルにリネームし、IAM『AdministratorAccess』ポリシー権限のアクセスキー&シークレットアクセスキーをセット

NAT SGに現在のIPアドレスからの22番ポートインバウンド許可を開ける

↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓

terraform plan -var-file="terraform.tfvars" で実行計画を見る

Terraformデプロイ1段階目
本来的には1発で構築できるべきなのですが、、ECSの性質上、
1段階目でservice 以外を構築し、
2段階目でservice をデプロイし、完成となります。
terraform apply -var-file="terraform.tfvars" で実行

以下のように**「Apply complete! Resources: XX added, 0 changed, 0 destroyed.」**となればOK

Terraformデプロイ2段階目
ecs.tf の
- 12~26行目(ECS Serviceに関する部分)
- 66~100行目(AutoScaling Alarmに関する部分)
- 107~154行目(AutoScaling Policyに関する部分)
をコメントアウトします。
instances.tf の
- 82~114行目(EC2 AutoScaling Alarmに関する部分)
をコメントアウトします。
terraform apply -var-file="terraform.tfvars" で実行

以下のように**「Apply complete! Resources: XX added, 0 changed, 0 destroyed.」**となればOK

[ALBのDNS名]/index.phpにアクセスしてみましょう。
以下のようなPHP info の画面が表示されます。

**ALBのDNS名/info.php**にアクセスし、ブラウザをリロードしてみましょう。
リロードするたびに、IPやIDが変わり、違うインスタンスにロードバランスされていることが確認できます。
STEP ②: DockerがインストールされたEC2 インスタンス上(NATインスタンス)にて、いろいろなコンテナをpullして動かしてみる
マネジメントコンソールにて、NAT インスタンスのIPを確認し、SSHログイン
(1)Swagger イメージの pullと起動
$ docker pull swaggerapi/swagger-ui
$ docker run -d -p 80:8080 swaggerapi/swagger-ui
**http://<NATインスタンスIP>/**にアクセスしてみましょう。
(2)Apache イメージの pullと起動:
$ docker pull httpd
$ docker run -d -p 8080:80 httpd
**http://<NATインスタンスIP>:8080/**にアクセスしてみましょう。
(3)Nginx イメージの pullと起動
$ docker pull nginx
$ docker run -d -p 9000:80 nginx
**http://<NATインスタンスIP>:9000/**にアクセスしてみましょう。
(4)この後利用するApache Bench & Kong イメージの pull
$ docker pull jordi/ab
$ docker pull kong
(5)以下のDockerコマンドを打ってみよう
・docker images:pullしたイメージの一覧確認
・docker ps:起動中Dockerコンテナプロセスの確認
・docker ps -a:(停止したものも含めた)全Dockerコンテナプロセスの確認
・docker stop <コンテナID>:起動中Dockerコンテナの停止
・docker exec -it <コンテナID> bash:起動中Dockerコンテナへアタッチ
STEP ③: Apache Bench で負荷をかけるとコンテナがオートスケーリングする
今回は以下のDockerイメージを使って、ALB~ECSに負荷をかけます。
『jig/docker-ab: Apache Benchmark Docker image』
タスクが2つ動いています。
NATインスタンスから以下のコマンドで、ALB~ECSに負荷をかけます。
$ docker run -d -p 8080:8080 jordi/server:http
$ docker run --rm jordi/ab ab -k -c 100 -n 100000 http://[ALBのDNS]:80/
(※Apache Bench コマンド補足)
-n:Totalで発行するリクエスト数を指定。
-c:同時接続数を指定。
STEP ④: 2台の内1台が削除されると自動的に1台新規追加される(オートヒーリング)
すると数分後、1台立ち上がってきて、また2台となります。
(※下図においてインスタンス名が変わっていることは気にしないでください・・m(__)m)

これはAuto Scalingグループによって、台数が常に以下のようになるように設定されているためです。

STEP ⑤: APIゲートウェイOSS 『Kong』 にてAPIを作成してみる
まずはNAT インスタンス上からKong DBの初期化マイグレーションやAPI作成等をします。
● Kong DB作成(@NATインスタンス)
$ docker run --rm \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=[RDS endpoint(XXX.YYY.ap-northeast-1.rds.amazonaws.com)]" \
-e "KONG_PG_PASSWORD=kongkong" \
kong kong migrations up
● Admin用Kong起動(@NATインスタンス)
$ docker run -d --name kong \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=[RDS endpoint(XXX.YYY.ap-northeast-1.rds.amazonaws.com)]" \
-e "KONG_PG_PASSWORD=kongkong" \
-e "KONG_ADMIN_LISTEN=0.0.0.0:8001" \
-p 8000:8000 \
-p 8001:8001 \
kong
● API作成(@NATインスタンス)
【Mockbinというページを返すAPI】
$ curl -i -X POST \
--url http://localhost:8001/apis/ \
--data 'uris=/mockbin' \
--data 'name=mockbin' \
--data 'upstream_url=http://mockbin.org'
【クライアントのIPアドレスを返すAPI】
$ curl -i -X POST \
--url http://localhost:8001/apis/ \
--data 'uris=/ip' \
--data 'name=ip' \
--data 'upstream_url=http://ip.jsontest.com/'
【クライアントのヘッダーを返すAPI】
$ curl -i -X POST \
--url http://localhost:8001/apis/ \
--data 'uris=/headers' \
--data 'name=headers' \
--data 'upstream_url=http://headers.jsontest.com/'
【日次と時間を返すAPI】
$ curl -i -X POST \
--url http://localhost:8001/apis/ \
--data 'uris=/date' \
--data 'name=date' \
--data 'upstream_url=http://date.jsontest.com/'
Kong Serviceのデプロイ
① ecs.tfファイルの30~44行目のコメントアウトを外す
② kong.json.backupファイルを → kong.json とファイル名を変更し、KONG_PG_HOST の値にRDSのエンドポイントを設定
③ terraform apply -var-file="terraform.tfvars" 実行
- http://[ALBエンドポイント]:8000/mockbin
- http://[ALBエンドポイント]:8000/ip
- http://[ALBエンドポイント]:8000/headers
- http://[ALBエンドポイント]:8000/date
にアクセスしてみましょう。
STEP ⑥: (おまけ)早く終わって時間の余った人向け(その1)OSS『c3vis』でECSのリソース状況を可視化してみよう
ECSのリソース状況を可視化できるOSS 『c3vis』 というものがあります。

#####【手順(@NATインスタンス)】
- READEMEに書かれたIAMポリシー&ロールを作成し、NATインスタンスにアタッチ(EC2の停止→再起動必要)
- Nodeのインストール
### 1. 依存パッケージのインストール
$ sudo yum install -y gcc-c++ make
### 2. node.js v6 をインストール(安定版の最新版)
$ curl --silent --location https://rpm.nodesource.com/setup_6.x | sudo bash -
### 3. node.jsのインストール
$ sudo yum install -y nodejs
- 『c3vis』をダウンロードして、解凍、ルートフォルダにリージョン名を書いた
aws_config.json配置
### 1. DownLoad
$ wget https://github.com/ExpediaDotCom/c3vis/archive/master.zip
### 2. unzip
$ unzip master.zip
### 3. ルートフォルダにリージョン名を書いたaws_config.json配置
$ cd c3vis-master/
$ echo '{
"region": "ap-northeast-1"
}' >aws_config.json
-
npm install実行 -
npm start実行 -
http:[NATインスタンスのIPアドレス]:3000/にアクセス
STEP ⑦: (おまけ)早く終わって時間の余った人向け(その2)OSS『Prometheus』でECSのリソース状況を可視化してみよう
Prometheusのダウンロード、解凍、起動(@NATサーバ)
$ wget https://github.com/prometheus/prometheus/releases/download/v2.0.0/prometheus-2.0.0.linux-amd64.tar.gz
$ tar xvfz prometheus-*.tar.gz
$ cd prometheus-*
$ ./prometheus --config.file=prometheus.yml
[Graph]タブ-> 監視対象のグラフを適当に選びExecuteのボタンを押すと、このようになります。
監視対象インスタンス(今回は2台のECSサーバ)に「node exporter」「container_exporter」をインストール
$ curl -OL https://github.com/prometheus/node_exporter/releases/download/v0.15.2/node_exporter-0.15.2.linux-amd64.tar.gz
$ tar xvfz node_exporter-*.tar.gz
$ cd node_exporter-*
[以下はログアウトしても「./node_exporter」を起動させ続けるコマンド]
$ nohup ./node_exporter &
$ (Ctrl+C が必要かも)
$ disown %1
【参考】
First steps | Prometheus
[実行中のコマンドをバックグランドに切り替える - Qiita] (https://qiita.com/strsk/items/1c971c1b7b3e9b08a445)
Prometheusにアクセスキー/シークレットアクセスキーをセットするため、ポリシー 「ReadOnlyAccessで」IAMユーザ作成

prometheus.ymlに以下のように追記(@NATインスタンス)
- job_name: 'node'
ec2_sd_configs:
- region: ap-northeast-1
access_key: APIKeyを書く
secret_key: SECRET_KEYを書く
port: 9100
全インスタンスを監視であれば上記で問題ありません。
ですが、監視対象をある程度条件で絞りたいケースがあります。
そんな時、Prometheus では relabel_configs でインスタンスの設定タグで絞る方法があります
[Node Exporter 構築手順 + Prometheus からAWSオートスケール監視 - 長生村本郷Engineers'Blog] (http://kenzo0107.hatenablog.com/entry/2017/01/25/154144)
だそうな。
また ./promtool check config prometheus.yml での文法チェックも可能、とのこと。
1万台のサーバを監視できると話題のPrometheusをGrafanaと組み合わせて導入した話~vol2~ | Nagisaのすゝめ
Prometheusの再起動を行なうと、以下のように2台のECSサーバがターゲットとして新たに増えています。
【参考情報】
Prometheus 環境構築手順 - Qiita
Getting started | Prometheus
PrometheusでAmazon Linuxのメトリクスを収集する
【入門】PrometheusでサーバやDockerコンテナのリソース監視 | Pocketstudio.jp log3
後片付け
terraform destroy -var-file="terraform.tfvars"
で一発削除できれば良いのですが、RDSがTerraformのバグ(?)により削除できません。
なので、マネジメントコンソール画面からRDSを削除したのち、
terraform destroy -var-file="terraform.tfvars"
を実行して今回の環境を削除します。
このハンズオンで触れていないこと
- Terraform についての詳細説明
- ECS についての詳細説明
- ECR (Elastic Container Registry) にプライベートなDockerイメージを保存
- カスタムなDockerイメージの作成(Dockerfileからのビルドやdocker commit等)
参考情報
dockerfile - denied: requested access to the resource is denied : docker - Stack Overflow
Apache Benchでサクッと性能テスト - Qiita
ec2(amazon linux)にnode.jsを導入 - Qiita
TerraformでEC2のインスタンスプロファイルを生成する - Qiita
(CentOS6まで)自作のサービスをchkconfigで登録する





















