ひとことで言うと#
本番またはステージング環境に計画的に障害を注入し、システムが想定通りに振る舞うか・チームが適切に対応できるかを検証するイベント型の演習。Netflixの Chaos Monkey を起点に発展したカオスエンジニアリングの実践手法であり、「壊れてから学ぶ」のではなく**「壊してから学ぶ」**アプローチをとる。
押さえておきたい用語#
- カオスエンジニアリング(Chaos Engineering)
- 本番システムに対して意図的に障害を発生させ、システムの振る舞いを観察・改善する工学的手法。定常状態の仮説を立て、実験で検証するサイエンティフィックなアプローチを取る。
- 定常状態仮説(Steady State Hypothesis)
- 「この障害が起きても、レイテンシはP99で500ms以下を維持する」のように、システムの正常な振る舞いを数値で定義した仮説。実験の成否判定に使う。
- 爆発半径(Blast Radius)
- 障害注入が影響する範囲のこと。まず爆発半径を小さく限定し、安全を確認してから徐々に拡大するのが鉄則。
- 障害注入(Fault Injection)
- サーバーの停止、ネットワーク遅延の追加、CPU負荷の人工的増大など、意図的に障害条件を作り出す行為。
- ゲームマスター(Game Master)
- ゲームデー当日にシナリオの進行・安全管理を担当する人。障害注入のタイミングと中止判断を行う。
カオスゲームデーの全体像#
こんな悩みに効く#
- 「冗長化しているから大丈夫」と言いつつ、本当にフェイルオーバーが動くか検証したことがない
- 障害が起きるたびに「想定外だった」と言い、根本対策が進まない
- インシデント対応がベテラン頼みで、新メンバーが初動を取れない
- SLOを設定したが、どこまでの障害なら守れるのか定量的にわかっていない
基本の使い方#
「この障害が起きても、システムは正常に振る舞い続ける」という仮説を数値で定義する。
- 例:「APIサーバー1台が停止しても、P99レイテンシは500ms以下を維持する」
- 例:「決済サービスが30秒間応答しなくても、注文画面はタイムアウトエラーを表示し、データ不整合は起きない」
- 仮説がないまま障害を注入すると「壊してみたけど何がわかったかわからない」状態になる
注入する障害の種類と、影響範囲を事前に定義する。
- 初回はステージング環境で実施し、本番は2回目以降にする
- 爆発半径: まず1台・1サービス・1リージョンなど最小単位から始める
- 中止基準: 「エラーレートが5%を超えたら即時中止」のように明確に決める
- ゲームマスターを任命し、中止判断の権限を持たせる
ゲームデー当日、シナリオに沿って障害を注入し、システムとチームの反応を記録する。
- ダッシュボード(Grafana、Datadog等)を全員で共有しながら進める
- アラートが期待通りに発報するか、オンコール体制が機能するかも検証対象
- チームの判断プロセス・コミュニケーションも観察ポイントにする
ゲームデー終了後、仮説の検証結果と発見した弱点をドキュメント化し、改善アクションを起票する。
- 仮説が正しかったか・覆されたかを記録する
- 検知が遅れた・アラートが鳴らなかったケースはモニタリング設定を修正する
- 次回のゲームデーで「前回の改善が効いているか」を再検証する
具体例#
月間取扱高8億円のECプラットフォーム。SRE 3名を含むインフラチーム8名で、初めてのカオスゲームデーを実施。
仮説: 「プライマリDBが停止しても、リードレプリカへのフェイルオーバーが30秒以内に完了し、決済処理のエラーレートは0.1%以下に収まる」
シナリオ: ステージング環境でプライマDBのインスタンスを停止
結果:
- フェイルオーバー自体は22秒で完了(仮説の30秒以内をクリア)
- しかし、決済サービスのコネクションプールが旧プライマリへの接続を保持し続け、フェイルオーバー後も3分間決済エラーが継続
- エラーレートは一時的に**12%**まで上昇(仮説は覆された)
改善アクション:
- コネクションプールのヘルスチェック間隔を60秒→5秒に短縮
- DNSキャッシュのTTLを300秒→30秒に変更
- 2回目のゲームデーで再検証し、エラーレートは**0.08%**に改善
この改善が2か月後の本番DB障害で効果を発揮。フェイルオーバー後の決済エラーは0件で、年末商戦のピーク時にもかかわらずSLOを維持できた。
70名規模のトラベルテック企業。航空券検索・ホテル検索・決済・通知の4マイクロサービスが稼働しており、外部API(航空会社API、ホテル在庫API)への依存度が高かった。
仮説: 「航空会社APIが500エラーを返し続けても、ホテル検索と決済は影響を受けず、航空券検索のみがエラーメッセージを表示する」
シナリオ: ステージング環境で航空会社APIのレスポンスを500エラーに差し替え
発見された問題:
- 航空会社APIのタイムアウト設定が30秒と長すぎ、スレッドプールが枯渇
- スレッドプール枯渇の影響がホテル検索にも伝播(同一サーバーで動いていたため)
- サーキットブレーカーが設定されていなかった
改善:
- 航空会社APIのタイムアウトを3秒に短縮
- サーキットブレーカー(Resilience4j)を導入し、5回連続失敗でオープン
- 航空券検索とホテル検索を別のコンテナに分離
2回目のゲームデーで同じシナリオを再実行し、ホテル検索への影響はゼロに。
エンジニア15名のBtoB SaaSスタートアップ。創業2年目で顧客が300社を超え、SLAに「月間稼働率99.9%」を明記した契約を結び始めていた。しかし、障害対応の経験者はCTO含め3名だけだった。
取り組み: 四半期に1回のカオスゲームデーを制度化。毎回異なるメンバーがインシデントコマンダー役を務めるローテーション方式にした。
1年間のゲームデー実績:
| 回 | シナリオ | 主な発見 |
|---|---|---|
| 第1回 | APIサーバー1台停止 | オートスケーリングの設定ミスで新インスタンスが起動しなかった |
| 第2回 | Redis障害 | セッション情報が全喪失し、全ユーザーが強制ログアウトされた |
| 第3回 | ネットワーク遅延200ms追加 | タイムアウト設定が未統一で、一部機能だけ動かなくなった |
| 第4回 | AZ(アベイラビリティゾーン)障害 | マルチAZ構成のつもりが、DBだけ単一AZだった |
成果(1年後):
- インシデント対応可能なメンバー: 3名 → 10名
- MTTR(平均復旧時間): 47分 → 18分
- SLA違反: 年3回 → 年0回
- 「障害は怖い」から「障害は練習できる」へチームのマインドセットが変化
やりがちな失敗パターン#
- いきなり本番で実施する — 初回から本番環境で障害を注入すると、予期しない影響で実際の障害を引き起こすリスクがある。まずステージングで十分に練習する
- 中止基準を決めない — 「どこまで壊れたらやめるか」を事前に決めないと、想定以上にシステムが壊れたときに判断が遅れる。数値で中止基準を定義し、ゲームマスターに権限を持たせる
- 振り返りをしない — ゲームデーを「イベント」として楽しんで終わり、改善アクションが起票されないケースが多い。翌日中にポストモーテムを書き、チケット化するところまでがゲームデー
- 同じシナリオを繰り返す — 毎回サーバー停止だけやっていると、ネットワーク障害やリソース枯渇など他の障害パターンへの備えが育たない。シナリオのバリエーションを計画的に広げる
まとめ#
カオスゲームデーは、計画的に障害を注入してシステムとチームの耐障害性を検証するイベント型演習である。定常状態仮説を立て、爆発半径を限定し、中止基準を決めたうえで実行するのが安全に進めるための三原則。大事なのは「壊すこと」ではなく、仮説が覆されたときに何を改善するかを明確にすること。四半期に1回でもゲームデーを続ければ、インシデント対応力は着実に底上げされ、「想定外」を「想定内」に変えていける。