LoginSignup

This article is a Private article. Only a writer and users who know the URL can access it.
Please change open range to public in publish setting if you want to share this article with other users.

More than 5 years have passed since last update.

Terraform で ECS環境構築ハンズオン

Last updated at Posted at 2018-01-06

:notebook_with_decorative_cover: 概要

Terraform でAWS(ALB~ECS~RDS)環境構築します。
● 「ECS(Elastic Container Service)
● 「オートスケーリング&ヒーリング
● 「Docker
● 「Kong(APIゲートウェイOSS)」
 等に触れてみましょう。

image.png

:notebook_with_decorative_cover: このハンズオンで体験できること

  • 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のリソース状況を可視化してみよう

image.png

:notebook_with_decorative_cover: STEP ①: Terraformを実行し、今回のAWS環境を構築

(1)Terraformのインストール

ダウンロードサイトからダウンロード

●【Windowsの場合】
Download Terraform - Terraform by HashiCorp

image.png

ダウンロードした zip を解凍し、『terraform.exe』をパスの通っている場所(今回はC:\Windowsにしました)に配置します。

(私の場合は、Downloadsフォルダに解凍後、PowerShellを管理者権限で起動し、mvコマンドで移動させました・・)
image.png

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

●【Macの場合】
Download Terraform - Terraform by HashiCorp

image.png

ダウンロードした zip を解凍し、『terraform』をパスの通っている場所(今回は/usr/local/bin/にしました)に配置します。

image.png

terraform -v と入力し、バージョンが表示されればOK
image.png

(2)今回の環境を構築するTerraformファイル一式をダウンロード & 好きな場所に解凍

HaraShun/terraform-sample: terraform examples

(3)AWS アクセスキー/シークレットアクセスキーをセットし、Terraform実行

AWSマネジメントコンソールにて、terraform という名のキーペアを作成
image.png

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

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

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

terraform-kong-ecs フォルダへ移動
image.png

terraform init で初期化
image.png

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

:notebook: Terraformデプロイ1段階目

本来的には1発で構築できるべきなのですが、、ECSの性質上、
1段階目でservice 以外を構築し、
2段階目でservice をデプロイし、完成となります。

image.png

image.png

terraform apply -var-file="terraform.tfvars" で実行
image.png

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

:notebook: 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" で実行
image.png

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

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

ALBのDNS名/info.phpにアクセスし、ブラウザをリロードしてみましょう。
リロードするたびに、IPやIDが変わり、違うインスタンスにロードバランスされていることが確認できます。

image.png
image.png

:notebook_with_decorative_cover: 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コンテナへアタッチ

:notebook_with_decorative_cover: STEP ③: Apache Bench で負荷をかけるとコンテナがオートスケーリングする

今回は以下のDockerイメージを使って、ALB~ECSに負荷をかけます。
jig/docker-ab: Apache Benchmark Docker image

負荷をかける前のECSの状態
image.png

タスクが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:同時接続数を指定。

CPUが上昇し、
image.png

実行中のタスクが4つになりました。
image.png
image.png

:notebook_with_decorative_cover: STEP ④: 2台の内1台が削除されると自動的に1台新規追加される(オートヒーリング)

2台のECSインスタンスの内、1台を削除してみます。
image.png

すると数分後、1台立ち上がってきて、また2台となります。
(※下図においてインスタンス名が変わっていることは気にしないでください・・m(__)m)
image.png

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

:notebook_with_decorative_cover: 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/'

:notebook: 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

にアクセスしてみましょう。

:notebook_with_decorative_cover: STEP ⑥: (おまけ)早く終わって時間の余った人向け(その1)OSS『c3vis』でECSのリソース状況を可視化してみよう

ECSのリソース状況を可視化できるOSS c3vis というものがあります。
image

【手順(@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/ にアクセス

今回の場合だと下図のようになります。
【Memory】
image.png

【CPU】
image.png

:notebook_with_decorative_cover: 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のボタンを押すと、このようになります。

【go_gc_duration_seconds】
image.png

【http_requests_total】
image.png

監視対象インスタンス(今回は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

Prometheusにアクセスキー/シークレットアクセスキーをセットするため、ポリシー 「ReadOnlyAccessで」IAMユーザ作成
image.png

prometheus.ymlに以下のように追記(@NATインスタンス)

  - job_name: 'node'
    ec2_sd_configs:
      - region: ap-northeast-1
        access_key: APIKeyを書く
        secret_key: SECRET_KEYを書く
        port: 9100

image.png

全インスタンスを監視であれば上記で問題ありません。
ですが、監視対象をある程度条件で絞りたいケースがあります。
そんな時、Prometheus では relabel_configs でインスタンスの設定タグで絞る方法があります

Node Exporter 構築手順 + Prometheus からAWSオートスケール監視 - 長生村本郷Engineers'Blog

だそうな。

また ./promtool check config prometheus.yml での文法チェックも可能、とのこと。
1万台のサーバを監視できると話題のPrometheusをGrafanaと組み合わせて導入した話~vol2~ | Nagisaのすゝめ

Prometheusの再起動を行なうと、以下のように2台のECSサーバがターゲットとして新たに増えています。

image.png

【参考情報】
Prometheus 環境構築手順 - Qiita
Getting started | Prometheus
PrometheusでAmazon Linuxのメトリクスを収集する
【入門】PrometheusでサーバやDockerコンテナのリソース監視 | Pocketstudio.jp log3

:notebook_with_decorative_cover: 後片付け

terraform destroy -var-file="terraform.tfvars"
で一発削除できれば良いのですが、RDSがTerraformのバグ(?)により削除できません。

『Terraform ignores skip_final_snapshot so it's impossible to delete rds db instance · Issue #92 · terraform-providers/terraform-provider-aws · GitHub』

なので、マネジメントコンソール画面からRDSを削除したのち、
terraform destroy -var-file="terraform.tfvars"
を実行して今回の環境を削除します。

:notebook_with_decorative_cover: このハンズオンで触れていないこと

  • Terraform についての詳細説明
  • ECS についての詳細説明
  • ECR (Elastic Container Registry) にプライベートなDockerイメージを保存
  • カスタムなDockerイメージの作成(Dockerfileからのビルドやdocker commit等)

:notebook: 参考情報

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で登録する

0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up