Gremlinを使って障害を注入してみる
こんにちは、森です。
昨年のAWS re:Invent 2018でも紹介されたカオスエンジニアリングツールの Gremlin というサービスを使って障害を注入し、 使用感を確かめたいと思います。
Gremlinとは
"Gremlin provides a hosted service for you to safely, securely, and simply run Chaos Experiments to prevent outages."
システムに障害を注入するためのホスティングサービスです。
以下の3つの原則をもとに、我々にChaos Experimentsを提供してくれます。
Safety
正確な故障テストで影響範囲を最小化。
安全に停止し、すぐに安定した状態にロールバックします。
Security
ルートアクセスを必要とせず、SSOとMFAを提供し、
定期的なサードパーティのセキュリティ監査を受けます。
Simplicity
数分で攻撃をインストールして実行します。ホストまたはコンテナで動作します。
インフラストラクチャ、アプリケーション両方に障害を注入できます。
システムの弱点を特定、問題になる前に修正することにより実際の障害時の被害を最小限に留める準備ができます。
Gremlinの使い方
公式ページに書かれているのは以下。
実験の計画をする
何がおかしいか仮説を立てる。
最小の範囲で実行する
簡単なテストを実行し、システムがどんな反応をするか確認する。
拡大縮小してから押しつぶす
テストを拡大、縮小しながら問題を特定し、そのあとそれを潰す
では、実際にチュートリアルを参考にし、使ってみようと思います。 今回はDockerを使います。
環境
mac OS Mojave | 10.14.6 |
Docker | 19.03.2, build 6a30dfc |
Gremlin | Free Plan |
料金に関してはこちらを参照。
インストール
公式手順を参考にインストールしていきます。
※ Dockerのインストールは割愛。
1. 測定用のコンテナを用意
vim Dockerfile
で以下の内容を保存します。
FROM alpine:latest RUN apk add --update htop && rm -rf /var/cache/apk/* ENTRYPOINT ["htop"]
Dockerfileを保存したディレクトリで以下を実行します。
docker build -t htop .
ビルドが完了したら
docker run -it --rm --pid=host htop
でコンテナを起動します。
このような画面になれば起動完了です。
終了させるときは qキーを押せば良いです。
2. テスト対象となるnginxのコンテナを用意
nginxで表示させるページを作成します。
mkdir -p ./docker-nginx/html cd ./docker-nginx/html vim index.html
以下の内容をペーストします。
<html> <head> <title>Docker nginx tutorial</title> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous" /> </head> <body> <div class="container"> <h1>Hello it is your container speaking</h1> <p>This nginx page was created by your Docker container.</p> <p>Now it’s time to create a Gremlin attack.</p> </div> </body> </html>
コンテナを作成します。
cd ../ docker run -l service=nginx --name docker-nginx -p 80:80 -d -v ${PWD}/docker-nginx/html:/usr/share/nginx/html nginx
docker ps -a
を実行すると
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS N AMES 4bd5dfa89e3a nginx "nginx -g 'daemon of…" About a minute ago Up About a minute 0.0.0.0:80->80/tcp docker-nginx
のように表示されるはずです。
3. Gremlinをコンテナにインストールする
- Gremlinのアカウントを作成(サインアップ)
- Gremlin Daemonのcredentialsを取得
する必要があります。
サインイン後、チーム設定の画面に遷移してください。
Team ID, Secret Keyが必要なため、控えておきます。
export GREMLIN_TEAM_ID={Team ID} export GREMLIN_TEAM_SECRET={Secret Key}
を実行し、環境変数に登録します。
公式のGremrin docker imageを使ってコンテナを起動します。
docker run -d --net=host \ --cap-add=NET_ADMIN --cap-add=SYS_BOOT --cap-add=SYS_TIME \ --cap-add=KILL \ -v $PWD/var/lib/gremlin:/var/lib/gremlin \ -v $PWD/var/log/gremlin:/var/log/gremlin \ -e GREMLIN_TEAM_ID="$GREMLIN_TEAM_ID" \ -e GREMLIN_TEAM_SECRET="$GREMLIN_TEAM_SECRET" \ gremlin/gremlin daemon
docker ps
で確認し、gremlinコンテナが起動したか確認します。
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c7528d9390e4 gremlin/gremlin "/entrypoint.sh daem…" 2 minutes ago Up 2 minutes friendly_benz 4bd5dfa89e3a nginx "nginx -g 'daemon of…" 3 hours ago Up 3 hours 0.0.0.0:80->80/tcp docker-nginx
gremlinのコンテナにログインし、コマンドが使える確認します。
※ CONTAINER IDは各自のものに置き換えてください。
docker exec -it c7528d9390e4 /bin/bash # コンテナ内で gremlin help attack-container # 以下のようにコンテナに攻撃種類がリストされます Type "gremlin help attack-container TYPE" for more details: blackhole # An attack which drops all matching network traffic cpu # An attack which consumes CPU resources io # An attack which consumes IO resources latency # An attack which adds latency to all matching network traffic memory # An attack which consumes memory packet_loss # An attack which introduces packet loss to all matching network traffic shutdown # An attack which forces the target to shutdown dns # An attack which blocks access to DNS servers time_travel # An attack which changes the system time. disk # An attack which consumes disk resources process_killer # An attack which kills the specified process exit
4. Gremlin CLIを使用して、Nginxコンテナに対してGremlinコンテナからCPU攻撃をする
Nginxコンテナのリソース状況を確認してみます。
※ CONTAINER IDは各自のものに置き換えてください
docker run -it --rm --pid=container:4bd5dfa89e3a htop
まだ攻撃を加えていないのでスカスカです。
では、以下のコマンドで攻撃を加えてみます。 ※ CONTAINER IDは各自のものに置き換えてください
1コアのデフォルト設定を使用して60秒間CPUを消費します。
docker run -d -it \ --cap-add=NET_ADMIN \ -e GREMLIN_TEAM_ID="${GREMLIN_TEAM_ID}" \ -e GREMLIN_TEAM_SECRET="${GREMLIN_TEAM_SECRET}" \ -v /var/run/docker.sock:/var/run/docker.sock \ gremlin/gremlin attack-container 4bd5dfa89e3a cpu
攻撃中のコンテナのリソースを確認してみます。
docker run -it --rm --pid=container:4bd5dfa89e3a htop
ご覧の通りgremlinからのcpu attackでCPUを消費していることがわかります。
gremlinの画面から確認してみると、以下のようにactiveな攻撃、終了済みの攻撃の履歴が見れます。
最後に
今回はgremlin cliを利用し、dockerコンテナにcpu攻撃を仕掛け、リソース状況を確認しました。 比較的簡単にできるかと思うので、カオスエンジニアリングのツールを検証している方がいればぜひやってみてください。
単体のコンテナに対して攻撃を仕掛けたのですが、次回以降は複数のコンテナ、また、分散システムなどにも攻撃をかける検証をしていきたいと思っております。
以上です