カオスエンジニアリング入門 - 本番環境での障害実験で耐障害性を高める

2026.04.10

公式ドキュメント

この記事の要点

カオスエンジニアリングは本番に意図的に障害を注入して耐障害性を検証する規律
5つの原則: 定常状態の仮説/現実的障害/本番環境/自動化/影響最小化
• 監視・アラート・ブレームレス文化が前提条件として必要

カオスエンジニアリング(Chaos Engineering)は、本番システムに意図的に障害を注入し、予期しない条件下での耐障害性を検証・改善する規律です。Netflix が2010年代初頭に提唱し、現代の SRE(Site Reliability Engineering)プラクティスの中核となっています。本記事では、カオスエンジニアリングの原則から実践、ツール、落とし穴までを体系的に解説します。

概要

カオスエンジニアリングとは

Chaos Engineering is the discipline of experimenting on a system in order to build confidence in the system’s capability to withstand turbulent conditions in production. — Principles of Chaos Engineering

「壊してみて、本当に壊れないか確かめる」というアプローチです。障害は避けるものではなく、積極的に発生させて学習します。

flowchart LR
    Design["耐障害性設計<br/>(Circuit Breaker, Retry等)"]
    Believe["動くはず<br/>という仮定"]
    Chaos["カオス実験<br/>(障害注入)"]
    Learn["学習<br/>(実際の挙動)"]
    Improve["改善<br/>(設計修正)"]

    Design --> Believe
    Believe --> Chaos
    Chaos --> Learn
    Learn --> Improve
    Improve --> Design

歴史

  • 2010: Netflix が Chaos Monkey を社内で運用開始
  • 2012: Chaos Monkey をオープンソース化
  • 2014: Netflix の Simian Army(Chaos Gorilla, Latency Monkey など)公開
  • 2015: “Principles of Chaos Engineering” 発表
  • 2016: Chaos Monkey 2.0、Spinnaker 統合
  • 2018: CNCF プロジェクトとして Chaos Mesh、LitmusChaos 登場
  • 2020s: AWS FIS、Gremlin など商用ソリューション成熟

原則・定義

Principles of Chaos の 5 原則

  1. 定常状態の仮説を立てる(Build a hypothesis around steady-state behavior)

    • システムの「正常」を定量的指標で定義する(例: エラー率、レイテンシ)
  2. 現実世界の事象を多様に用いる(Vary real-world events)

    • サーバクラッシュ、ネットワーク遅延、ハードウェア故障を模擬
  3. 本番環境で実験する(Run experiments in production)

    • ステージング環境では再現できない問題がある
  4. 実験を継続的に自動化する(Automate experiments to run continuously)

    • 一度きりでなく、常時実験を繰り返す
  5. 影響範囲を最小化する(Minimize blast radius)

    • 事故にならないよう、影響を制御する

カオス実験の定式化

カオス実験は次の4要素で構成されます: 定常状態指標 + 仮説 + 障害注入 + 観測

interface ChaosExperiment {
  name: string;
  steadyStateHypothesis: {
    title: string;
    probes: Probe[];  // 正常状態の測定
  };
  method: Action[];   // 障害の注入
  rollback: Action[]; // 実験後の復旧
}

interface Probe {
  type: "http" | "prometheus" | "cloudwatch";
  tolerance: unknown; // 許容範囲
}

構成要素

カオス実験のフェーズ

flowchart TB
    Plan["1. 計画<br/>仮説・指標を定義"]
    Baseline["2. ベースライン測定<br/>定常状態を確認"]
    Inject["3. 障害注入<br/>最小の影響範囲で開始"]
    Observe["4. 観測<br/>仮説と比較"]
    Analyze["5. 分析<br/>逸脱を特定"]
    Fix["6. 改善<br/>設計/実装修正"]
    Scale["7. 影響範囲拡大<br/>次の実験へ"]

    Plan --> Baseline --> Inject --> Observe --> Analyze --> Fix --> Scale
    Scale -.-> Plan

障害の種類(Failure Modes)

カテゴリ
インフラ障害VM停止、ディスク故障、AZ全停止
ネットワーク遅延、パケットロス、DNS障害、分断
アプリケーションプロセスクラッシュ、OOM、CPU消費
依存サービスサードパーティAPI停止、DBスローダウン
データレプリケーション遅延、データ破損
人的誤デプロイ、設定ミス

実装例

1. chaostoolkit による実験定義

{
  "version": "1.0.0",
  "title": "orders API remains available when user-service has latency",
  "description": "Inject 500ms latency into user-service calls",
  "steady-state-hypothesis": {
    "title": "API p99 latency under 1s and error rate under 1%",
    "probes": [
      {
        "type": "probe",
        "name": "orders-api-healthy",
        "tolerance": 200,
        "provider": {
          "type": "http",
          "url": "https://api.example.com/orders/health",
          "timeout": 3
        }
      }
    ]
  },
  "method": [
    {
      "type": "action",
      "name": "add-latency-to-user-service",
      "provider": {
        "type": "process",
        "path": "tc",
        "arguments": ["qdisc", "add", "dev", "eth0", "root", "netem", "delay", "500ms"]
      },
      "pauses": { "after": 60 }
    }
  ],
  "rollbacks": [
    {
      "type": "action",
      "name": "remove-latency",
      "provider": {
        "type": "process",
        "path": "tc",
        "arguments": ["qdisc", "del", "dev", "eth0", "root"]
      }
    }
  ]
}

2. Chaos Mesh(Kubernetes)による Pod 削除実験

apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata:
  name: pod-failure-example
  namespace: chaos-testing
spec:
  action: pod-failure
  mode: fixed-percent
  value: "25"  # 25% の Pod に影響
  duration: "60s"
  selector:
    namespaces:
      - production
    labelSelectors:
      app: order-service
  scheduler:
    cron: "@every 6h"  # 6時間ごとに実行

3. ネットワーク分断実験

apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
  name: partition-payment-service
spec:
  action: partition
  mode: all
  selector:
    labelSelectors:
      app: order-service
  direction: to
  target:
    mode: all
    selector:
      labelSelectors:
        app: payment-service
  duration: "5m"

4. AWS Fault Injection Service(FIS)

{
  "description": "Stop 50% of EC2 instances in prod",
  "targets": {
    "Instances": {
      "resourceType": "aws:ec2:instance",
      "resourceTags": { "Environment": "production" },
      "selectionMode": "PERCENT(50)"
    }
  },
  "actions": {
    "StopInstances": {
      "actionId": "aws:ec2:stop-instances",
      "parameters": { "duration": "PT5M" },
      "targets": { "Instances": "Instances" }
    }
  },
  "stopConditions": [
    {
      "source": "aws:cloudwatch:alarm",
      "value": "arn:aws:cloudwatch:us-east-1:123456789012:alarm:HighErrorRate"
    }
  ],
  "roleArn": "arn:aws:iam::123456789012:role/FISRole"
}

stopConditions により、CloudWatch アラームがトリガーされたら実験を自動停止 = 影響範囲の制御。

5. アプリケーションレベルの障害注入(TypeScript)

class ChaosMiddleware {
  constructor(
    private readonly config: {
      enabled: boolean;
      errorRate: number;    // 0.0 - 1.0
      latencyMs: number;
      allowedEndpoints: string[];
    },
  ) {}

  async handle(
    req: Request,
    next: () => Promise<Response>,
  ): Promise<Response> {
    if (!this.config.enabled || !this.shouldApply(req)) {
      return next();
    }

    // ランダム遅延
    if (this.config.latencyMs > 0) {
      await new Promise((r) => setTimeout(r, this.config.latencyMs));
    }

    // ランダムエラー
    if (Math.random() < this.config.errorRate) {
      return new Response("Chaos: injected failure", { status: 503 });
    }

    return next();
  }

  private shouldApply(req: Request): boolean {
    const url = new URL(req.url);
    return this.config.allowedEndpoints.some((p) => url.pathname.startsWith(p));
  }
}

6. Game Day の進行表

# Game Day: Payment Service Degradation

## 目的
payment-service の遅延時に、注文 API が適切にフォールバックするか検証

## 参加者
- SRE: 2名(オペレータ)
- Backend: 2名(観測・分析)
- PM: 1名(意思決定)

## タイムライン
- 10:00 ベースライン測定 (Grafana 確認)
- 10:15 仮説: p99 < 2s, error rate < 2%
- 10:30 実験1: 500ms 遅延を payment-service に注入
- 10:45 観測と議論
- 11:00 実験2: payment-service 1 Pod を削除
- 11:15 観測と議論
- 11:30 ロールバック確認、ポストモーテム

メリット・デメリット

メリット

  1. 隠れた障害モードの発見: 設計図には現れない問題
  2. 耐障害性の実証: 「動くはず」から「動くと確認済み」へ
  3. オンコール対応力向上: 実際の障害に対するチーム訓練
  4. 設計改善のフィードバック: Circuit Breaker/Retry の効果検証
  5. SLO の現実的な設定: 机上ではなく実測で SLA を決める
  6. ポストモーテム文化: 失敗を学びに変える組織文化

デメリット

  1. 本番影響のリスク: 実際の顧客影響が発生する可能性
  2. 組織文化の要求: 失敗を許容する文化が前提
  3. 成熟度の要求: 監視・アラートが整備されていないと危険
  4. 実施コスト: Game Day の準備・実施に工数
  5. スコープ管理の難しさ: 影響範囲の制御が高度
  6. 経営層の理解: 「なぜわざわざ壊すのか」の説明負荷

ユースケース

適用が有効な場面

  • 大規模分散システム(マイクロサービス、多リージョン)
  • SLO/SLA が厳しいサービス(金融、e-commerce)
  • リリース頻度が高いアジャイル組織
  • SRE プラクティスを導入している組織
  • ディザスタリカバリ計画の検証

開始を控えるべき場面

  • 監視・アラート・ロールバック機構がない
  • ポストモーテム文化がない組織
  • 単一障害点だらけのシステム
  • 初期プロトタイプ段階

落とし穴

注意: 監視・アラート・ロールバック機構が整備されていない状態でのカオス実験は、問題を悪化させるだけです。必ず SLI/SLO/ダッシュボード/アラートを先に整備してください。

1. 監視なしで実験開始

異常を検知できないままカオス実験を行うと、問題を悪化させます。先に SLI/SLO、ダッシュボード、アラートを整備します。

2. 影響範囲制御を怠る

「本番でやる」と「顧客に影響させる」は別です。フィーチャーフラグ、対象の絞り込み、自動停止条件で影響を制御します。

3. 仮説なし実験

「とりあえず壊す」では学びが得られません。定常状態と期待される挙動を事前に文書化します。

4. 一度やって終わり

カオスエンジニアリングは継続的規律です。一度きりの実験ではなく、CI/CD に組み込み常時実行します。

5. 組織的合意の欠如

事前に関係者(SRE、開発、プロダクト、場合によっては顧客サポート)に周知していないと、実験が事故として扱われます。

6. 失敗の責任追及

カオス実験で問題が見つかったのに「誰のせいだ」と追及する文化では、実験が萎縮します。ブレームレスポストモーテムが必須です。

7. いきなり本番

最初からプロダクションはハイリスクです。Dev → Staging → Canary → Prod の順で経験を積みます。

比較表

主要なカオスエンジニアリングツール

ツール提供元対象特徴
Chaos MonkeyNetflixEC2/Spinnaker祖。VM停止を中心
Chaos MeshCNCFKubernetesPod/Network/IO/カーネル
LitmusChaosCNCFKubernetesGitOps 連携
AWS FISAWSAWS リソースマネージド、自動停止
Azure Chaos StudioAzureAzure リソースマネージド
GremlinGremlin Incマルチクラウド商用、UX重視
chaostoolkitOSS汎用JSON定義、拡張可能
PumbaOSSDockerコンテナ単体向け

テストとの違い

観点単体テスト統合テストカオスエンジニアリング
対象関数/クラスモジュール間システム全体
環境ローカルCI本番/本番相当
目的仕様の検証連携の検証未知の障害の発見
時期開発時ビルド時継続的
結果Pass/FailPass/Fail学びと改善

実践メモ: まずはDev環境から始め、Dev → Staging → Canary → Prod の順で経験を積みましょう。いきなり本番はリスクが高すぎます。

ポイント: ブレームレスポストモーテムが前提です。カオス実験で問題が見つかった時、人ではなく設計を責める文化がなければ実験が萎縮します。

ベストプラクティス

  1. SRE基盤を先に整備: SLI/SLO/アラート/Runbook
  2. 小さく始める: Dev → Staging → 本番の段階
  3. 影響範囲の自動制御: エラー率閾値で自動停止
  4. 仮説駆動: 実験前に期待動作を文書化
  5. ポストモーテム: 学びを組織知にする
  6. GameDay の定例化: 月1回など継続実施
  7. 継続的カオス: Chaos Monkey 的な常時実験
  8. 顧客影響の計測: 実験の「コスト」を可視化
  9. ブレームレス文化: 人ではなく設計を責める
  10. ロールバック準備: 常に元に戻せる状態を維持

まとめ

カオスエンジニアリングは、単なる「壊すテスト」ではなく、本番の不確実性と向き合う規律です。

  • 原則: 定常状態 / 現実的障害 / 本番 / 自動化 / 最小範囲
  • 実践: 仮説 → 注入 → 観測 → 学習 → 改善
  • 前提: 監視・アラート・ブレームレス文化
  • ツール: Chaos Mesh、AWS FIS、Gremlin など
  • 継続: 一度きりでなく常時実施

「障害は避けられない、ならば学ぼう」という姿勢が、真に強いシステムを生みます。

応用トピック

成熟度モデル

Netflix が定義する「カオスエンジニアリング成熟度モデル(Maturity Model)」は、Sophistication(洗練度)と Adoption(採用度)の2軸で組織の状態を評価します。

レベルSophisticationAdoption
1手動、単発1チームのみ
2部分自動複数チーム
3完全自動組織全体
4本番継続全サービス標準

カオスエンジニアリング vs Resilience Testing

両者は似ていますが焦点が異なります。

  • Resilience Testing: 既知の障害に対する既知の挙動の確認
  • Chaos Engineering: 未知の障害モードの発見

カオスエンジニアリングは「知らないことを知らない」領域を狙います。

Security Chaos Engineering

Aaron Rinehart らが提唱する、セキュリティ領域へのカオスエンジニアリング適用です。

  • IAM 権限の一時的な削除
  • WAF ルールの無効化
  • TLS 証明書の期限切れシミュレーション
  • シークレットのローテーション失敗

セキュリティ機構が実際に発火するか、ブロックされた際の挙動が適切かを検証します。

Continuous Verification

従来の CI/CD が「コードが壊れていないか」を検証するのに対し、Continuous Verification は「システム全体が期待通り動作するか」を継続検証する概念です。カオスエンジニアリングはこの実現手段の1つです。

flowchart LR
    CI["CI<br/>ビルド検証"]
    CD["CD<br/>デプロイ"]
    CV["CV<br/>継続検証"]
    Prod["本番"]

    CI --> CD --> Prod
    CV -.-> Prod
    CV -. フィードバック .-> CI

ブラストレディウス制御の実装パターン

class BlastRadiusGuard {
  constructor(
    private readonly maxAffectedPct: number,
    private readonly errorRateThreshold: number,
    private readonly getCurrentMetrics: () => Promise<Metrics>,
  ) {}

  async canContinue(): Promise<boolean> {
    const m = await this.getCurrentMetrics();
    if (m.errorRate > this.errorRateThreshold) return false;
    if (m.affectedInstancesPct > this.maxAffectedPct) return false;
    return true;
  }
}

interface Metrics {
  errorRate: number;
  affectedInstancesPct: number;
}

ポストモーテムのテンプレート

カオス実験後は必ず構造化された振り返りを残します。

# Postmortem: <実験名>

## Summary
<1行要約>

## Timeline
- HH:MM ベースライン測定
- HH:MM 実験開始
- HH:MM 異常検知
- HH:MM ロールバック
- HH:MM 解消

## Hypothesis
<期待していた挙動>

## Actual
<実際に起きたこと>

## Root Causes
- <原因1>
- <原因2>

## Action Items
- [ ] <改善1> @owner
- [ ] <改善2> @owner

## Lessons Learned
- <学び>

参考リソース

この技術を体系的に学びたいですか?

未来学では東証プライム上場企業のITエンジニアが24時間サポート。月額24,800円から、退会金0円のオンラインIT塾です。

メールで無料相談する
← 一覧に戻る