この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
カオスエンジニアリングという言葉自体は知っているが、実際に試したことがある方は少ないのではないでしょうか。
今回は、カオスエンジニアリングを簡単に実施できるGremlinというツールでECS上のアプリケーションに障害を注入していきたいと思います。
なお、こちらは公式ブログを参考にしています。
構成図
せっかちな人へ
GitHubにソースコードを上げているのでそちらをご確認ください。
PHPサンプルアプリケーションの作成
Laravelチュートリアル – 掲示板を作成してみようを参考にしました。
laravel new laravel-bbs
でlaravel-bbs
配下に適当なアプリケーションを作成しています。
$ tree laravel-bbs -L 1
laravel-bbs
├── app
├── artisan
├── bootstrap
├── composer.json
├── composer.lock
├── config
├── database
├── package.json
├── phpunit.xml
├── public
├── README.md
├── resources
├── routes
├── server.php
├── storage
├── tests
├── vendor
└── webpack.mix.js
本題と逸れるため説明は割愛します。
出来上がったのはこんな感じのサイト。 書き込みはできないリードオンリーのサイトです。
Dockerfileの作成
docker
配下にnginx
とphp
用のDockerfileをそれぞれ作成します。
$ tree docker -L 2
docker
├── nginx
│ ├── default.conf
│ └── dockerfile
└── php
├── dockerfile
└── php.ini
また、docker-compose up
で起動できるようdocker-compose.yml
も作成しておきます。
それぞれの設定はソースコードを確認してください。
ローカルでGremlinを試してみる
先ほど作成したアプリケーションをdocker-compose up
で起動します
$ docker-compose up
Starting php ... done
Starting nginx ... done
Attaching to php, nginx
...
次に、こちらを参考Gremlinコンテナをサイドカーとして起動します。
- 環境変数をセット
export GREMLIN_TEAM_ID=<your-team-id>
export GREMLIN_TEAM_SECRET=<your-team-secret>
- Gremlinコンテナの起動
※ 少し改良しています
$ docker run -d --rm --net=host \
--name gremlin-deamon \
--cap-add=NET_ADMIN --cap-add=SYS_BOOT --cap-add=SYS_TIME \
--cap-add=KILL \
-v /tmp/gremlin/var/lib/gremlin:/var/lib/gremlin \
-v /tmp/gremlin/var/log/gremlin:/var/log/gremlin \
-v /var/run/docker.sock:/var/run/docker.sock \
-e GREMLIN_TEAM_ID="$GREMLIN_TEAM_ID" \
-e GREMLIN_TEAM_SECRET="$GREMLIN_TEAM_SECRET" \
gremlin/gremlin daemon
Gremlinの管理画面で、先ほど起動したPHPアプリケーションがターゲットに登録されているのが確認してみます。
ためしにホストの1コアに対してCPU利用率を100%まで上げてみます。
htop
コマンドで見るとちゃんと動いていることが確認できます。
ECS用のCloudFormationの作成
実際にECS上で動かすため、CloudFormationのテンプレートを作成していきます。
$ tree cloudformation -L 2
cloudformation
├── template-for-ecr.yml
└── template.yml
template-for-ecr.yml
がECR用、template.yml
がその他もろもろの設定です。
長くなるので、最終的なテンプレートはソースコードを確認してください。
インフラとアプリケーションのデプロイ
まずは、template-for-ecr.yml
をデプロイします。
aws cloudformation deploy \
--template-file cloudformation/template-for-ecr.yml \
--stack-name php-repo-stack
つづいて、DockerイメージをビルドしてECRにPUSHします。
ACCOUNT_ID=$(aws sts get-caller-identity --output text --query 'Account')
aws ecr get-login-password | docker login --username AWS --password-stdin ${ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com
docker-compose build nginx php
docker tag arai-nginx:latest ${ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/php-app-repo/nginx:latest
docker tag arai-php:latest ${ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/php-app-repo/php:latest
docker push ${ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/php-app-repo/nginx:latest
docker push ${ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/php-app-repo/php:latest
さいごに、template.yml
をデプロイします。
aws cloudformation deploy \
--template-file cloudformation/template.yml \
--stack-name php-app-stack \
--parameter-overrides \
GremlinTeamId=${GREMLIN_TEAM_ID} \
GremlinTeamSecret=${GREMLIN_TEAM_SECRET} \
--capabilities CAPABILITY_NAMED_IAM
ALBのDNS名からサイトが表示されるか確認します。
Gremlinで攻撃する
Auto Scaling Groupsの設定でCPU利用率が50%以上を超えるとスケールアップするように設定しているので、CPU負荷をかけてちゃんと動作するのか試していきます。
しばらくするとCPU利用率が99%ぐらいになっているのが確認できます。
その後、ECSインスタンスが増えて、新しいタスクが起動しているのが確認できます。
おわりに
クラスメソッドではGremlinの導入支援を行っています。
気になった方はぜひ次回のウェビナーにご参加ください。