カオスエンジニアリングツールGremlinでECS上のPHPアプリケーションにCPU負荷を注入してみた
カオスエンジニアリングという言葉自体は知っているが、実際に試したことがある方は少ないのではないでしょうか。
今回は、カオスエンジニアリングを簡単に実施できる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の導入支援を行っています。
気になった方はぜひ次回のウェビナーにご参加ください。