ひとことで言うと#
「壊れるかもしれない」と心配するのではなく、意図的に本番環境で障害を起こしてシステムの弱点を見つけ出す実践手法。「障害は必ず起きる。だから自分たちの手で先に起こして備える」という考え方。
押さえておきたい用語#
- 定常状態(Steady State)
- システムが正常に動作しているときの定量的な指標。レイテンシp99、エラー率、スループットなど。実験の基準線になる。
- 爆風半径(Blast Radius)
- 障害注入が影響を及ぼす範囲のこと。最初は小さく始め、徐々に拡大するのが原則。
- キルスイッチ
- 実験中に問題が発生した際に即座に障害注入を停止する仕組み。すべてのカオス実験に必須。
- Game Day
- チーム全員で計画的にカオス実験を実施するイベント日。障害対応の訓練も兼ねる。
- Chaos Monkey
- Netflixが開発した本番環境のインスタンスをランダムに停止するツール。カオスエンジニアリングの代名詞。
カオスエンジニアリングの全体像#
こんな悩みに効く#
- 障害発生時にどこが壊れるか予測できず、いつも後手に回る
- 「このサーバーが落ちたらどうなる?」と聞かれても誰も答えられない
- 障害訓練をしたいが、何をどうすればいいかわからない
基本の使い方#
「正常な状態」を定量的に定義する。
- レイテンシ p99 < 200ms、エラー率 < 0.1% など
- ビジネスメトリクス(注文数/分など)も含める
- この数値が「実験後も維持されるはず」が仮説になる
ポイント: 「正常」が定義できなければ、「異常」も判断できない。
どんな障害を注入するかを計画する。
- サーバーの停止、ネットワーク遅延、CPU高負荷、ディスク満杯
- 外部サービスの応答遅延・エラー
- 爆風半径(blast radius)を小さく始める
ポイント: 最初は影響範囲が小さく、すぐ止められる実験から始める。
本番環境で障害を注入し、システムの挙動を観察する。
- ツール(Chaos Monkey, Gremlin, Litmus等)を活用する
- 実験中はダッシュボードとアラートを注視する
- 即座に中止できるキルスイッチを必ず用意する
ポイント: 本番でやるからこそ意味がある。ステージングでは見つからない問題がある。
仮説と実際の結果を比較し、改善点を洗い出す。
- 定常状態が維持された → 仮説通り(耐障害性が確認された)
- 定常状態が崩れた → 弱点が発見された。修正して再実験
- 発見した弱点はバックログに追加し、優先度をつけて修正する
ポイント: 「壊れた」は失敗ではなく成功。本番インシデントの前に見つけられたことに価値がある。
具体例#
仮説: 「決済サービスが3秒以上応答しなくなっても、注文のエラー率は1%以下に収まるはず(サーキットブレーカーが作動するため)」
実験: Gremlin を使って、決済サービスへのリクエストに5秒のレイテンシを注入。対象は全トラフィックの10%。
結果:
- サーキットブレーカーは正しく作動した
- しかし、ブレーカーOpen時のフォールバック処理にバグがあり、ユーザーに「null」が表示された
- また、ブレーカー状態変化のアラートがSlackに通知されていなかった
改善: フォールバック処理のバグを修正。ブレーカー状態変化のアラートを追加。2週間後に再実験 → 仮説通りの結果を確認。実際の障害が起きる前に2つの問題を発見・修正できた。
状況: 年間重大インシデント15件。障害発生時の対応が属人化しており、MTTR(平均復旧時間)が2時間。
Game Day導入:
- 四半期ごとに1日、チーム全員でカオス実験を実施
- 第1回: DBのプライマリをフェイルオーバーさせる → レプリカへの切り替えに5分かかることが判明
- 第2回: Redis障害 → キャッシュ消失時のDB負荷急増(Thundering Herd)を発見
- 第3回: 外部認証プロバイダーの障害 → ログインフォールバック未実装を発見
結果: 4回のGame Dayで合計11件の弱点を発見・修正。翌年のインシデント数が15件→6件に削減(60%減)。MTTRも2時間→35分に短縮した。
仮説: 「AWSの1つのAZ(Availability Zone)が完全に停止しても、サービスは自動的にフェイルオーバーし、レイテンシp99が500ms以下を維持するはず」
実験: AWS FIS(Fault Injection Simulator)で、AZ-1aの全EC2インスタンスを停止。ECS タスクも同AZのものを強制停止。
結果:
- ECSタスクは他AZで自動起動したが、起動に90秒かかった(想定は30秒)
- その間、残りのAZのタスクに負荷が集中し、p99が500ms→2,800msに悪化
- ALBのヘルスチェック間隔が30秒で、停止したタスクへのリクエストが30秒間失敗
改善: ECSの最小タスク数を各AZに均等配置するように変更。ALBヘルスチェック間隔を10秒に短縮。再実験でフェイルオーバー時間が90秒→15秒に改善、p99も350msで安定した。
やりがちな失敗パターン#
- いきなり大規模な障害を注入する — 全サーバーの50%を落とすような実験を最初からやると、本当のインシデントになる。爆風半径を小さく始め、徐々に拡大すること
- ステージング環境だけで実験する — ステージングと本番ではトラフィック量やデータ量が違うため、本番特有の問題が見つからない。本番で実施する覚悟を持つ(ただし段階的に)
- 発見した弱点を修正しない — 実験で問題を見つけても、バックログの優先度が低く放置される。カオス実験の知見をインシデント相当の優先度で扱うこと
- 実験結果を記録しない — 何を実験して何がわかったかを記録しないと、同じ実験を繰り返したり知見が共有されない。実験レポートをADRと同様にリポジトリに保存する
企業での実践例 — Netflix#
カオスエンジニアリングの起源は2010年、NetflixがデータセンターからAWSへの大規模移行を進める中で生まれた。クラウド環境ではインスタンスがいつ消えてもおかしくないという前提に立ち、エンジニアのGregory Orzellらが「本番環境のインスタンスをランダムに停止する」ツール、Chaos Monkeyを開発した。当初は社内でも反発があったが、Chaos Monkeyを日常的に動かすことで「障害に耐えられないサービスは、本番の障害が起きる前に壊れる」という文化が根付いた。
Netflixはその後、Chaos Monkeyを「Simian Army」と呼ばれるツール群に拡張している。Latency Monkey(遅延注入)、Chaos Gorilla(AZ全体の停止シミュレーション)、Chaos Kong(リージョン全体の障害シミュレーション)などを組み合わせ、全世界2億人以上のユーザーに影響する規模で継続的にカオス実験を行っている。2014年にはカオスエンジニアリングの専門チームを正式に設立し、コミュニティへのツール公開や「Principles of Chaos Engineering」の策定を主導した。Netflix技術ブログの報告によれば、カオス実験の導入以降、重大インシデントの発生時にも自動復旧が機能するケースが大幅に増え、ユーザーが障害を体感する頻度は大きく低下している。現在ではAmazon、Google、Microsoftなど主要テック企業がカオスエンジニアリングを実践しており、その出発点はNetflixの「壊れることを前提にシステムを設計する」という発想にある。
まとめ#
カオスエンジニアリングは 「障害は起きるもの」 という前提に立ち、先手を打ってシステムの弱点を発見する手法。定常状態を定義し、小さな実験から始め、発見した問題を確実に修正するサイクルを回すことが大事。怖がらず、でも慎重に始めよう。