Skip to content
Published on

Chaos Engineering 実践ガイド: LitmusとChaos MeshによるKubernetes障害注入とレジリエンス検証

Authors
  • Name
    Twitter
Chaos Engineering

はじめに

「すべてのものはいずれ障害を起こす(Everything fails, all the time)。」AWS CTOのWerner Vogelsのこの言葉は、分散システム運用の核心的な真理を表しています。どれほど堅牢に設計されたシステムであっても、予期しない障害は発生し得るものであり、問題は障害の発生の有無ではなく、障害発生時にシステムがどれだけ迅速かつ安全に復旧できるかです。

Chaos Engineeringは、この哲学に基づき、制御された環境で意図的に障害を注入し、システムのレジリエンス(Resilience)を事前に検証する方法論です。Netflixが2010年代初頭にChaos Monkeyを導入して以来、Chaos Engineeringは本番システムの信頼性を保証するための重要なエンジニアリングプラクティスとして定着しました。特にKubernetes環境では、Pod障害、ネットワーク遅延、ノードダウン、I/Oエラーなど多様な種類の障害が発生する可能性があり、これらを事前に実験し対応体制を整えることが運用安定性の鍵となります。

本記事では、Kubernetes環境で最も広く使用されている2つのオープンソースChaos EngineeringプラットフォームであるLitmusChaosChaos Meshを深く比較し、実際の本番環境での障害注入実験の設計からGameDay運用、SLOベースの定常状態検証、そして障害事例と復旧手順までを総合的に取り上げます。

Chaos Engineeringの原則

Chaos Engineeringは単に「システムを壊すこと」ではなく、科学的な実験方法論に従う体系的なアプローチです。Netflixが確立したChaos Engineeringの核心原則は以下のとおりです。

1. 定常状態に対する仮説の策定(Steady State Hypothesis)

実験前にシステムの「定常状態」を定義します。これは測定可能なビジネスメトリクスや技術指標で表現される必要があります。例えば「APIレスポンスタイムp99が500ms以下」、「エラー率が0.1%未満」、「注文処理量が毎秒100件以上」などが定常状態の仮説となります。

2. 実世界のイベントで実験する(Real-World Events)

実験で注入する障害は、実際に発生し得るシナリオを反映する必要があります。Podクラッシュ、ネットワークパーティション、ディスクI/O遅延、CPU過負荷、DNS障害などが代表的です。

3. 本番環境で実験を実行する(Run Experiments in Production)

システムの実際の動作を最も正確に検証するには、本番環境で実験する必要があります。ただし、十分なセーフガード(abort条件、blast radius制限)を備えた上で実施する必要があります。

4. 継続的な自動化(Automate Experiments to Run Continuously)

Chaos Engineeringは一回限りのイベントではなく、CI/CDパイプラインに統合して継続的に実行することを目指します。

5. 爆発半径の最小化(Minimize Blast Radius)

実験の影響範囲を最小限に制限し、異常事態が発生した際に即座に実験を中断できるメカニズムを備える必要があります。

Litmus vs Chaos Mesh 比較表

2つのプラットフォームを多角的に比較し、組織の要件に適したツールを選択できるようにします。

項目LitmusChaosChaos Mesh
CNCFグレードIncubating(2022年昇格)Incubating(2022年昇格)
開発主体ChaosNative(Harness買収)PingCAP / コミュニティ
対応環境Kubernetes, VM, Cloud, Bare MetalKubernetes専用
インストール方法Helm / kubectl / OperatorHelm / kubectl
Web UIChaosCenter(フルダッシュボード)Chaos Dashboard
実験定義ChaosExperiment + ChaosEngine CRD各Chaosタイプ別CRD(PodChaos, NetworkChaos等)
実験ハブChaosHub(コミュニティ共有実験)内蔵実験 + カスタム
SLO統合Probeベースの定常状態検証StatusCheck + Grafana連携
RBACネイティブ対応(プロジェクト/チーム単位)Kubernetes RBAC連携
スケジューリングCronWorkflowベースSchedule CRDベース
学習コスト中程度(概念がやや複雑)低い(直感的なCRD構造)
コミュニティ規模GitHub Stars 4.4k+GitHub Stars 6.5k+
CI/CD統合API/SDK, GitHub Actions対応API, CLIベース
商用サポートHarness Chaos Engineeringコミュニティベース

選択基準の要約: Kubernetes以外の環境も含めた包括的なChaos Engineeringが必要な場合や、体系的な実験管理とChaosHubベースの実験共有が重要であればLitmusChaosが適しています。Kubernetes専用環境で迅速に始めたい場合や、直感的なCRDベースの障害注入を好む場合はChaos Meshが良い選択です。

インストールガイド

LitmusChaosのインストール

LitmusChaosはChaosCenter(管理ダッシュボード)とChaos Infrastructure(実験実行エージェント)で構成されます。

# LitmusChaosネームスペースの作成
kubectl create namespace litmus

# Helmリポジトリの追加
helm repo add litmuschaos https://litmuschaos.github.io/litmus-helm/
helm repo update

# ChaosCenterのインストール(MongoDB, Auth Server, Frontend, Backendを含む)
helm upgrade --install litmus litmuschaos/litmus \
  --namespace litmus \
  --set portal.server.service.type=ClusterIP \
  --set portal.frontend.service.type=ClusterIP \
  --set mongodb.persistence.enabled=true \
  --set mongodb.persistence.storageClass=standard \
  --set mongodb.persistence.size=20Gi

# インストールの確認
kubectl get pods -n litmus

# ChaosCenter UIへのアクセス(ポートフォワーディング)
kubectl port-forward svc/litmus-frontend-service -n litmus 9091:9091

# デフォルト管理者アカウント: admin / litmus
# 初回ログイン後に必ずパスワードを変更してください

Chaos Meshのインストール

Chaos MeshはController Manager、Chaos Daemon、Dashboardで構成されます。

# Chaos Meshネームスペースの作成
kubectl create namespace chaos-mesh

# Helmリポジトリの追加
helm repo add chaos-mesh https://charts.chaos-mesh.org
helm repo update

# Chaos Meshのインストール
helm upgrade --install chaos-mesh chaos-mesh/chaos-mesh \
  --namespace chaos-mesh \
  --set chaosDaemon.runtime=containerd \
  --set chaosDaemon.socketPath=/run/containerd/containerd.sock \
  --set dashboard.securityMode=true \
  --set dashboard.create=true \
  --version 2.7.0

# インストールの確認
kubectl get pods -n chaos-mesh

# CRDの確認
kubectl get crd | grep chaos-mesh

# Dashboardへのアクセス(ポートフォワーディング)
kubectl port-forward svc/chaos-dashboard -n chaos-mesh 2333:2333

注意すべき点は、Chaos MeshのchaosDaemon.runtimechaosDaemon.socketPathをクラスタのコンテナランタイムに合わせて設定する必要があることです。containerd、CRI-O、Dockerそれぞれのソケットパスが異なるため、クラスタのランタイム環境を事前に確認する必要があります。

ChaosExperiment設計

Pod Kill実験

最も基本的なChaos実験であり、特定のPodを強制終了してアプリケーションの自動復旧能力を検証します。

Litmus - Pod Delete実験:

# litmus-pod-delete.yaml
apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: pod-delete-chaos
  namespace: production
spec:
  engineState: active
  annotationCheck: 'false'
  appinfo:
    appns: production
    applabel: app=payment-service
    appkind: deployment
  chaosServiceAccount: litmus-admin
  experiments:
    - name: pod-delete
      spec:
        components:
          env:
            # 実験の持続時間(秒)
            - name: TOTAL_CHAOS_DURATION
              value: '60'
            # Pod削除間隔(秒)
            - name: CHAOS_INTERVAL
              value: '10'
            # 強制削除の有無
            - name: FORCE
              value: 'false'
            # 削除するPod数
            - name: PODS_AFFECTED_PERC
              value: '50'
            # 実験の順序(parallelまたはserial)
            - name: SEQUENCE
              value: 'parallel'
        probe:
          - name: payment-health-check
            type: httpProbe
            mode: Continuous
            httpProbe/inputs:
              url: 'http://payment-service.production.svc:8080/health'
              method:
                get:
                  criteria: ==
                  responseCode: '200'
            runProperties:
              probeTimeout: 5s
              interval: 5s
              retry: 3
              probePollingInterval: 2s

Chaos Mesh - PodChaos実験:

# chaos-mesh-pod-kill.yaml
apiVersion: chaos-mesh.org/v1alpha1
kind: PodChaos
metadata:
  name: pod-kill-payment
  namespace: chaos-mesh
spec:
  action: pod-kill
  mode: fixed-percent
  value: '50'
  selector:
    namespaces:
      - production
    labelSelectors:
      app: payment-service
  # gracePeriod: 0 の場合は強制終了
  gracePeriod: 30
  duration: '60s'
---
# スケジュールされた実験(毎週水曜日午前10時)
apiVersion: chaos-mesh.org/v1alpha1
kind: Schedule
metadata:
  name: scheduled-pod-kill
  namespace: chaos-mesh
spec:
  schedule: '0 10 * * 3'
  type: PodChaos
  historyLimit: 5
  concurrencyPolicy: Forbid
  podChaos:
    action: pod-kill
    mode: one
    selector:
      namespaces:
        - production
      labelSelectors:
        app: payment-service
    gracePeriod: 30
    duration: '30s'

Network Latency実験

ネットワーク遅延を注入し、マイクロサービス間通信におけるタイムアウト設定やCircuit Breakerパターンが正しく動作するかを検証します。

Chaos Mesh - NetworkChaos(遅延注入):

# chaos-mesh-network-delay.yaml
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
  name: network-delay-between-services
  namespace: chaos-mesh
spec:
  action: delay
  mode: all
  selector:
    namespaces:
      - production
    labelSelectors:
      app: order-service
  delay:
    latency: '200ms'
    jitter: '50ms'
    correlation: '25'
  direction: to
  target:
    selector:
      namespaces:
        - production
      labelSelectors:
        app: payment-service
    mode: all
  duration: '5m'
---
# ネットワークパケットロス実験
apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
  name: network-loss-experiment
  namespace: chaos-mesh
spec:
  action: loss
  mode: all
  selector:
    namespaces:
      - production
    labelSelectors:
      app: api-gateway
  loss:
    loss: '30'
    correlation: '25'
  direction: both
  duration: '3m'

IO Fault実験

ディスクI/O障害をシミュレーションし、データベース、キャッシュ、ロギングシステムのレジリエンスを検証します。

Chaos Mesh - IOChaos(I/O障害注入):

# chaos-mesh-io-fault.yaml
apiVersion: chaos-mesh.org/v1alpha1
kind: IOChaos
metadata:
  name: io-latency-database
  namespace: chaos-mesh
spec:
  action: latency
  mode: one
  selector:
    namespaces:
      - production
    labelSelectors:
      app: postgres
  volumePath: /var/lib/postgresql/data
  path: '**/*'
  delay: '100ms'
  percent: 50
  duration: '5m'
---
# I/Oエラー注入(読み取り操作にエラーを返す)
apiVersion: chaos-mesh.org/v1alpha1
kind: IOChaos
metadata:
  name: io-error-experiment
  namespace: chaos-mesh
spec:
  action: fault
  mode: one
  selector:
    namespaces:
      - production
    labelSelectors:
      app: postgres
  volumePath: /var/lib/postgresql/data
  path: '**/*.dat'
  errno: 5
  percent: 30
  duration: '3m'

CPU Stress実験

CPU過負荷状況をシミュレーションし、HPA(Horizontal Pod Autoscaler)のスケールアウト動作とサービス品質低下時の対応を検証します。

Chaos Mesh - StressChaos(CPU/Memoryストレス):

# chaos-mesh-stress.yaml
apiVersion: chaos-mesh.org/v1alpha1
kind: StressChaos
metadata:
  name: cpu-stress-api
  namespace: chaos-mesh
spec:
  mode: all
  selector:
    namespaces:
      - production
    labelSelectors:
      app: api-server
  stressors:
    cpu:
      workers: 4
      load: 80
    memory:
      workers: 2
      size: '512MB'
  duration: '5m'
  containerNames:
    - api-server

GameDayプロセス

GameDayは、Chaos Engineering実験を組織的に実施するイベントです。単なる技術的テストを超えて、チームの障害対応プロセスとコミュニケーションを実践的に検証することが核心です。

ステップ1: 事前準備(1〜2週間前)

  • 範囲の定義: 実験対象のサービス、影響範囲(blast radius)、実験タイプを確定します。
  • 仮説の策定: 定常状態仮説をSLOベースで定義します。例えば「注文サービスのPod 50%が終了してもp99レスポンスタイム1秒以下、エラー率1%未満を維持すべきである」という形で具体化します。
  • 観測ツールの準備: 実験中にモニタリングするダッシュボード(Grafana)、ログシステム(ELK/Loki)、トレーシングシステム(Jaeger/Tempo)を事前に構成します。
  • ロールバック計画: 実験中に予期しない状況が発生した場合の緊急中断手順(abort)と復旧手順を文書化します。
  • ステークホルダーへの通知: 実験スケジュールと予想される影響範囲を関連チーム(運用、ビジネス、カスタマーサポート)に事前共有します。

ステップ2: 実験の実行(当日)

  • 事前チェック: 実験前にシステムの現在の状態が正常であることを確認します。すでに障害が進行中の状態でChaos実験を実施してはいけません。
  • 障害注入: 事前に定義したChaosExperimentを順次実行します。軽い実験から始めて、強度を段階的に上げていきます。
  • リアルタイム観測: 定常状態仮説の指標をリアルタイムでモニタリングし、異常の兆候が発生した場合は即座に記録します。
  • 中断条件の判断: 事前に定義した中断条件(エラー率5%超過、レスポンスタイム5秒超過など)に達した場合、即座に実験を中断します。

ステップ3: 事後分析(実験後1週間以内)

  • 結果の文書化: 各実験の仮説、実際の結果、観察された異常現象を詳細に記録します。
  • 改善項目の抽出: 仮説が失敗した場合(システムが予想どおりに復旧しなかった場合)、具体的な改善項目と担当者を指定します。
  • アクションアイテムの追跡: 抽出された改善項目の実装状況を継続的に追跡し、次回のGameDayで改善状況を再検証します。

SLOベースの定常状態仮説検証

Chaos Engineering実験の成否は、**定常状態仮説(Steady State Hypothesis)**の定義と検証にかかっています。SLO(Service Level Objective)をベースに定常状態を定義することで、ビジネス観点で意味のある実験結果を導き出すことができます。

SLO定義の例

サービスSLI(指標)SLO(目標)測定方法
API Gateway可用性99.9%(月間)Prometheus up メトリクス
注文サービスレスポンスタイム p99500ms以下Histogram http_request_duration_seconds
決済サービスエラー率0.1%未満http_requests_total{status=~"5.."} / 全リクエスト
検索サービススループット毎秒1000リクエスト以上rate(http_requests_total[5m])
データベースクエリ遅延 p95100ms以下pg_stat_statements

LitmusChaos Probeを活用した検証

LitmusChaosは、Probeメカニズムを通じて実験実行中に定常状態仮説を自動的に検証します。HTTP Probe、CMD Probe、Prometheus Probe、Kubernetes Probeなど多様なタイプをサポートしており、実験結果が仮説を満たさない場合、実験は「Failed」と表示されます。

HTTP Probeは、特定のエンドポイントのレスポンスコードとレスポンスタイムを実験前(SOT)、実験中(Continuous)、実験後(EOT)の各時点で検証できます。Prometheus ProbeはPrometheusクエリを実行し、SLIメトリクスがSLO閾値を超えていないかを検証します。これにより、実験の成否を客観的に判断することができます。

Chaos Mesh StatusCheckを活用した検証

Chaos Meshでは、StatusCheck CRDとWorkflowを組み合わせて定常状態検証を自動化できます。実験実行の前後でHTTPリクエストやカスタムスクリプトを実行してシステム状態を確認し、Grafanaダッシュボードと連携してSLO指標の変化を視覚的に追跡します。

障害事例と復旧手順

事例1: Chaos Experimentが中断されない問題

症状: NetworkChaos実験のdurationが満了したにもかかわらずネットワーク遅延が解除されず、本番サービスに持続的な影響が発生します。

原因: Chaos DaemonがOOM Killされるか、ノードが再起動されたことでtc(traffic control)ルールのクリーンアップが実行されなかった場合。またはChaos Mesh Controller Managerが削除イベントを処理できなかった場合。

復旧手順:

# 1. 進行中のChaosリソースの強制削除
kubectl delete networkchaos network-delay-between-services -n chaos-mesh

# 2. Chaos Daemonが正常に動作しているか確認
kubectl get pods -n chaos-mesh -l app.kubernetes.io/component=chaos-daemon

# 3. Chaos Daemonが異常であれば再起動
kubectl rollout restart daemonset chaos-daemon -n chaos-mesh

# 4. 手動でtcルールをクリーンアップ(影響を受けたノードで)
# ノードにSSH接続後
tc qdisc show dev eth0
tc qdisc del dev eth0 root netem 2>/dev/null || true

# 5. iptablesルールのクリーンアップ(ネットワークパーティション実験の場合)
iptables -L -n | grep CHAOS
iptables -F CHAOS-INPUT 2>/dev/null || true
iptables -F CHAOS-OUTPUT 2>/dev/null || true

予防策: Chaos Daemonのリソースrequests/limitsを十分に設定し、実験後の自動クリーンアップの完了を確認するモニタリングアラートを構成します。本番環境では必ずdurationフィールドを短く設定し、段階的に延長します。

事例2: Chaos実験が意図しないPodに影響

症状: ラベルセレクタのミスにより、Chaos実験が対象サービス以外の他のサービスPodにも障害を注入し、連鎖的なサービス障害が発生します。

原因: ラベルセレクタが広範囲に設定されていたか、ネームスペースの指定漏れによりクラスタ全体のPodが対象に含まれた場合。

復旧手順:

  1. 即座にChaosリソースを削除して実験を中断します。
  2. 影響を受けたPodの状態を確認し、必要に応じてDeploymentをロールアウト再起動します。
  3. Chaos実験のセレクタを修正し、正確な対象のみを選択するように変更します。

予防策: 実験前に--dry-runまたは対象Pod一覧を事前確認するスクリプトを実行します。ネームスペースを必ず明示的に指定し、annotationCheckを有効化してChaos対象アノテーションが付いたPodのみを選択するようにします。

事例3: StressChaosによるノード全体の不安定化

症状: CPU/Memoryストレス実験が対象Podだけでなく同一ノードの他のPodにも影響を及ぼし、ノード全体がNotReady状態になります。

原因: ストレス実験がcgroup制限なしで実行され、ノードレベルのリソース枯渇が発生した場合。または対象Podにリソースlimitsが設定されておらず、ストレスがノード全体に波及した場合。

復旧手順:

  1. Chaosリソースを即座に削除します。
  2. ノードがNotReady状態であれば、kubeletを再起動するかノードをdrainした後に再起動します。
  3. 影響を受けたワークロードの復旧状態を確認します。

予防策: StressChaos実験の対象Podには必ずリソースlimitsを設定します。containerNamesフィールドを使用して特定のコンテナにのみストレスを注入し、最初は低い負荷(CPU load 20〜30%)から開始して段階的に上げていきます。

事例4: IOChaos実験後のデータ整合性の問題

症状: I/O障害注入実験後、データベースのWAL(Write-Ahead Log)ファイルが破損し、データベースが正常に起動しなくなります。

原因: I/Oエラー注入(action: fault)がデータベースのクリティカルパスに適用され、トランザクションログが不完全に記録された場合。

復旧手順:

  1. データベースPodを削除し、PVCから再起動して自動復旧を試みます。
  2. WAL復旧ツールを使用して破損したログを復元します。
  3. 自動復旧が不可能な場合、最新のバックアップからデータを復元します。

予防策: IOChaos実験でデータベースを対象とする場合は、必ず読み取り専用パスにのみ障害を注入します。pathフィールドを使用してWALディレクトリを除外し、percent値を低く(10〜20%)設定して部分的なI/O障害のみをシミュレーションします。実験前にデータベースの最新バックアップが存在することを必ず確認します。

事例5: LitmusChaos ChaosEngineが完了しない問題

症状: ChaosEngineリソースのステータスがRunningのまま変わらず、実験が無限に進行しているように見えます。

原因: Chaos Runner Podがcrash loopに陥ったか、実験実行Podのイメージプルに失敗して実験が開始できなかった場合。

復旧手順:

  1. ChaosEngineのステータスと関連Podを確認します: kubectl describe chaosengine <name> -n <namespace>
  2. Chaos Runnerと実験Podのログを確認します。
  3. ChaosEngineのengineStatestopに変更して実験を中断します。
  4. 問題を解決した後、新しいChaosEngineを作成して再試行します。

予防策: 実験に使用するコンテナイメージを事前にノードにプルしておき、ChaosEngineにタイムアウトを設定して、指定された時間内に完了しない場合は自動的に中断されるようにします。

運用時の注意事項チェックリスト

実験設計時の確認事項

  • 定常状態仮説(Steady State Hypothesis)が測定可能な指標で定義されているか
  • 実験の爆発半径(blast radius)が明確に制限されているか
  • ラベルセレクタとネームスペースが正確な対象のみを選択するか事前検証したか
  • 実験中断条件(abort criteria)が事前に定義されているか
  • ロールバック/復旧手順が文書化されており、チームメンバーが把握しているか

本番環境適用時の確認事項

  • ステージング環境で十分にテストした後に本番環境に適用しているか
  • 実験開始前にシステムの現在の状態が正常であることを確認したか
  • 実験中のリアルタイムモニタリング(Grafanaダッシュボード、アラート)が構成されているか
  • ビジネスクリティカルな時間帯(決済ピーク、イベント期間)を避けて実験を実施しているか
  • 実験スケジュールと影響範囲を関連チームに事前共有したか
  • Chaos RBACを通じて実験実行権限が適切に制限されているか

実験実行中の確認事項

  • すべてのSLI指標がリアルタイムでモニタリングされているか
  • 中断条件に達した場合に即座に実験を中断できる準備ができているか
  • 実験結果(成功/失敗)を記録しているか
  • 予期しない副作用(side effect)が発見された場合、即座に報告しているか

実験後の確認事項

  • 注入した障害が完全にクリーンアップされたことを確認したか
  • tcルール、iptablesルールなどシステムレベルの変更が元に戻されたことを確認したか
  • 実験結果を文書化し改善項目を抽出したか
  • 抽出された改善項目に担当者と期限を設定したか
  • 次回のGameDayスケジュールと再検証計画を策定したか

参考資料