この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは。AWS事業本部のKyoです。
みなさま、自動化はお好きでしょうか?カオスエンジニアリングにおいても自動化は重要なトピックの1つです。
今回はGetting started with Gremlin’s APIを元にAPIから障害注入を行ってみました。APIから障害注入を行うことでCI/CDとの統合が可能になり、障害注入の自動化が可能になります。
概要
今回は以下の2つを行っています。
- GUIから簡単にAPIの実行コマンドを取得する
- CLIから障害注入をやってみる
準備
- Gremlinアカウント(
CompanyName
,Team ID
,Secret Key
が必要) - Gremlin agentがインストールされたEC2インスタンス x1
各種情報の取得方法やGremlin agentのインストール、GUIからの障害注入のは方法などは以下のブログをご覧ください。
GUIから簡単にAPIの実行コマンドを取得する
curlを利用してAPIを叩くことは多いと思いますが、パラメータの設定等に手間取ることは少なくないのではないでしょうか。Gremlinのコンソールをポチポチするだけで、APIの実行コマンドが簡単に生成できます。
API実行コマンドの取得
まず、Gremlinのコンソールにログインし、左カラムよりAttacks
を選択します。
通常の攻撃と同様に対象と注入する障害を選択します。
Choose Hosts to target
から準備していたインスタンスを選択し、Choose a Gremlin
からCPU攻撃を120秒としました。
通常ならば、ここでUnleash Gremlin
のボタンをクリックするところですが、今回はその右側のGremlin API Examples
をクリックします。
すると、以下の画面が表示されるので、CURL Example
の右のCopy to clipboad
をクリックします。
以下のコマンドがクリップボードにコピーできました。
これを実行することで、先ほど選択した内容の障害注入を実施できます。パラメータにもCPU
や120
という文字列が確認できます。
curl -i -X POST 'https://api.gremlin.com/v1/attacks/new?teamId=<your team id>' \
-H 'Content-Type: application/json;charset=utf-8' \
-H 'Authorization: <your bearer>' \
-d '{"target":{"hosts":{"ids":["10.0.1.82"]},"type":"Exact"},"command":{"type":"cpu","commandType":"CPU","args":["-l","120","-c","1"]}}'
同様の方法で、CPU攻撃以外についてもGUIからAPIの実行コマンドを生成することが可能です。
障害注入の実施と確認
障害注入を実行し、確認します。 Activeとして表示されています。
詳細を表示します。
念のため、対象のEC2にもログインしtop
コマンドを実行してみました。
gremlinによってCPUリソースが消費されていることが確認できました。
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2637 gremlin 20 0 23400 5872 5500 S 99.3 0.6 1:00.27 gremlin
1 root 20 0 159820 8928 6568 S 0.0 0.9 0:02.77 systemd
2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd
3 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 rcu_gp
4 root 0 -20 0 0 0 I 0.0 0.0 0:00.00 rcu_par_gp
5 root 20 0 0 0 0 I 0.0 0.0 0:00.07 kworker/0:0-eve
〜〜以下略〜〜
CLIから障害注入をやってみる
自動化のためには一連の動作がCLIで完結する必要があります。
認証
以下のコマンドでBearer
を取得します。
curl -X POST --header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'email=gremlin@gremlin.com' \
--data-urlencode 'password=P@ssw0rd1!' \
--data-urlencode 'companyName=Chaos' \
'https://api.gremlin.com/v1/users/auth'
コンソールへのログインにMFAを利用している場合は、下記のように-data-urlencode
が必要です。
curl -X POST --header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'email=gremlin@gremlin.com' \
--data-urlencode 'password=changeit' \
--data-urlencode 'token=000000' \
'https://api.gremlin.com/v1/users/auth/mfa/auth?getCompanySession=true'
レスポンスとして以下のようなJSONが返ってきます(一部の結果はダミーです)。
[
{
"company_id": "<company_id>",
"company_is_alfi_enabled": true,
"expires_at": "2020-07-17T01:58:15.357Z",
"header": "Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"identifier": "<email>",
"org_id": "<org_id>",
"org_name": "<org_name>",
"renew_token": "<renew_token>",
"token": "<token>",
"tier": "Enterprise",
"roles": [
"<role1>",
"<role2>"
],
"privileges": [
"<privileges1>",
"<privileges2>"
],
"company_name": "<company_name>",
"last_login": "2020-06-21T09:28:53.820Z"
}
]
所属している組織の数だけの情報が含まれます。
bearer
を利用するため、header
の値を取得し、変数化しておきます。
export bearertoken="Bearer XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
障害注入
先ほどと同様にCPU攻撃を120秒行います。今回ターゲットはランダムにしてあります。
curl -X POST \
--header "Content-Type: application/json" \
--header "Authorization: $bearertoken" \
https://api.gremlin.com/v1/attacks/new?teamId=<your team id> \
--data '
{
"command": { "type": "cpu", "args": ["-c", "1", "--length", "120"] },
"target": { "type": "Random" }
}'
上記を実行すると実行IDが返されます。これをもとに、障害注入状態の確認を行えます。
障害注入状態の確認
以下のコマンドで障害注入の状態を確認することが可能です。
curl -X GET "https://api.gremlin.com/v1/attacks/<実行ID>?teamId=<your team id>" \
--header "Authorization: $bearertoken" \
-H "accept: application/json"
以下のようなJSONが返されます(一部の結果はダミーです)。
{
"total_clients": 1,
"infra_target": {
"resolvedHosts": [
"ip-192-168-9-36.ap-northeast-1.compute.internal"
],
"targetType": "Host",
"strategy": {
"allHosts": false,
"count": 1,
"type": "RandomCount",
"allContainers": false
},
"strategyType": "Random"
},
"client_metrics_enabled_count": 1,
"target_type": "Host",
"version": 9,
"targets": [
"ip-192-168-9-36.ap-northeast-1.compute.internal"
],
"org_id": "<org_id>",
"args": [
"cpu",
"-c",
"1",
"--length",
"120"
],
"created_at": "2020-07-16T14:26:27.210Z",
"create_source": "Api",
"stage": "Successful",
"execution_stage_summary": {
"Successful": 1
},
"infra_command": {
"commandType": "CPU",
"commandArgs": {
"allCores": false,
"cores": 1,
"length": 120,
"percent": 100
}
},
"stage_lifecycle": "Complete",
"guid": "<実行ID>",
"create_user": "<email>",
"start_time": "2020-07-16T14:26:27.210Z",
"end_time": "2020-07-16T14:28:40.105Z",
"updated_at": "2020-07-16T14:28:40.105Z",
"kind": "Api"
念のため、コンソールも見てみます。
こちらでも障害注入の成功が確認できました!
Appendix
APIリファレンスは以下にあります。
おわりに
今回はGremlin APIを利用して、GUIから簡単にAPIの実行コマンドを取得し、CLIから障害注入を実施してみました。
カオスエンジニアリングの原則の詳細原則の1つ、「継続的に実行する検証の自動化」 に一歩近づけたのではないでしょうか。
手作業による検証は、手間がかかり、最終的には長続きしません。実験を自動化し、継続して実行します。カオスエンジニアリングは、オーケストレーションと分析の両方を行うためにシステムを自動化します。
以上、何かのお役に立てれば幸いです。