Litmus

Litmus Chaos Engineering 完全ガイド

1. はじめに

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

カオスエンジニアリングとは、本番環境における分散システムの信頼性を向上させるために、システムに意図的に障害を注入し、その挙動を観察・分析する手法である。Netflixが2010年代初頭に提唱した「Chaos Monkey」の概念に端を発し、現在ではクラウドネイティブアーキテクチャにおける品質保証の中核的プラクティスとして広く認知されている。

カオスエンジニアリングの基本原則は以下の通りである:

  1. 定常状態の仮説を立てる: システムの正常な動作を定量的に定義する
  2. 実世界のイベントを反映した変数を導入する: 実際に発生しうる障害シナリオを再現する
  3. 本番環境で実験を実行する: 可能な限り本番に近い環境で検証する
  4. 定常状態の仮説を検証する: 障害注入後のシステム挙動を観察し、仮説と比較する
  5. 影響範囲を最小化する: 実験による被害を制限する仕組みを設ける

1.2 Litmusとは

LitmusChaos(以下Litmus)は、CNCFに所属するオープンソースのカオスエンジニアリングプラットフォームである。Kubernetes環境に特化して設計されており、クラウドネイティブアプリケーションに対する障害注入実験を体系的に実施するためのフレームワークを提供する。

Litmusの主な特徴は以下の通りである:

  • Kubernetes ネイティブ: CRD(Custom Resource Definition)ベースのアーキテクチャにより、Kubernetesのエコシステムとシームレスに統合
  • ChaosHub: 事前定義されたカオス実験のカタログを提供し、再利用可能な実験テンプレートを共有
  • Litmus Portal(ChaosCenter): Web UIベースの管理ポータルで、実験の作成・スケジューリング・モニタリングを一元管理
  • GitOps対応: 実験定義をGitリポジトリで管理し、CI/CDパイプラインとの統合を実現
  • マルチテナント: 複数のチーム・プロジェクトで独立したカオス実験環境を運用可能
  • 観測性統合: Prometheus、Grafanaなどのモニタリングツールとの連携による実験結果の可視化

1.3 Litmusの歴史とCNCFでの位置づけ

Litmusプロジェクトは2018年にMayaData(現在のDataCore Software)によって開始された。その後のマイルストーンは以下の通りである:

年月イベント
2018年Litmusプロジェクトの開始
2020年1月CNCF Sandboxプロジェクトとして採択
2022年1月CNCF Incubatingプロジェクトに昇格
2022年Litmus 3.0のリリース(アーキテクチャの大幅刷新)
2023年-2024年エンタープライズ機能の強化、Linux Chaos対応の拡充

CNCFランドスケープにおいて、Litmusは「Observability and Analysis」カテゴリの「Chaos Engineering」サブカテゴリに位置づけられている。同カテゴリにはChaos Mesh(PingCAP)やChaosBlade(Alibaba)などの競合プロジェクトも存在するが、LitmusはChaosHubによる実験カタログの充実度と、ChaosCenter(旧Litmus Portal)による運用管理の容易さで差別化されている。

1.4 本記事の構成

本記事では以下の構成でLitmusの全容を解説する:

  1. はじめに(本章): カオスエンジニアリングとLitmusの概要
  2. アーキテクチャ: Litmusのシステム構成とコンポーネント詳細
  3. コアコンセプト: CRD、Workflow、Probe、ChaosHubなどの基本概念
  4. インストールと初期設定: Helm Chartを用いたデプロイ手順
  5. カオス実験の種類: Pod、Node、Network、Stress、Application Level Chaos
  6. ChaosWorkflow の設計と実装: Argoベースのワークフロー定義
  7. Probeによるバリデーション: 実験結果の自動検証メカニズム
  8. ChaosHub: 実験カタログの管理と拡張
  9. GitOps統合: Git連携によるカオス実験の自動化
  10. CI/CDパイプライン統合: GitHub Actions、Tekton等との連携
  11. モニタリングと観測性: Prometheus/Grafanaとの統合
  12. マルチテナントとRBAC: エンタープライズ運用のためのアクセス制御
  13. カスタムカオス実験の作成: 独自の障害注入実験の開発
  14. ベストプラクティスと運用ガイド: 実践的な運用指針
  15. トラブルシューティング: よくある問題と解決策
  16. まとめと展望: Litmusの将来と発展方向

2. アーキテクチャ

2.1 全体アーキテクチャ概要

Litmus 3.x のアーキテクチャは、大きく分けて**コントロールプレーン(ChaosCenter)実行プレーン(Chaos Infrastructure)**の2層構成となっている。

┌─────────────────────────────────────────────────────────────────┐
│                     ChaosCenter(コントロールプレーン)              │
│  ┌─────────────┐  ┌──────────────┐  ┌─────────────────────────┐ │
│  │  Frontend    │  │  GraphQL     │  │  Authentication Server  │ │
│  │  (React)     │  │  Server      │  │  (OAuth/LDAP/OIDC)      │ │
│  └──────┬──────┘  └──────┬───────┘  └────────────┬────────────┘ │
│         │                │                        │              │
│  ┌──────┴────────────────┴────────────────────────┴────────────┐ │
│  │                    MongoDB                                   │ │
│  │  (実験定義, ワークフロー結果, ユーザー/プロジェクト情報)          │ │
│  └─────────────────────────────────────────────────────────────┘ │
└───────────────────────────┬─────────────────────────────────────┘
                            │ gRPC / WebSocket
                            ▼
┌─────────────────────────────────────────────────────────────────┐
│              Chaos Infrastructure(実行プレーン)                  │
│  ┌───────────────────┐  ┌──────────────────────────────────┐    │
│  │  Subscriber        │  │  Workflow Controller              │    │
│  │  (ChaosCenter通信) │  │  (Argo Workflows)                │    │
│  └───────────────────┘  └──────────────┬───────────────────┘    │
│                                         │                        │
│  ┌──────────────────────────────────────┴───────────────────┐   │
│  │              Chaos Operator                                │   │
│  │  ┌─────────────┐ ┌──────────────┐ ┌───────────────────┐  │   │
│  │  │ ChaosEngine │ │ ChaosExp     │ │ ChaosResult       │  │   │
│  │  │ Controller  │ │ Controller   │ │ Controller        │  │   │
│  │  └──────┬──────┘ └──────┬───────┘ └───────────────────┘  │   │
│  └─────────┼───────────────┼────────────────────────────────┘   │
│            │               │                                     │
│  ┌─────────┴───────────────┴─────────────────────────────────┐  │
│  │              Chaos Experiment Pods                          │  │
│  │  ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐     │  │
│  │  │ pod-     │ │ node-    │ │ network- │ │ stress-  │     │  │
│  │  │ delete   │ │ drain    │ │ loss     │ │ chaos    │     │  │
│  │  └──────────┘ └──────────┘ └──────────┘ └──────────┘     │  │
│  └───────────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────────┘

2.2 コントロールプレーン(ChaosCenter)

ChaosCenter はLitmusの管理ポータルであり、以下のコンポーネントで構成される。

2.2.1 Frontend(litmusportal-frontend)

  • 技術スタック: React.js / TypeScript
  • 機能: カオス実験の作成・管理、ワークフロー可視化、ダッシュボード表示
  • ポート: デフォルトで9091番ポートで稼働

2.2.2 GraphQL Server(litmusportal-server)

ChaosCenter のバックエンドAPIサーバーである。

  • 技術スタック: Go言語、GraphQL
  • 機能:
    • カオス実験・ワークフローのCRUD操作
    • Chaos Infrastructure の登録・管理
    • ChaosHub の同期・管理
    • 実験結果の集約・保存
    • イベント配信(GraphQL Subscription)
  • ポート: デフォルトで8080番ポート(HTTP/GraphQL)

2.2.3 Authentication Server

  • 技術スタック: Go言語
  • 機能:
    • ローカル認証(ユーザー名/パスワード)
    • OAuth2.0 / OIDC連携(Dex経由)
    • RBAC(Role-Based Access Control)
    • APIトークン管理
  • ポート: 3000番ポート

2.2.4 MongoDB

  • 用途: 全てのメタデータの永続化ストレージ
  • 格納データ:
    • ユーザー・プロジェクト情報
    • Chaos Infrastructure 登録情報
    • ワークフロー定義・実行結果
    • ChaosHub メタデータ
    • 監査ログ

2.3 実行プレーン(Chaos Infrastructure)

実際のカオス実験を実行するクラスタ側のコンポーネント群である。

2.3.1 Subscriber

Subscriber は ChaosCenter と Chaos Infrastructure 間の通信を仲介するエージェントである。

  • 通信方式: gRPC(双方向ストリーミング)またはWebSocket
  • 機能:
    • ChaosCenter からのワークフロー実行指示の受信
    • ワークフロー実行ステータスの送信
    • Chaos Infrastructure の健全性レポート
    • カオス実験結果の転送
# Subscriber のデプロイメント例
apiVersion: apps/v1
kind: Deployment
metadata:
  name: subscriber
  namespace: litmus
spec:
  replicas: 1
  selector:
    matchLabels:
      app: subscriber
  template:
    metadata:
      labels:
        app: subscriber
    spec:
      serviceAccountName: litmus-cluster-scope
      containers:
        - name: subscriber
          image: litmuschaos/litmusportal-subscriber:3.9.0
          env:
            - name: INFRA_ID
              valueFrom:
                configMapKeyRef:
                  name: subscriber-config
                  key: INFRA_ID
            - name: ACCESS_KEY
              valueFrom:
                secretKeyRef:
                  name: subscriber-secret
                  key: ACCESS_KEY
            - name: SERVER_ADDR
              valueFrom:
                configMapKeyRef:
                  name: subscriber-config
                  key: SERVER_ADDR

2.3.2 Workflow Controller(Argo Workflows)

Litmus は内部的に Argo Workflows をワークフローエンジンとして使用している。

  • 役割: カオス実験ワークフローのオーケストレーション
  • 機能:
    • ワークフローステップの順次・並列実行
    • 条件分岐・ループ処理
    • タイムアウト管理
    • リトライ制御

2.3.3 Chaos Operator

Chaos Operator は Litmus の中核コンポーネントであり、Kubernetes Operator パターンで実装されている。

  • 監視するCRD:
    • ChaosEngine: カオス実験の実行制御
    • ChaosExperiment: カオス実験の定義
    • ChaosResult: カオス実験の結果記録
  • Reconciliation Loop: ChaosEngine の状態変化を検知し、対応するカオス実験 Pod を起動・管理する

2.4 通信フロー

カオス実験の実行時における典型的な通信フローを示す。

ユーザー → Frontend → GraphQL Server → MongoDB(ワークフロー保存)
                                    ↓
                              Subscriber(gRPC経由でワークフロー転送)
                                    ↓
                           Workflow Controller(Argo Workflow作成)
                                    ↓
                            Chaos Operator(ChaosEngine処理)
                                    ↓
                          Experiment Pod(障害注入実行)
                                    ↓
                            ChaosResult(結果記録)
                                    ↓
                              Subscriber → GraphQL Server → MongoDB → Frontend

2.5 ネットワーク要件

通信元通信先プロトコルポート用途
FrontendGraphQL ServerHTTP/HTTPS8080API通信
GraphQL ServerMongoDBTCP27017データ永続化
SubscriberGraphQL ServergRPC/WebSocket8080双方向通信
Chaos OperatorKubernetes APIHTTPS443CRD操作
Experiment Pod対象Pod/Node各種各種障害注入

2.6 Self-Agentモードと External Agent モード

Litmus は2つのデプロイメントモードをサポートする。

Self-Agent モード: ChaosCenter と同じクラスタ内でカオス実験を実行する。開発・テスト環境に適している。

External Agent モード: ChaosCenter とは異なるクラスタでカオス実験を実行する。本番環境のカオスエンジニアリングに適しており、ChaosCenter を安全なマネジメントクラスタに配置しつつ、複数のターゲットクラスタに対して実験を実行できる。

┌─────────────────────┐
│  Management Cluster  │
│  ┌───────────────┐  │
│  │  ChaosCenter  │  │
│  └───────┬───────┘  │     ┌──────────────────────┐
│          │          │     │  Target Cluster A     │
│          ├──────────┼────→│  (Chaos Infrastructure)│
│          │          │     └──────────────────────┘
│          │          │     ┌──────────────────────┐
│          └──────────┼────→│  Target Cluster B     │
│                     │     │  (Chaos Infrastructure)│
└─────────────────────┘     └──────────────────────┘

3. コアコンセプト

3.1 Custom Resource Definitions(CRD)

Litmus は Kubernetes の CRD を活用してカオス実験を宣言的に定義する。主要な CRD は以下の3つである。

3.1.1 ChaosExperiment

カオス実験のテンプレートを定義するリソースである。実験のパラメータ、必要な権限、デフォルト値などを宣言する。

apiVersion: litmuschaos.io/v1alpha1
kind: ChaosExperiment
metadata:
  name: pod-delete
  namespace: litmus
spec:
  definition:
    scope: Namespaced
    permissions:
      - apiGroups: [""]
        resources: ["pods"]
        verbs: ["create", "delete", "get", "list", "patch", "update"]
      - apiGroups: [""]
        resources: ["events"]
        verbs: ["create", "get", "list", "patch", "update"]
      - apiGroups: ["litmuschaos.io"]
        resources: ["chaosengines", "chaosexperiments", "chaosresults"]
        verbs: ["create", "delete", "get", "list", "patch", "update"]
    image: litmuschaos/go-runner:3.9.0
    imagePullPolicy: Always
    args:
      - -c
      - ./experiments -name pod-delete
    command:
      - /bin/bash
    env:
      - name: TOTAL_CHAOS_DURATION
        value: "30"
      - name: CHAOS_INTERVAL
        value: "10"
      - name: FORCE
        value: "true"
      - name: TARGET_PODS
        value: ""
      - name: PODS_AFFECTED_PERC
        value: ""
      - name: RAMP_TIME
        value: ""
      - name: SEQUENCE
        value: "parallel"
    labels:
      name: pod-delete
      app.kubernetes.io/part-of: litmus
      app.kubernetes.io/component: experiment-job

3.1.2 ChaosEngine

カオス実験の実行をトリガーするリソースである。どのアプリケーションに対してどの実験を実行するかを指定する。

apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: nginx-chaos
  namespace: default
spec:
  engineState: "active"
  appinfo:
    appns: "default"
    applabel: "app=nginx"
    appkind: "deployment"
  chaosServiceAccount: pod-delete-sa
  experiments:
    - name: pod-delete
      spec:
        components:
          env:
            - name: TOTAL_CHAOS_DURATION
              value: "60"
            - name: CHAOS_INTERVAL
              value: "10"
            - name: FORCE
              value: "true"
            - name: PODS_AFFECTED_PERC
              value: "50"
        probe:
          - name: "check-nginx-health"
            type: "httpProbe"
            mode: "Continuous"
            runProperties:
              probeTimeout: 5s
              retry: 2
              interval: 5s
            httpProbe/inputs:
              url: "http://nginx-service:80"
              insecureSkipVerify: false
              method:
                get:
                  criteria: "=="
                  responseCode: "200"

3.1.3 ChaosResult

カオス実験の結果を記録するリソースである。Chaos Operator によって自動的に作成・更新される。

apiVersion: litmuschaos.io/v1alpha1
kind: ChaosResult
metadata:
  name: nginx-chaos-pod-delete
  namespace: default
spec:
  engine: nginx-chaos
  experiment: pod-delete
status:
  experimentStatus:
    phase: Completed
    verdict: Pass
    failStep: "N/A"
    probeSuccessPercentage: "100"
  probeStatuses:
    - name: "check-nginx-health"
      type: "httpProbe"
      mode: "Continuous"
      status:
        continuousProbePhase: "Passed"
        continuousProbeVerdict: "Passed"
  history:
    passedRuns: 1
    failedRuns: 0
    stoppedRuns: 0

3.2 ChaosWorkflow(Resilience Workflow)

Litmus 3.x では、複数のカオス実験を組み合わせたワークフローを定義できる。内部的にはArgo Workflowsの Workflow CRD を使用している。

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  name: resilience-test-workflow
  namespace: litmus
  labels:
    workflows.argoproj.io/controller-instanceid: ""
spec:
  entrypoint: chaos-test
  serviceAccountName: argo-chaos
  securityContext:
    runAsUser: 1000
    runAsNonRoot: true
  arguments:
    parameters:
      - name: adminModeNamespace
        value: litmus
  templates:
    - name: chaos-test
      steps:
        - - name: install-pod-delete-experiment
            template: install-experiment
            arguments:
              parameters:
                - name: experiment-name
                  value: pod-delete
        - - name: run-pod-delete
            template: pod-delete
        - - name: cleanup
            template: revert-chaos

    - name: install-experiment
      inputs:
        parameters:
          - name: experiment-name
      container:
        image: litmuschaos/k8s:3.9.0
        command: [sh, -c]
        args:
          - "kubectl apply -f https://hub.litmuschaos.io/api/chaos/3.9.0?file=faults/kubernetes/{{inputs.parameters.experiment-name}}/fault.yaml -n {{workflow.parameters.adminModeNamespace}}"

    - name: pod-delete
      inputs:
        artifacts:
          - name: pod-delete
            path: /tmp/chaosengine-pod-delete.yaml
            raw:
              data: |
                apiVersion: litmuschaos.io/v1alpha1
                kind: ChaosEngine
                metadata:
                  name: workflow-pod-delete
                  namespace: "{{workflow.parameters.adminModeNamespace}}"
                  labels:
                    workflow_run_id: "{{workflow.uid}}"
                spec:
                  engineState: active
                  appinfo:
                    appns: default
                    applabel: app=my-app
                    appkind: deployment
                  chaosServiceAccount: litmus-admin
                  experiments:
                    - name: pod-delete
                      spec:
                        components:
                          env:
                            - name: TOTAL_CHAOS_DURATION
                              value: "30"
                            - name: CHAOS_INTERVAL
                              value: "10"
                            - name: FORCE
                              value: "true"
      container:
        image: litmuschaos/litmus-checker:3.9.0
        args: ["-file=/tmp/chaosengine-pod-delete.yaml", "-saveName=/tmp/engine-name"]

    - name: revert-chaos
      container:
        image: litmuschaos/k8s:3.9.0
        command: [sh, -c]
        args:
          - "kubectl delete chaosengine -l workflow_run_id={{workflow.uid}} -n {{workflow.parameters.adminModeNamespace}}"

3.3 Resilience Score(レジリエンススコア)

Litmusはカオス実験の結果を定量的に評価するResilience Scoreを算出する。これは各実験の重み付けと成否に基づいて計算される。

計算式:

Resilience Score = Σ(実験の重み × Probe成功率) / Σ(実験の重み) × 100

例えば、3つの実験を実行した場合:

実験名重みProbe成功率寄与
pod-delete10100%10.0
network-loss875%6.0
node-drain5100%5.0
合計23-21.0

Resilience Score = 21.0 / 23 × 100 = 91.3%

このスコアにより、システムの回復力を定量的に追跡・比較できる。

3.4 Chaos Infrastructure のスコープ

Chaos Infrastructure は2つのスコープで動作する。

Cluster Scope(クラスタスコープ):

  • クラスタ全体に対するカオス実験が可能
  • Node レベルの障害注入(node-drain、node-taint等)が利用可能
  • ClusterRole / ClusterRoleBinding が必要

Namespace Scope(ネームスペーススコープ):

  • 特定のネームスペースに限定したカオス実験
  • Pod レベルの障害注入のみ利用可能
  • マルチテナント環境でのセキュリティ隔離に適している
  • Role / RoleBinding のみで動作
# Cluster Scope の ServiceAccount 例
apiVersion: v1
kind: ServiceAccount
metadata:
  name: litmus-cluster-scope
  namespace: litmus
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: litmus-cluster-scope-cr
rules:
  - apiGroups: [""]
    resources: ["pods", "pods/log", "pods/exec", "events", "services", "nodes"]
    verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
  - apiGroups: ["apps"]
    resources: ["deployments", "statefulsets", "replicasets", "daemonsets"]
    verbs: ["get", "list", "patch", "update", "delete"]
  - apiGroups: ["batch"]
    resources: ["jobs"]
    verbs: ["create", "delete", "get", "list", "watch"]
  - apiGroups: ["litmuschaos.io"]
    resources: ["chaosengines", "chaosexperiments", "chaosresults"]
    verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: litmus-cluster-scope-crb
subjects:
  - kind: ServiceAccount
    name: litmus-cluster-scope
    namespace: litmus
roleRef:
  kind: ClusterRole
  name: litmus-cluster-scope-cr
  apiGroup: rbac.authorization.k8s.io

4. インストールと初期設定

4.1 前提条件

Litmus 3.x のインストールに必要な前提条件は以下の通りである。

要件最小バージョン
Kubernetesv1.21以上
Helmv3.x
kubectlv1.21以上
ノードリソース(ChaosCenter)CPU: 2コア, メモリ: 4GB
PersistentVolumeMongoDB用に20GB以上

4.2 Helm Chartによるインストール

4.2.1 ChaosCenter のインストール

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

# litmus 名前空間の作成
kubectl create namespace litmus

# ChaosCenter のインストール
helm install chaos litmuschaos/litmus \
  --namespace litmus \
  --set portal.server.service.type=LoadBalancer \
  --set portal.frontend.service.type=LoadBalancer \
  --set mongodb.persistence.enabled=true \
  --set mongodb.persistence.size=20Gi

4.2.2 カスタム values.yaml による詳細設定

# values.yaml - ChaosCenter のカスタム設定
portal:
  server:
    replicas: 2
    service:
      type: ClusterIP
    resources:
      requests:
        cpu: 250m
        memory: 512Mi
      limits:
        cpu: 1000m
        memory: 1Gi
    # GraphQL サーバー設定
    graphqlServer:
      image:
        repository: litmuschaos/litmusportal-server
        tag: 3.9.0
        pullPolicy: Always
      genericEnv:
        SERVER_SERVICE_NAME: "litmusportal-server-service"
        SELF_AGENT: "true"
        SELF_AGENT_NODE_SELECTOR: ""
        SELF_AGENT_TOLERATIONS: ""
        CONTAINER_RUNTIME_EXECUTOR: "k8sapi"
      # TLS設定
      tls:
        enabled: false
        secretName: ""

    # 認証サーバー設定
    authServer:
      image:
        repository: litmuschaos/litmusportal-auth-server
        tag: 3.9.0
      env:
        ADMIN_USERNAME: "admin"
        ADMIN_PASSWORD: "litmus"
        # OIDC設定
        OIDC_ENABLED: "false"
        # Dex設定
        DEX_ENABLED: "false"

  frontend:
    replicas: 1
    service:
      type: ClusterIP
    resources:
      requests:
        cpu: 125m
        memory: 256Mi
      limits:
        cpu: 500m
        memory: 512Mi
    image:
      repository: litmuschaos/litmusportal-frontend
      tag: 3.9.0

# MongoDB設定
mongodb:
  enabled: true
  image:
    repository: litmuschaos/mongo
    tag: "5.0"
  persistence:
    enabled: true
    storageClass: "gp3"
    size: 20Gi
    accessModes:
      - ReadWriteOnce
  resources:
    requests:
      cpu: 250m
      memory: 512Mi
    limits:
      cpu: 1000m
      memory: 2Gi
  # MongoDB認証
  auth:
    enabled: true
    rootUser: "root"
    rootPassword: "1234"
  # レプリカセット設定
  replicaCount: 3
  architecture: replicaset

# Ingress設定
ingress:
  enabled: true
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
  host:
    name: chaos.example.com
  tls:
    - secretName: chaos-tls
      hosts:
        - chaos.example.com
# カスタム設定でのインストール
helm install chaos litmuschaos/litmus \
  --namespace litmus \
  -f values.yaml

4.3 ChaosCenter の初期セットアップ

4.3.1 初回ログイン

# ChaosCenter のURL取得
export CHAOS_URL=$(kubectl get svc -n litmus litmusportal-frontend-service \
  -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
echo "ChaosCenter URL: http://${CHAOS_URL}:9091"

# デフォルト認証情報
# Username: admin
# Password: litmus

4.3.2 プロジェクトの作成

ChaosCenter にログイン後、まずプロジェクトを作成する。プロジェクトはカオス実験のテナント単位であり、独立した環境を提供する。

# GraphQL APIでのプロジェクト作成例
mutation {
  createProject(projectName: "production-chaos") {
    projectID
    name
    createdAt
  }
}

4.3.3 Chaos Infrastructure の登録

ターゲットクラスタにChaos Infrastructureを登録する手順を示す。

ChaosCenter UI経由の場合:

  1. ChaosCenter にログイン
  2. 「Chaos Infrastructures」メニューに移動
  3. 「Enable Chaos Infrastructure」をクリック
  4. Infrastructure名、説明、スコープ(Cluster/Namespace)を指定
  5. 生成されたマニフェストをターゲットクラスタに適用

CLI経由の場合:

# ChaosCenter APIからインフラマニフェストを取得
curl -X POST \
  "http://${CHAOS_URL}:8080/api/query" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ${TOKEN}" \
  -d '{
    "query": "mutation { registerInfra(projectID: \"<PROJECT_ID>\", request: { name: \"prod-cluster\", infraScope: CLUSTER, environmentID: \"<ENV_ID>\", platformName: \"Kubernetes\", infraNamespace: \"litmus\", skipSsl: false, infraNsExists: true }) { token infraID name manifest } }"
  }'

# 取得したマニフェストをターゲットクラスタに適用
kubectl apply -f infra-manifest.yaml

4.4 Chaos Infrastructure の接続確認

# Chaos Infrastructure のステータス確認
kubectl get pods -n litmus

# 期待される出力:
# NAME                                     READY   STATUS    RESTARTS   AGE
# chaos-operator-ce-7b5c4d8f9-xxxxx        1/1     Running   0          5m
# subscriber-7c8d9e0f1-xxxxx               1/1     Running   0          5m
# workflow-controller-6b7c8d9e0-xxxxx       1/1     Running   0          5m
# chaos-exporter-5a6b7c8d9-xxxxx           1/1     Running   0          5m

# ChaosCenter でのインフラ接続確認
kubectl get chaosinfra -n litmus

4.5 ネットワークポリシーの設定

セキュリティ要件に応じてネットワークポリシーを設定する。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: litmus-server-policy
  namespace: litmus
spec:
  podSelector:
    matchLabels:
      component: litmusportal-server
  policyTypes:
    - Ingress
    - Egress
  ingress:
    # Frontendからのアクセスを許可
    - from:
        - podSelector:
            matchLabels:
              component: litmusportal-frontend
      ports:
        - protocol: TCP
          port: 8080
    # Subscriberからのアクセスを許可(gRPC)
    - from:
        - namespaceSelector: {}
          podSelector:
            matchLabels:
              app: subscriber
      ports:
        - protocol: TCP
          port: 8080
  egress:
    # MongoDBへのアクセスを許可
    - to:
        - podSelector:
            matchLabels:
              app: mongodb
      ports:
        - protocol: TCP
          port: 27017
    # DNS解決を許可
    - to:
        - namespaceSelector: {}
      ports:
        - protocol: UDP
          port: 53

5. カオス実験の種類

Litmus は広範なカオス実験を提供している。以下にカテゴリ別に主要な実験を解説する。

5.1 Pod レベルのカオス実験

5.1.1 pod-delete

最も基本的なカオス実験であり、対象 Pod を強制削除してアプリケーションの自己回復能力を検証する。

apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: pod-delete-chaos
  namespace: default
spec:
  engineState: "active"
  appinfo:
    appns: "default"
    applabel: "app=web-server"
    appkind: "deployment"
  chaosServiceAccount: pod-delete-sa
  experiments:
    - name: pod-delete
      spec:
        components:
          env:
            # カオス持続時間(秒)
            - name: TOTAL_CHAOS_DURATION
              value: "60"
            # Pod削除の間隔(秒)
            - name: CHAOS_INTERVAL
              value: "15"
            # 強制削除(GracePeriod=0)
            - name: FORCE
              value: "true"
            # 影響するPodの割合(%)
            - name: PODS_AFFECTED_PERC
              value: "50"
            # ランプアップ時間(秒)
            - name: RAMP_TIME
              value: "10"
            # 実行順序(parallel/serial)
            - name: SEQUENCE
              value: "parallel"

パラメータ詳細:

パラメータ説明デフォルト値
TOTAL_CHAOS_DURATION実験の総持続時間(秒)30
CHAOS_INTERVALPod削除の間隔(秒)10
FORCE強制削除(GracePeriod=0)true
PODS_AFFECTED_PERC影響するPodの割合0(全Pod)
TARGET_PODS特定のPod名を指定""(ラベル選択)
RAMP_TIME実験開始前の待機時間0
SEQUENCEPod削除の順序parallel

5.1.2 container-kill

特定のコンテナプロセスを kill し、コンテナランタイムの回復能力を検証する。

apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: container-kill-chaos
  namespace: default
spec:
  engineState: "active"
  appinfo:
    appns: "default"
    applabel: "app=web-server"
    appkind: "deployment"
  chaosServiceAccount: container-kill-sa
  experiments:
    - name: container-kill
      spec:
        components:
          env:
            - name: TARGET_CONTAINER
              value: "nginx"
            - name: TOTAL_CHAOS_DURATION
              value: "60"
            - name: CHAOS_INTERVAL
              value: "10"
            - name: CONTAINER_RUNTIME
              value: "containerd"
            - name: SOCKET_PATH
              value: "/run/containerd/containerd.sock"
            # シグナル指定(SIGKILL=9, SIGTERM=15)
            - name: SIGNAL
              value: "SIGKILL"

5.1.3 pod-cpu-hog / pod-memory-hog

Pod 内でCPUまたはメモリのストレスを生成し、リソース制限とスロットリングの動作を検証する。

# Pod CPU Hog
apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: pod-cpu-hog-chaos
  namespace: default
spec:
  engineState: "active"
  appinfo:
    appns: "default"
    applabel: "app=web-server"
    appkind: "deployment"
  chaosServiceAccount: pod-cpu-hog-sa
  experiments:
    - name: pod-cpu-hog
      spec:
        components:
          env:
            # 使用するCPUコア数
            - name: CPU_CORES
              value: "2"
            # CPUロード(ミリコア)
            - name: CPU_LOAD
              value: "100"
            - name: TOTAL_CHAOS_DURATION
              value: "120"
            - name: PODS_AFFECTED_PERC
              value: "100"
            # ストレスイメージ
            - name: LIB_IMAGE
              value: "litmuschaos/go-runner:3.9.0"
# Pod Memory Hog
apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: pod-memory-hog-chaos
  namespace: default
spec:
  engineState: "active"
  appinfo:
    appns: "default"
    applabel: "app=web-server"
    appkind: "deployment"
  chaosServiceAccount: pod-memory-hog-sa
  experiments:
    - name: pod-memory-hog
      spec:
        components:
          env:
            # 消費するメモリ量(MB)
            - name: MEMORY_CONSUMPTION
              value: "500"
            - name: TOTAL_CHAOS_DURATION
              value: "120"
            - name: PODS_AFFECTED_PERC
              value: "50"

5.1.4 pod-io-stress

Pod 内のディスクI/Oにストレスをかけ、ストレージ性能低下時のアプリケーション挙動を検証する。

apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: pod-io-stress-chaos
  namespace: default
spec:
  engineState: "active"
  appinfo:
    appns: "default"
    applabel: "app=database"
    appkind: "statefulset"
  chaosServiceAccount: pod-io-stress-sa
  experiments:
    - name: pod-io-stress
      spec:
        components:
          env:
            # I/Oワーカー数
            - name: FILESYSTEM_UTILIZATION_PERCENTAGE
              value: "80"
            - name: NUMBER_OF_WORKERS
              value: "4"
            # I/Oブロックサイズ
            - name: FILESYSTEM_UTILIZATION_BYTES
              value: "0"
            - name: TOTAL_CHAOS_DURATION
              value: "120"
            - name: VOLUME_MOUNT_PATH
              value: "/data"

5.2 Node レベルのカオス実験

5.2.1 node-drain

Kubernetes ノードを drain し、ワークロードの再スケジューリング能力を検証する。

apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: node-drain-chaos
  namespace: litmus
spec:
  engineState: "active"
  auxiliaryAppInfo: ""
  chaosServiceAccount: node-drain-sa
  experiments:
    - name: node-drain
      spec:
        components:
          env:
            # ターゲットノード名
            - name: TARGET_NODE
              value: "worker-node-1"
            - name: TOTAL_CHAOS_DURATION
              value: "90"
          nodeSelector:
            kubernetes.io/os: linux

5.2.2 node-taint

ノードに taint を追加し、スケジューリングへの影響を検証する。

apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: node-taint-chaos
  namespace: litmus
spec:
  engineState: "active"
  chaosServiceAccount: node-taint-sa
  experiments:
    - name: node-taint
      spec:
        components:
          env:
            - name: TARGET_NODE
              value: "worker-node-2"
            - name: TOTAL_CHAOS_DURATION
              value: "120"
            # Taint の Effect
            - name: TAINT_LABEL
              value: "chaos=true:NoSchedule"

5.2.3 node-cpu-hog / node-memory-hog

ノードレベルでCPU/メモリのストレスを生成する。

apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: node-cpu-hog-chaos
  namespace: litmus
spec:
  engineState: "active"
  chaosServiceAccount: node-cpu-hog-sa
  experiments:
    - name: node-cpu-hog
      spec:
        components:
          env:
            - name: TARGET_NODE
              value: "worker-node-1"
            - name: NODE_CPU_CORE
              value: "4"
            - name: CPU_LOAD
              value: "90"
            - name: TOTAL_CHAOS_DURATION
              value: "120"

5.3 Network レベルのカオス実験

5.3.1 pod-network-loss

ネットワークパケットロスを発生させ、アプリケーションの耐障害性を検証する。

apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: network-loss-chaos
  namespace: default
spec:
  engineState: "active"
  appinfo:
    appns: "default"
    applabel: "app=web-server"
    appkind: "deployment"
  chaosServiceAccount: pod-network-loss-sa
  experiments:
    - name: pod-network-loss
      spec:
        components:
          env:
            # パケットロス率(%)
            - name: NETWORK_INTERFACE
              value: "eth0"
            - name: NETWORK_PACKET_LOSS_PERCENTAGE
              value: "50"
            - name: TOTAL_CHAOS_DURATION
              value: "60"
            # ターゲットサービスのIPまたはホスト
            - name: DESTINATION_IPS
              value: "10.0.0.50"
            - name: DESTINATION_HOSTS
              value: "database-service.default.svc.cluster.local"

5.3.2 pod-network-latency

ネットワーク遅延を注入し、レイテンシ増加時のアプリケーション挙動を検証する。

apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: network-latency-chaos
  namespace: default
spec:
  engineState: "active"
  appinfo:
    appns: "default"
    applabel: "app=web-server"
    appkind: "deployment"
  chaosServiceAccount: pod-network-latency-sa
  experiments:
    - name: pod-network-latency
      spec:
        components:
          env:
            - name: NETWORK_INTERFACE
              value: "eth0"
            # レイテンシ(ミリ秒)
            - name: NETWORK_LATENCY
              value: "500"
            # ジッター(ミリ秒)
            - name: JITTER
              value: "100"
            - name: TOTAL_CHAOS_DURATION
              value: "120"
            - name: DESTINATION_IPS
              value: ""
            - name: DESTINATION_HOSTS
              value: ""

5.3.3 pod-network-corruption

パケットの破損を発生させる。

apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: network-corruption-chaos
  namespace: default
spec:
  engineState: "active"
  appinfo:
    appns: "default"
    applabel: "app=web-server"
    appkind: "deployment"
  chaosServiceAccount: pod-network-corruption-sa
  experiments:
    - name: pod-network-corruption
      spec:
        components:
          env:
            - name: NETWORK_INTERFACE
              value: "eth0"
            # パケット破損率(%)
            - name: NETWORK_PACKET_CORRUPTION_PERCENTAGE
              value: "50"
            - name: TOTAL_CHAOS_DURATION
              value: "60"

5.3.4 pod-network-duplication

パケットの重複を発生させ、冪等性の検証を行う。

apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: network-duplication-chaos
  namespace: default
spec:
  engineState: "active"
  appinfo:
    appns: "default"
    applabel: "app=payment-service"
    appkind: "deployment"
  chaosServiceAccount: pod-network-duplication-sa
  experiments:
    - name: pod-network-duplication
      spec:
        components:
          env:
            - name: NETWORK_INTERFACE
              value: "eth0"
            - name: NETWORK_PACKET_DUPLICATION_PERCENTAGE
              value: "80"
            - name: TOTAL_CHAOS_DURATION
              value: "60"

5.3.5 pod-dns-error / pod-dns-spoof

DNS 解決の障害やスプーフィングを注入する。

# DNS Error
apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: dns-error-chaos
  namespace: default
spec:
  engineState: "active"
  appinfo:
    appns: "default"
    applabel: "app=web-server"
    appkind: "deployment"
  chaosServiceAccount: pod-dns-error-sa
  experiments:
    - name: pod-dns-error
      spec:
        components:
          env:
            # DNS エラーを発生させるドメイン
            - name: TARGET_HOSTNAMES
              value: "api.external-service.com"
            - name: TOTAL_CHAOS_DURATION
              value: "60"
            - name: PODS_AFFECTED_PERC
              value: "100"
# DNS Spoof
apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: dns-spoof-chaos
  namespace: default
spec:
  engineState: "active"
  appinfo:
    appns: "default"
    applabel: "app=web-server"
    appkind: "deployment"
  chaosServiceAccount: pod-dns-spoof-sa
  experiments:
    - name: pod-dns-spoof
      spec:
        components:
          env:
            - name: TARGET_HOSTNAMES
              value: "api.payment-gateway.com"
            # スプーフ先のIP
            - name: SPOOF_MAP
              value: '{"api.payment-gateway.com": "10.0.0.99"}'
            - name: TOTAL_CHAOS_DURATION
              value: "60"

5.4 HTTP Chaos 実験

5.4.1 pod-http-latency

HTTPレスポンスに遅延を注入する。

apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: http-latency-chaos
  namespace: default
spec:
  engineState: "active"
  appinfo:
    appns: "default"
    applabel: "app=web-server"
    appkind: "deployment"
  chaosServiceAccount: pod-http-latency-sa
  experiments:
    - name: pod-http-latency
      spec:
        components:
          env:
            # ターゲットのサービスポート
            - name: TARGET_SERVICE_PORT
              value: "8080"
            # 注入する遅延(ミリ秒)
            - name: LATENCY
              value: "2000"
            # プロキシポート
            - name: PROXY_PORT
              value: "20000"
            - name: TOTAL_CHAOS_DURATION
              value: "60"
            # パスフィルタ
            - name: PATH_FILTER
              value: "/api/v1/orders"

5.4.2 pod-http-status-code

特定のHTTPステータスコードを返す障害を注入する。

apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: http-status-code-chaos
  namespace: default
spec:
  engineState: "active"
  appinfo:
    appns: "default"
    applabel: "app=web-server"
    appkind: "deployment"
  chaosServiceAccount: pod-http-status-code-sa
  experiments:
    - name: pod-http-status-code
      spec:
        components:
          env:
            - name: TARGET_SERVICE_PORT
              value: "8080"
            # 注入するステータスコード
            - name: STATUS_CODE
              value: "503"
            # レスポンスボディの変更
            - name: MODIFY_RESPONSE_BODY
              value: "true"
            - name: RESPONSE_BODY
              value: '{"error": "Service Unavailable - Chaos Test"}'
            - name: TOTAL_CHAOS_DURATION
              value: "60"
            - name: PROXY_PORT
              value: "20000"

5.4.3 pod-http-modify-body / pod-http-modify-header

HTTPリクエスト/レスポンスのボディやヘッダーを改変する。

apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: http-modify-header-chaos
  namespace: default
spec:
  engineState: "active"
  appinfo:
    appns: "default"
    applabel: "app=web-server"
    appkind: "deployment"
  chaosServiceAccount: pod-http-modify-header-sa
  experiments:
    - name: pod-http-modify-header
      spec:
        components:
          env:
            - name: TARGET_SERVICE_PORT
              value: "8080"
            # 追加/変更するヘッダー
            - name: HEADERS_MAP
              value: '{"X-Custom-Header": "chaos-test", "Content-Type": "text/plain"}'
            - name: HEADER_MODE
              value: "response"
            - name: TOTAL_CHAOS_DURATION
              value: "60"
            - name: PROXY_PORT
              value: "20000"

5.5 AWS/GCP/Azure カオス実験

Litmus はクラウドプロバイダー固有のカオス実験もサポートしている。

5.5.1 AWS EC2 Stop

apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: ec2-stop-chaos
  namespace: litmus
spec:
  engineState: "active"
  chaosServiceAccount: ec2-stop-sa
  experiments:
    - name: ec2-terminate-by-id
      spec:
        components:
          env:
            - name: EC2_INSTANCE_ID
              value: "i-0a1b2c3d4e5f6g7h8"
            - name: REGION
              value: "us-west-2"
            - name: TOTAL_CHAOS_DURATION
              value: "60"
          secrets:
            - name: cloud-secret
              mountPath: /tmp/
        components:
          nodeSelector:
            kubernetes.io/os: linux
# AWS認証用Secret
apiVersion: v1
kind: Secret
metadata:
  name: cloud-secret
  namespace: litmus
type: Opaque
stringData:
  cloud_config.yml: |
    [default]
    aws_access_key_id = AKIAIOSFODNN7EXAMPLE
    aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

5.5.2 AWS EBS Loss

apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: ebs-loss-chaos
  namespace: litmus
spec:
  engineState: "active"
  chaosServiceAccount: ebs-loss-sa
  experiments:
    - name: ebs-loss-by-id
      spec:
        components:
          env:
            - name: EBS_VOLUME_ID
              value: "vol-0a1b2c3d4e5f6g7h8"
            - name: REGION
              value: "us-west-2"
            - name: TOTAL_CHAOS_DURATION
              value: "90"
          secrets:
            - name: cloud-secret
              mountPath: /tmp/

5.6 カオス実験一覧表

カテゴリ実験名説明
Podpod-deletePod の強制削除
container-killコンテナプロセスの kill
pod-cpu-hogPod CPU ストレス
pod-memory-hogPod メモリストレス
pod-io-stressPod I/O ストレス
pod-autoscalerPod の自動スケーリング検証
Nodenode-drainノードの drain
node-taintノードの taint
node-cpu-hogノード CPU ストレス
node-memory-hogノード メモリストレス
node-io-stressノード I/O ストレス
node-restartノードの再起動
Networkpod-network-lossパケットロス
pod-network-latencyネットワーク遅延
pod-network-corruptionパケット破損
pod-network-duplicationパケット重複
pod-dns-errorDNS エラー
pod-dns-spoofDNS スプーフィング
HTTPpod-http-latencyHTTP レイテンシ注入
pod-http-status-codeHTTP ステータスコード注入
pod-http-modify-bodyHTTP ボディ改変
pod-http-modify-headerHTTP ヘッダー改変
pod-http-reset-peerHTTP 接続リセット
AWSec2-terminate-by-idEC2 インスタンス停止
ebs-loss-by-idEBS ボリュームデタッチ
aws-az-chaosAZ 障害シミュレーション
GCPgcp-vm-instance-stopGCE インスタンス停止
gcp-vm-disk-lossGCE ディスクロス
Azureazure-instance-stopAzure VM 停止
azure-disk-lossAzure ディスクロス

6. Probe によるバリデーション

6.1 Probe の概要

Probe はカオス実験の成否を判定するためのバリデーション機構である。Litmus は実験中にシステムの状態を自動的に検証し、定常状態の仮説が維持されているかどうかを判定する。

Probe は以下の4種類が提供されている:

  1. httpProbe: HTTP エンドポイントの応答を検証
  2. cmdProbe: コマンドの実行結果を検証
  3. k8sProbe: Kubernetes リソースの状態を検証
  4. promProbe: Prometheus メトリクスを検証

6.2 Probe の実行モード

モード説明ユースケース
SOT (Start of Test)実験開始時に1回だけ実行初期状態の確認
EOT (End of Test)実験終了時に1回だけ実行最終状態の確認
Edge実験の開始時と終了時に実行前後比較
Continuous実験中に継続的に実行リアルタイム監視
OnChaosカオス注入中のみ実行障害中の挙動検証

6.3 httpProbe

HTTP エンドポイントのヘルスチェックを行う。

probe:
  - name: "api-health-check"
    type: "httpProbe"
    mode: "Continuous"
    runProperties:
      probeTimeout: 10s
      retry: 3
      interval: 5s
      # 連続成功回数の閾値
      probePollingInterval: 2s
      initialDelay: 5s
      stopOnFailure: false
    httpProbe/inputs:
      url: "http://api-service.default.svc.cluster.local:8080/health"
      insecureSkipVerify: false
      method:
        get:
          criteria: "=="
          responseCode: "200"
      # レスポンスボディの検証
      responseTimeout: 5000

  - name: "api-response-validation"
    type: "httpProbe"
    mode: "Continuous"
    runProperties:
      probeTimeout: 10s
      retry: 2
      interval: 10s
    httpProbe/inputs:
      url: "http://api-service.default.svc.cluster.local:8080/api/v1/status"
      insecureSkipVerify: false
      method:
        post:
          contentType: "application/json"
          body: '{"check": "deep-health"}'
          criteria: "contains"
          responseCode: "200"
      # ヘッダー付きリクエスト
      headers:
        Authorization: "Bearer ${AUTH_TOKEN}"
        Content-Type: "application/json"

6.4 cmdProbe

任意のコマンドを実行してその結果を検証する。

probe:
  - name: "check-pod-count"
    type: "cmdProbe"
    mode: "Edge"
    runProperties:
      probeTimeout: 30s
      retry: 3
      interval: 5s
      initialDelay: 3s
    cmdProbe/inputs:
      command: "kubectl get pods -n default -l app=web-server --no-headers | grep Running | wc -l"
      source:
        image: "litmuschaos/k8s:3.9.0"
        hostNetwork: false
      comparator:
        type: "int"
        criteria: ">="
        value: "3"

  - name: "check-database-connection"
    type: "cmdProbe"
    mode: "Continuous"
    runProperties:
      probeTimeout: 15s
      retry: 2
      interval: 10s
    cmdProbe/inputs:
      command: "pg_isready -h postgres-service.default.svc.cluster.local -p 5432"
      source:
        image: "postgres:15"
      comparator:
        type: "string"
        criteria: "contains"
        value: "accepting connections"

6.5 k8sProbe

Kubernetes リソースの状態を直接検証する。

probe:
  - name: "check-deployment-ready"
    type: "k8sProbe"
    mode: "EOT"
    runProperties:
      probeTimeout: 60s
      retry: 3
      interval: 10s
    k8sProbe/inputs:
      group: "apps"
      version: "v1"
      resource: "deployments"
      namespace: "default"
      fieldSelector: "metadata.name=web-server"
      operation: "present"

  - name: "check-no-failed-pods"
    type: "k8sProbe"
    mode: "EOT"
    runProperties:
      probeTimeout: 30s
      retry: 2
      interval: 5s
    k8sProbe/inputs:
      group: ""
      version: "v1"
      resource: "pods"
      namespace: "default"
      labelSelector: "app=web-server"
      operation: "present"
      # conditions でステータスを検証
      conditions:
        - jsonPath: "{.items[*].status.phase}"
          operator: "allOf"
          value: "Running"

  - name: "check-pvc-bound"
    type: "k8sProbe"
    mode: "Edge"
    runProperties:
      probeTimeout: 30s
      retry: 3
      interval: 10s
    k8sProbe/inputs:
      group: ""
      version: "v1"
      resource: "persistentvolumeclaims"
      namespace: "default"
      fieldSelector: "metadata.name=data-pvc"
      operation: "present"

6.6 promProbe

Prometheus メトリクスに基づいて検証を行う。

probe:
  - name: "check-error-rate"
    type: "promProbe"
    mode: "Continuous"
    runProperties:
      probeTimeout: 10s
      retry: 2
      interval: 15s
    promProbe/inputs:
      endpoint: "http://prometheus-server.monitoring.svc.cluster.local:9090"
      query: 'sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) * 100'
      comparator:
        type: "float"
        criteria: "<="
        value: "5.0"

  - name: "check-latency-p99"
    type: "promProbe"
    mode: "Continuous"
    runProperties:
      probeTimeout: 10s
      retry: 2
      interval: 15s
    promProbe/inputs:
      endpoint: "http://prometheus-server.monitoring.svc.cluster.local:9090"
      query: 'histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))'
      comparator:
        type: "float"
        criteria: "<="
        value: "2.0"

  - name: "check-memory-usage"
    type: "promProbe"
    mode: "OnChaos"
    runProperties:
      probeTimeout: 10s
      retry: 3
      interval: 30s
    promProbe/inputs:
      endpoint: "http://prometheus-server.monitoring.svc.cluster.local:9090"
      query: 'container_memory_working_set_bytes{namespace="default",container="web-server"} / container_spec_memory_limit_bytes{namespace="default",container="web-server"} * 100'
      comparator:
        type: "float"
        criteria: "<="
        value: "85.0"

6.7 Probe のベストプラクティス

  1. 必ず Continuous モードの Probe を含める: 実験中のリアルタイム検証が重要
  2. Edge モードで前後比較を行う: 実験がシステムに永続的な影響を与えていないことを確認
  3. SLO に基づいた閾値を設定する: Probe の判定基準はサービスレベル目標と整合させる
  4. 複数種類の Probe を組み合わせる: HTTP、Prometheus、k8s の各層で検証を行う
  5. 適切なタイムアウトとリトライを設定する: 一時的な揺らぎによる偽陽性を防ぐ

7. ChaosHub

7.1 ChaosHub の概要

ChaosHub はカオス実験のカタログリポジトリであり、再利用可能な実験テンプレートを管理・共有するための仕組みである。Litmus はデフォルトで公式の ChaosHub(Litmus ChaosHub)を提供しているが、カスタムのプライベート ChaosHub を作成することも可能である。

7.2 デフォルト ChaosHub

Litmus の公式 ChaosHub は GitHub リポジトリ https://github.com/litmuschaos/chaos-charts でホストされており、以下のカテゴリの実験が含まれている:

  • Kubernetes: Pod、Node、Network、Stress 関連の実験
  • AWS: EC2、EBS、Lambda 関連の実験
  • GCP: VM、Disk 関連の実験
  • Azure: VM、Disk 関連の実験
  • VMware: vSphere VM 関連の実験
  • Linux: プロセス、ネットワーク、ファイルシステム関連の実験

7.3 ChaosHub のディレクトリ構造

chaos-charts/
├── charts/
│   ├── generic/
│   │   ├── pod-delete/
│   │   │   ├── fault.yaml          # ChaosExperiment CRD
│   │   │   ├── engine.yaml         # ChaosEngine テンプレート
│   │   │   ├── rbac.yaml           # RBAC 設定
│   │   │   ├── icons/
│   │   │   │   └── pod-delete.png
│   │   │   └── experiment.yaml     # 実験メタデータ
│   │   ├── pod-network-loss/
│   │   ├── node-drain/
│   │   └── ...
│   ├── aws/
│   │   ├── ec2-terminate-by-id/
│   │   ├── ebs-loss-by-id/
│   │   └── ...
│   └── gcp/
│       ├── gcp-vm-instance-stop/
│       └── ...
└── README.md

7.4 カスタム ChaosHub の作成

プライベートなカオス実験カタログを作成する手順を示す。

7.4.1 GitリポジトリのHub登録

# ChaosCenter APIでカスタムHubを登録
mutation {
  addChaosHub(
    projectID: "project-id-here"
    request: {
      name: "my-custom-hub"
      repoURL: "https://github.com/my-org/chaos-experiments.git"
      repoBranch: "main"
      isPrivate: true
      authType: TOKEN
      token: "ghp_xxxxxxxxxxxxxxxxxxxx"
      hubType: GIT
    }
  ) {
    id
    name
    repoURL
    repoBranch
    isAvailable
    lastSyncedAt
  }
}

7.4.2 カスタム実験の作成

# my-custom-experiment/fault.yaml
apiVersion: litmuschaos.io/v1alpha1
kind: ChaosExperiment
metadata:
  name: custom-service-restart
spec:
  definition:
    scope: Namespaced
    permissions:
      - apiGroups: [""]
        resources: ["pods", "pods/exec"]
        verbs: ["create", "delete", "get", "list"]
      - apiGroups: ["litmuschaos.io"]
        resources: ["chaosengines", "chaosexperiments", "chaosresults"]
        verbs: ["create", "delete", "get", "list", "patch", "update"]
    image: my-registry/custom-chaos-runner:1.0.0
    imagePullPolicy: Always
    args:
      - -c
      - python3 /app/custom_experiment.py
    command:
      - /bin/bash
    env:
      - name: SERVICE_NAME
        value: ""
      - name: RESTART_METHOD
        value: "rolling"
      - name: TOTAL_CHAOS_DURATION
        value: "60"
      - name: CHAOS_INTERVAL
        value: "15"
    labels:
      name: custom-service-restart
# my-custom-experiment/experiment.yaml(メタデータ)
apiVersion: litmuchaos.io/v1alpha1
description:
  message: "Custom service restart experiment for our microservices"
metadata:
  name: custom-service-restart
  version: 1.0.0
  annotations:
    chartDescription: "Performs a rolling restart of the target service"
    categories: "custom,service-level"
    vendor: "My Organization"
    support: "https://internal-wiki.example.com/chaos-experiments"
spec:
  displayName: "Custom Service Restart"
  categoryDescription: "Verifies the application's resilience during rolling restarts"
  keywords:
    - "service"
    - "restart"
    - "rolling-update"
  platforms:
    - "Kubernetes"
  maturity: "stable"
  faultTypes:
    - "service-level"
  prerequisites:
    - "Target deployment must have readiness probes configured"
    - "PodDisruptionBudget should be set"

7.5 ChaosHub の同期

ChaosHub は定期的にGitリポジトリと同期される。手動同期も可能である。

# 手動同期
mutation {
  syncChaosHub(
    projectID: "project-id-here"
    id: "hub-id-here"
  ) {
    id
    name
    lastSyncedAt
    isAvailable
  }
}

8. GitOps統合

8.1 GitOps の概要

Litmus の GitOps 機能により、カオス実験のワークフロー定義を Git リポジトリで管理し、リポジトリの変更をトリガーとして自動的にカオス実験を実行できる。

8.2 GitOps ワークフロー

┌──────────────┐     ┌──────────────┐     ┌──────────────────┐
│  Git Repo    │────→│  ChaosCenter │────→│  Chaos           │
│  (定義変更)   │     │  (検知・配信)  │     │  Infrastructure  │
│              │     │              │     │  (実験実行)        │
└──────────────┘     └──────────────┘     └──────────────────┘
       ↑                    │
       │                    │
       └────────────────────┘
          実験結果をGitにコミット

8.3 GitOps の設定

8.3.1 ChaosCenter での GitOps 有効化

mutation {
  enableGitOps(
    projectID: "project-id-here"
    configurations: {
      repoURL: "https://github.com/my-org/chaos-gitops.git"
      branch: "main"
      authType: TOKEN
      token: "ghp_xxxxxxxxxxxxxxxxxxxx"
    }
  )
}

8.3.2 GitOps リポジトリ構造

chaos-gitops/
├── environments/
│   ├── staging/
│   │   ├── workflow-pod-delete.yaml
│   │   ├── workflow-network-chaos.yaml
│   │   └── workflow-comprehensive.yaml
│   └── production/
│       ├── workflow-pod-delete.yaml
│       └── workflow-network-chaos.yaml
├── schedules/
│   ├── daily-resilience-test.yaml
│   └── weekly-comprehensive-test.yaml
└── README.md

8.3.3 Event-Driven GitOps

Git リポジトリへのプッシュをトリガーにした自動実験実行フロー:

# .github/workflows/chaos-gitops.yaml
name: Chaos Engineering GitOps
on:
  push:
    branches: [main]
    paths:
      - 'environments/**'
      - 'schedules/**'

jobs:
  trigger-chaos:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Detect Changed Workflows
        id: changes
        run: |
          CHANGED_FILES=$(git diff --name-only HEAD~1 HEAD -- 'environments/' 'schedules/')
          echo "changed_files=${CHANGED_FILES}" >> $GITHUB_OUTPUT

      - name: Notify ChaosCenter
        run: |
          curl -X POST \
            "${{ secrets.CHAOS_CENTER_URL }}/api/query" \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer ${{ secrets.CHAOS_TOKEN }}" \
            -d '{
              "query": "mutation { gitopsNotify(clusterInfo: { clusterID: \"${{ secrets.CLUSTER_ID }}\", accessKey: \"${{ secrets.ACCESS_KEY }}\" }) }"
            }'

8.4 スケジュール実行

ChaosCenter はCRON式による定期的なカオス実験のスケジュール実行をサポートする。

# ChaosCenter UIまたはAPIでスケジュール設定
# 毎日午前2時(UTC)に実行
schedule:
  type: "cron"
  cron: "0 2 * * *"
  
# 毎週月曜日の午前3時に実行
schedule:
  type: "cron"
  cron: "0 3 * * 1"

# 即座に1回だけ実行
schedule:
  type: "now"

9. CI/CDパイプライン統合

9.1 CI/CD統合の意義

カオスエンジニアリングをCI/CDパイプラインに組み込むことで、デプロイ前にアプリケーションのレジリエンスを自動的に検証できる。これにより「Shift-Left」のアプローチでカオステストを開発サイクルの早い段階に組み込むことが可能となる。

9.2 GitHub Actions との統合

# .github/workflows/chaos-test.yaml
name: Resilience Test Pipeline

on:
  pull_request:
    branches: [main]
  workflow_dispatch:

env:
  CHAOS_CENTER_URL: ${{ secrets.CHAOS_CENTER_URL }}
  CHAOS_API_TOKEN: ${{ secrets.CHAOS_API_TOKEN }}
  PROJECT_ID: ${{ secrets.CHAOS_PROJECT_ID }}

jobs:
  deploy-staging:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Deploy to Staging
        run: |
          kubectl apply -f k8s/staging/ --namespace staging

      - name: Wait for Deployment Ready
        run: |
          kubectl rollout status deployment/web-server \
            --namespace staging --timeout=300s

  chaos-test:
    needs: deploy-staging
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Run Pod Delete Chaos Test
        uses: litmuschaos/github-chaos-actions@v2
        env:
          EXPERIMENT_NAME: pod-delete
          EXPERIMENT_NAMESPACE: staging
          APP_NS: staging
          APP_LABEL: app=web-server
          APP_KIND: deployment
          TOTAL_CHAOS_DURATION: "30"
          CHAOS_INTERVAL: "10"
          FORCE: "true"
          PODS_AFFECTED_PERC: "50"

      - name: Run Network Latency Chaos Test
        uses: litmuschaos/github-chaos-actions@v2
        env:
          EXPERIMENT_NAME: pod-network-latency
          EXPERIMENT_NAMESPACE: staging
          APP_NS: staging
          APP_LABEL: app=web-server
          APP_KIND: deployment
          NETWORK_LATENCY: "300"
          TOTAL_CHAOS_DURATION: "60"

      - name: Verify Resilience Score
        run: |
          SCORE=$(curl -s -X POST \
            "${CHAOS_CENTER_URL}/api/query" \
            -H "Content-Type: application/json" \
            -H "Authorization: Bearer ${CHAOS_API_TOKEN}" \
            -d '{
              "query": "query { getWorkflowRunStats(projectID: \"'${PROJECT_ID}'\", workflowRunStatsRequest: { workflowRunIds: [\"'${WORKFLOW_RUN_ID}'\"] }) { resilienceScore } }"
            }' | jq '.data.getWorkflowRunStats[0].resilienceScore')
          
          echo "Resilience Score: ${SCORE}"
          
          if (( $(echo "${SCORE} < 80" | bc -l) )); then
            echo "ERROR: Resilience Score ${SCORE} is below threshold (80)"
            exit 1
          fi

      - name: Upload Chaos Results
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: chaos-results
          path: chaos-results/

  promote-to-production:
    needs: chaos-test
    runs-on: ubuntu-latest
    if: success()
    steps:
      - name: Promote to Production
        run: |
          echo "Chaos tests passed. Promoting to production..."
          kubectl apply -f k8s/production/ --namespace production

      - name: Notify Success
        run: |
          curl -X POST "${{ secrets.SLACK_WEBHOOK }}" \
            -H 'Content-type: application/json' \
            -d '{"text": "Chaos tests passed with score '${SCORE}'. Deployment promoted to production."}'

9.3 Tekton Pipelines との統合

# Tekton Task for Litmus Chaos
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: litmus-chaos-test
  namespace: tekton-pipelines
spec:
  params:
    - name: experiment-name
      type: string
      description: "Name of the chaos experiment to run"
    - name: app-namespace
      type: string
      description: "Target application namespace"
    - name: app-label
      type: string
      description: "Target application label"
    - name: chaos-duration
      type: string
      default: "30"
    - name: resilience-threshold
      type: string
      default: "80"
  steps:
    - name: install-experiment
      image: litmuschaos/k8s:3.9.0
      command: ["kubectl"]
      args:
        - apply
        - -f
        - "https://hub.litmuschaos.io/api/chaos/3.9.0?file=faults/kubernetes/$(params.experiment-name)/fault.yaml"
        - -n
        - $(params.app-namespace)

    - name: create-chaos-engine
      image: litmuschaos/k8s:3.9.0
      script: |
        cat <<EOF | kubectl apply -f -
        apiVersion: litmuschaos.io/v1alpha1
        kind: ChaosEngine
        metadata:
          name: tekton-$(params.experiment-name)
          namespace: $(params.app-namespace)
        spec:
          engineState: active
          appinfo:
            appns: $(params.app-namespace)
            applabel: $(params.app-label)
            appkind: deployment
          chaosServiceAccount: litmus-admin
          experiments:
            - name: $(params.experiment-name)
              spec:
                components:
                  env:
                    - name: TOTAL_CHAOS_DURATION
                      value: "$(params.chaos-duration)"
        EOF

    - name: wait-for-completion
      image: litmuschaos/k8s:3.9.0
      script: |
        while true; do
          STATUS=$(kubectl get chaosresult \
            tekton-$(params.experiment-name)-$(params.experiment-name) \
            -n $(params.app-namespace) \
            -o jsonpath='{.status.experimentStatus.phase}' 2>/dev/null)
          if [ "$STATUS" = "Completed" ]; then
            VERDICT=$(kubectl get chaosresult \
              tekton-$(params.experiment-name)-$(params.experiment-name) \
              -n $(params.app-namespace) \
              -o jsonpath='{.status.experimentStatus.verdict}')
            echo "Experiment completed with verdict: $VERDICT"
            if [ "$VERDICT" = "Pass" ]; then
              exit 0
            else
              echo "Chaos experiment failed!"
              exit 1
            fi
          fi
          echo "Waiting for experiment to complete... Status: $STATUS"
          sleep 10
        done

    - name: cleanup
      image: litmuschaos/k8s:3.9.0
      command: ["kubectl"]
      args:
        - delete
        - chaosengine
        - "tekton-$(params.experiment-name)"
        - -n
        - $(params.app-namespace)
        - --ignore-not-found=true
# Tekton Pipeline
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: resilience-test-pipeline
spec:
  params:
    - name: app-namespace
      type: string
    - name: app-label
      type: string
  tasks:
    - name: pod-delete-test
      taskRef:
        name: litmus-chaos-test
      params:
        - name: experiment-name
          value: "pod-delete"
        - name: app-namespace
          value: "$(params.app-namespace)"
        - name: app-label
          value: "$(params.app-label)"
        - name: chaos-duration
          value: "30"

    - name: network-latency-test
      taskRef:
        name: litmus-chaos-test
      runAfter: ["pod-delete-test"]
      params:
        - name: experiment-name
          value: "pod-network-latency"
        - name: app-namespace
          value: "$(params.app-namespace)"
        - name: app-label
          value: "$(params.app-label)"
        - name: chaos-duration
          value: "60"

9.4 Jenkins との統合

// Jenkinsfile
pipeline {
    agent any
    
    environment {
        CHAOS_CENTER_URL = credentials('chaos-center-url')
        CHAOS_API_TOKEN = credentials('chaos-api-token')
        KUBECONFIG = credentials('kubeconfig')
    }
    
    stages {
        stage('Deploy to Staging') {
            steps {
                sh 'kubectl apply -f k8s/staging/ --namespace staging'
                sh 'kubectl rollout status deployment/web-server --namespace staging --timeout=300s'
            }
        }
        
        stage('Chaos Test - Pod Delete') {
            steps {
                script {
                    sh '''
                    kubectl apply -f - <<EOF
                    apiVersion: litmuschaos.io/v1alpha1
                    kind: ChaosEngine
                    metadata:
                      name: jenkins-pod-delete
                      namespace: staging
                    spec:
                      engineState: active
                      appinfo:
                        appns: staging
                        applabel: app=web-server
                        appkind: deployment
                      chaosServiceAccount: litmus-admin
                      experiments:
                        - name: pod-delete
                          spec:
                            components:
                              env:
                                - name: TOTAL_CHAOS_DURATION
                                  value: "30"
                                - name: FORCE
                                  value: "true"
                    EOF
                    '''
                    
                    // 実験完了を待機
                    timeout(time: 5, unit: 'MINUTES') {
                        waitUntil {
                            def status = sh(
                                script: "kubectl get chaosresult jenkins-pod-delete-pod-delete -n staging -o jsonpath='{.status.experimentStatus.phase}' 2>/dev/null || echo 'Pending'",
                                returnStdout: true
                            ).trim()
                            return status == 'Completed'
                        }
                    }
                }
            }
        }
        
        stage('Validate Results') {
            steps {
                script {
                    def verdict = sh(
                        script: "kubectl get chaosresult jenkins-pod-delete-pod-delete -n staging -o jsonpath='{.status.experimentStatus.verdict}'",
                        returnStdout: true
                    ).trim()
                    
                    if (verdict != 'Pass') {
                        error "Chaos experiment failed with verdict: ${verdict}"
                    }
                    echo "Chaos experiment passed!"
                }
            }
        }
        
        stage('Promote to Production') {
            when {
                expression { currentBuild.result == null || currentBuild.result == 'SUCCESS' }
            }
            steps {
                sh 'kubectl apply -f k8s/production/ --namespace production'
            }
        }
    }
    
    post {
        always {
            sh 'kubectl delete chaosengine jenkins-pod-delete -n staging --ignore-not-found=true'
        }
        failure {
            slackSend(
                channel: '#chaos-engineering',
                message: "Chaos test failed in build ${env.BUILD_NUMBER}"
            )
        }
    }
}

10. モニタリングと観測性

10.1 Prometheus メトリクス

Litmus は Chaos Exporter コンポーネントを通じて Prometheus メトリクスを公開する。

10.1.1 Chaos Exporter のデプロイ

apiVersion: apps/v1
kind: Deployment
metadata:
  name: chaos-exporter
  namespace: litmus
spec:
  replicas: 1
  selector:
    matchLabels:
      app: chaos-exporter
  template:
    metadata:
      labels:
        app: chaos-exporter
    spec:
      serviceAccountName: litmus-admin
      containers:
        - name: chaos-exporter
          image: litmuschaos/chaos-exporter:3.9.0
          ports:
            - containerPort: 8080
              name: metrics
          env:
            - name: CHAOSENGINE_NAMESPACE
              value: ""
            - name: TSDB_SCRAPE_INTERVAL
              value: "10"
---
apiVersion: v1
kind: Service
metadata:
  name: chaos-exporter
  namespace: litmus
  labels:
    app: chaos-exporter
spec:
  ports:
    - port: 8080
      targetPort: 8080
      name: metrics
  selector:
    app: chaos-exporter
---
# Prometheus ServiceMonitor
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: chaos-exporter
  namespace: monitoring
  labels:
    release: prometheus
spec:
  namespaceSelector:
    matchNames:
      - litmus
  selector:
    matchLabels:
      app: chaos-exporter
  endpoints:
    - port: metrics
      interval: 10s
      path: /metrics

10.1.2 公開されるメトリクス

メトリクス名タイプ説明
litmuschaos_experiment_verdictGauge実験の判定結果(Pass=1, Fail=0)
litmuschaos_experiment_phaseGauge実験のフェーズ
litmuschaos_probe_success_percentageGaugeProbeの成功率
litmuschaos_experiment_chaos_injected_totalCounterカオス注入の総回数
litmuschaos_engine_total_experimentsGaugeエンジンの総実験数
litmuschaos_engine_passed_experimentsGauge成功した実験数
litmuschaos_engine_failed_experimentsGauge失敗した実験数
litmuschaos_awaited_experimentsGauge待機中の実験数

10.2 Grafana ダッシュボード

{
  "dashboard": {
    "title": "Litmus Chaos Engineering Dashboard",
    "panels": [
      {
        "title": "Experiment Verdict Overview",
        "type": "stat",
        "targets": [
          {
            "expr": "sum(litmuschaos_experiment_verdict{verdict='Pass'})",
            "legendFormat": "Passed"
          },
          {
            "expr": "sum(litmuschaos_experiment_verdict{verdict='Fail'})",
            "legendFormat": "Failed"
          }
        ]
      },
      {
        "title": "Resilience Score Over Time",
        "type": "timeseries",
        "targets": [
          {
            "expr": "avg(litmuschaos_probe_success_percentage) by (chaosengine_name)",
            "legendFormat": "{{chaosengine_name}}"
          }
        ]
      },
      {
        "title": "Chaos Injection Rate",
        "type": "graph",
        "targets": [
          {
            "expr": "rate(litmuschaos_experiment_chaos_injected_total[5m])",
            "legendFormat": "Injection Rate"
          }
        ]
      },
      {
        "title": "Active Chaos Experiments",
        "type": "table",
        "targets": [
          {
            "expr": "litmuschaos_experiment_phase{phase='Running'}",
            "format": "table",
            "legendFormat": ""
          }
        ]
      },
      {
        "title": "Application Error Rate During Chaos",
        "type": "timeseries",
        "targets": [
          {
            "expr": "sum(rate(http_requests_total{status=~'5..'}[5m])) / sum(rate(http_requests_total[5m])) * 100",
            "legendFormat": "Error Rate %"
          }
        ]
      },
      {
        "title": "P99 Latency During Chaos",
        "type": "timeseries",
        "targets": [
          {
            "expr": "histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))",
            "legendFormat": "P99 Latency"
          }
        ]
      }
    ]
  }
}

10.3 アラート設定

# PrometheusRule for Litmus Chaos alerts
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: litmus-chaos-alerts
  namespace: monitoring
spec:
  groups:
    - name: litmus-chaos
      rules:
        - alert: ChaosExperimentFailed
          expr: litmuschaos_experiment_verdict{verdict="Fail"} == 1
          for: 0m
          labels:
            severity: warning
          annotations:
            summary: "Chaos experiment {{ $labels.chaosengine_name }} failed"
            description: "The chaos experiment {{ $labels.experiment_name }} in namespace {{ $labels.chaosengine_namespace }} has failed"

        - alert: LowResilienceScore
          expr: avg(litmuschaos_probe_success_percentage) by (chaosengine_name) < 70
          for: 0m
          labels:
            severity: critical
          annotations:
            summary: "Low resilience score for {{ $labels.chaosengine_name }}"
            description: "Resilience score is {{ $value }}% which is below the 70% threshold"

        - alert: HighErrorRateDuringChaos
          expr: |
            (sum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) * 100) > 10
            and on() litmuschaos_experiment_phase{phase="Running"} > 0
          for: 2m
          labels:
            severity: critical
          annotations:
            summary: "High error rate detected during chaos experiment"
            description: "Error rate is {{ $value }}% while chaos experiment is running"

        - alert: ChaosExporterDown
          expr: up{job="chaos-exporter"} == 0
          for: 5m
          labels:
            severity: warning
          annotations:
            summary: "Chaos Exporter is down"
            description: "Chaos Exporter has been unreachable for more than 5 minutes"

10.4 Logging統合

# Fluentd ConfigMap for Litmus logs
apiVersion: v1
kind: ConfigMap
metadata:
  name: fluentd-litmus-config
  namespace: logging
data:
  litmus.conf: |
    <source>
      @type tail
      path /var/log/containers/chaos-*.log
      pos_file /var/log/fluentd-litmus.pos
      tag litmus.*
      <parse>
        @type json
        time_key time
        time_format %Y-%m-%dT%H:%M:%S.%NZ
      </parse>
    </source>

    <filter litmus.**>
      @type record_transformer
      <record>
        source litmus-chaos
        cluster ${ENV['CLUSTER_NAME']}
      </record>
    </filter>

    <match litmus.**>
      @type elasticsearch
      host elasticsearch.logging.svc.cluster.local
      port 9200
      index_name litmus-chaos-logs
      type_name _doc
    </match>

11. マルチテナントとRBAC

11.1 プロジェクトベースのマルチテナンシー

Litmus ChaosCenter はプロジェクトを単位としたマルチテナンシーを提供する。各プロジェクトは独立した環境を持ち、独自のChaos Infrastructure、ワークフロー、ChaosHub、メンバーを管理できる。

ChaosCenter
├── Project: platform-team
│   ├── Chaos Infra: staging-cluster
│   ├── Chaos Infra: production-cluster
│   ├── Workflows: [pod-delete-test, network-chaos-test]
│   └── Members: [alice(Owner), bob(Editor), charlie(Viewer)]
├── Project: payment-team
│   ├── Chaos Infra: payment-staging
│   ├── Workflows: [payment-resilience-test]
│   └── Members: [dave(Owner), eve(Editor)]
└── Project: data-team
    ├── Chaos Infra: data-pipeline-cluster
    ├── Workflows: [kafka-chaos-test, redis-chaos-test]
    └── Members: [frank(Owner), grace(Viewer)]

11.2 ロールと権限

Litmus は3つのプロジェクトレベルロールを定義している。

ロール権限
Ownerプロジェクトの全権限(メンバー管理、削除含む)
Editorワークフローの作成・実行・編集、Chaos Infraの管理
Viewerワークフローと結果の閲覧のみ
# メンバーの招待
mutation {
  sendInvitation(
    projectID: "project-id-here"
    request: {
      userID: "user-id-here"
      role: EDITOR
    }
  ) {
    userID
    role
    invitation
  }
}

11.3 OIDC/LDAP 統合認証

# Dex を使用した OIDC 設定
# values.yaml の認証設定部分
portal:
  server:
    authServer:
      env:
        DEX_ENABLED: "true"
        DEX_CALLBACK_URL: "https://chaos.example.com/auth/dex/callback"

# Dex の設定
dex:
  enabled: true
  config:
    issuer: https://chaos.example.com/auth/dex
    storage:
      type: kubernetes
      config:
        inCluster: true
    web:
      http: 0.0.0.0:5556
    connectors:
      # LDAP 接続
      - type: ldap
        id: ldap
        name: LDAP
        config:
          host: ldap.example.com:636
          insecureNoSSL: false
          insecureSkipVerify: false
          rootCA: /etc/dex/ldap-ca.pem
          bindDN: cn=admin,dc=example,dc=com
          bindPW: admin-password
          userSearch:
            baseDN: ou=users,dc=example,dc=com
            filter: "(objectClass=person)"
            username: uid
            idAttr: uid
            emailAttr: mail
            nameAttr: displayName
          groupSearch:
            baseDN: ou=groups,dc=example,dc=com
            filter: "(objectClass=groupOfNames)"
            userMatchers:
              - userAttr: DN
                groupAttr: member
            nameAttr: cn

      # OIDC 接続(例: Keycloak)
      - type: oidc
        id: keycloak
        name: Keycloak
        config:
          issuer: https://keycloak.example.com/realms/chaos
          clientID: litmus-chaoscenter
          clientSecret: $KEYCLOAK_CLIENT_SECRET
          redirectURI: https://chaos.example.com/auth/dex/callback
          scopes:
            - openid
            - profile
            - email
            - groups
          getUserInfo: true
          userNameKey: preferred_username

11.4 Namespace レベルのアクセス制御

Kubernetes RBAC と連携して、Chaos Infrastructure のアクセス範囲を制限する。

# チームA用の Namespace Scope Infrastructure
apiVersion: v1
kind: ServiceAccount
metadata:
  name: team-a-chaos-sa
  namespace: team-a-apps
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: team-a-chaos-role
  namespace: team-a-apps
rules:
  - apiGroups: [""]
    resources: ["pods", "pods/log", "pods/exec", "events"]
    verbs: ["create", "delete", "get", "list", "patch", "update"]
  - apiGroups: ["apps"]
    resources: ["deployments", "statefulsets"]
    verbs: ["get", "list"]
  - apiGroups: ["litmuschaos.io"]
    resources: ["chaosengines", "chaosexperiments", "chaosresults"]
    verbs: ["create", "delete", "get", "list", "patch", "update"]
  # Node レベルの操作は明示的に除外
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: team-a-chaos-rb
  namespace: team-a-apps
subjects:
  - kind: ServiceAccount
    name: team-a-chaos-sa
    namespace: team-a-apps
roleRef:
  kind: Role
  name: team-a-chaos-role
  apiGroup: rbac.authorization.k8s.io

11.5 PodSecurityPolicy / SecurityContext の設定

# Chaos実験Podのセキュリティコンテキスト設定
apiVersion: v1
kind: Pod
metadata:
  name: chaos-experiment-runner
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    fsGroup: 1000
    seccompProfile:
      type: RuntimeDefault
  containers:
    - name: experiment
      image: litmuschaos/go-runner:3.9.0
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop:
            - ALL
          add:
            - NET_ADMIN      # ネットワーク実験に必要
            - SYS_PTRACE     # プロセス操作に必要

12. カスタムカオス実験の作成

12.1 カスタム実験の開発フロー

Litmus はカスタムのカオス実験を開発するためのフレームワークを提供している。

1. 実験ロジックの実装(Go/Python/Bash)
    ↓
2. Docker イメージのビルド
    ↓
3. ChaosExperiment CRD の作成
    ↓
4. RBAC の設定
    ↓
5. ChaosHub への登録(オプション)
    ↓
6. ChaosEngine で実行

12.2 Go による実験実装

// experiments/custom-experiment/experiment.go
package main

import (
    "fmt"
    "os"
    "strconv"
    "time"

    "github.com/litmuschaos/litmus-go/pkg/clients"
    "github.com/litmuschaos/litmus-go/pkg/events"
    "github.com/litmuschaos/litmus-go/pkg/log"
    "github.com/litmuschaos/litmus-go/pkg/probe"
    "github.com/litmuschaos/litmus-go/pkg/result"
    "github.com/litmuschaos/litmus-go/pkg/status"
    "github.com/litmuschaos/litmus-go/pkg/types"
    "github.com/litmuschaos/litmus-go/pkg/utils/common"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// ExperimentDetails はカスタム実験の設定を保持する構造体
type ExperimentDetails struct {
    ExperimentName     string
    EngineName         string
    ChaosDuration      int
    ChaosInterval      int
    RampTime           int
    AppNS              string
    AppLabel           string
    AppKind            string
    ChaosNamespace     string
    TargetContainer    string
    // カスタムパラメータ
    CustomParam1       string
    CustomParam2       int
}

func main() {
    // 実験パラメータの初期化
    experimentsDetails := ExperimentDetails{}
    clients := clients.ClientSets{}
    resultDetails := types.ResultDetails{}
    eventsDetails := types.EventDetails{}
    chaosDetails := types.ChaosDetails{}

    // クライアントの初期化
    if err := clients.GenerateClientSetFromKubeConfig(); err != nil {
        log.Fatalf("Unable to create clientsets: %v", err)
    }

    // 環境変数から実験パラメータを取得
    getENV(&experimentsDetails)

    // ChaosResult の初期化
    if err := result.ChaosResult(&chaosDetails, clients, &resultDetails, "SOT"); err != nil {
        log.Fatalf("Unable to create chaos result: %v", err)
    }

    // Probe の実行(SOT)
    if len(resultDetails.ProbeDetails) != 0 {
        if err := probe.RunProbes(&chaosDetails, clients, &resultDetails, "PreChaos", &eventsDetails); err != nil {
            log.Fatalf("Probe failed: %v", err)
        }
    }

    // Ramp Time の待機
    if experimentsDetails.RampTime != 0 {
        log.Infof("[Ramp]: Waiting for %d seconds before chaos injection", experimentsDetails.RampTime)
        common.WaitForDuration(experimentsDetails.RampTime)
    }

    log.Info("[Chaos]: Starting custom chaos experiment")

    // メインのカオス注入ロジック
    if err := injectChaos(&experimentsDetails, clients); err != nil {
        // 実験失敗の記録
        resultDetails.Verdict = "Fail"
        result.ChaosResult(&chaosDetails, clients, &resultDetails, "EOT")
        log.Fatalf("Chaos injection failed: %v", err)
    }

    log.Info("[Chaos]: Custom chaos experiment completed successfully")

    // Ramp Time の待機(終了時)
    if experimentsDetails.RampTime != 0 {
        log.Infof("[Ramp]: Waiting for %d seconds after chaos injection", experimentsDetails.RampTime)
        common.WaitForDuration(experimentsDetails.RampTime)
    }

    // Probe の実行(EOT)
    if len(resultDetails.ProbeDetails) != 0 {
        if err := probe.RunProbes(&chaosDetails, clients, &resultDetails, "PostChaos", &eventsDetails); err != nil {
            log.Fatalf("Post-chaos probe failed: %v", err)
        }
    }

    // 結果の記録
    resultDetails.Verdict = "Pass"
    result.ChaosResult(&chaosDetails, clients, &resultDetails, "EOT")
}

// injectChaos はカスタムカオスロジックを実装する
func injectChaos(details *ExperimentDetails, clients clients.ClientSets) error {
    duration := time.Duration(details.ChaosDuration) * time.Second
    interval := time.Duration(details.ChaosInterval) * time.Second
    endTime := time.Now().Add(duration)

    for time.Now().Before(endTime) {
        // --- ここにカスタムのカオス注入ロジックを実装 ---
        // 例: 特定のConfigMapを変更して設定障害をシミュレート
        log.Info("[Chaos]: Injecting custom fault...")

        configMap, err := clients.KubeClient.CoreV1().
            ConfigMaps(details.AppNS).
            Get(details.CustomParam1, metav1.GetOptions{})
        if err != nil {
            return fmt.Errorf("failed to get configmap: %v", err)
        }

        // 元の値を保存
        originalData := make(map[string]string)
        for k, v := range configMap.Data {
            originalData[k] = v
        }

        // 障害データを注入
        configMap.Data["fault-injected"] = "true"
        configMap.Data["chaos-timestamp"] = time.Now().Format(time.RFC3339)

        _, err = clients.KubeClient.CoreV1().
            ConfigMaps(details.AppNS).
            Update(configMap)
        if err != nil {
            return fmt.Errorf("failed to update configmap: %v", err)
        }

        // インターバル待機
        time.Sleep(interval)

        // 復元
        configMap.Data = originalData
        _, err = clients.KubeClient.CoreV1().
            ConfigMaps(details.AppNS).
            Update(configMap)
        if err != nil {
            return fmt.Errorf("failed to restore configmap: %v", err)
        }

        log.Info("[Chaos]: Fault injection cycle completed")
    }

    return nil
}

func getENV(details *ExperimentDetails) {
    details.ExperimentName = common.Getenv("EXPERIMENT_NAME", "custom-experiment")
    details.EngineName = common.Getenv("CHAOSENGINE", "")
    details.ChaosDuration, _ = strconv.Atoi(common.Getenv("TOTAL_CHAOS_DURATION", "60"))
    details.ChaosInterval, _ = strconv.Atoi(common.Getenv("CHAOS_INTERVAL", "10"))
    details.RampTime, _ = strconv.Atoi(common.Getenv("RAMP_TIME", "0"))
    details.AppNS = common.Getenv("APP_NAMESPACE", "default")
    details.AppLabel = common.Getenv("APP_LABEL", "")
    details.AppKind = common.Getenv("APP_KIND", "deployment")
    details.ChaosNamespace = common.Getenv("CHAOS_NAMESPACE", "litmus")
    details.CustomParam1 = common.Getenv("TARGET_CONFIGMAP", "")
    details.CustomParam2, _ = strconv.Atoi(common.Getenv("CUSTOM_PARAM_2", "0"))
}

12.3 Dockerfile

# Dockerfile for custom chaos experiment
FROM golang:1.22-alpine AS builder

WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download

COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo \
    -o /bin/custom-experiment ./experiments/custom-experiment/

FROM alpine:3.19
RUN apk add --no-cache bash curl kubectl

COPY --from=builder /bin/custom-experiment /bin/custom-experiment

ENTRYPOINT ["/bin/custom-experiment"]

12.4 カスタム実験の CRD と RBAC

# custom-experiment-crd.yaml
apiVersion: litmuschaos.io/v1alpha1
kind: ChaosExperiment
metadata:
  name: custom-configmap-chaos
  namespace: litmus
spec:
  definition:
    scope: Namespaced
    permissions:
      - apiGroups: [""]
        resources: ["pods", "configmaps", "events"]
        verbs: ["create", "delete", "get", "list", "patch", "update"]
      - apiGroups: ["litmuschaos.io"]
        resources: ["chaosengines", "chaosexperiments", "chaosresults"]
        verbs: ["create", "delete", "get", "list", "patch", "update"]
    image: my-registry/custom-chaos-experiment:1.0.0
    imagePullPolicy: Always
    args:
      - -c
      - /bin/custom-experiment
    command:
      - /bin/bash
    env:
      - name: TARGET_CONFIGMAP
        value: ""
      - name: TOTAL_CHAOS_DURATION
        value: "60"
      - name: CHAOS_INTERVAL
        value: "15"
      - name: RAMP_TIME
        value: "0"
    labels:
      name: custom-configmap-chaos

13. ベストプラクティスと運用ガイド

13.1 段階的導入戦略

カオスエンジニアリングを組織に導入する際は、以下の段階的アプローチを推奨する。

Phase 1: 学習と基盤構築(1-2ヶ月)

  • 非本番環境(開発/ステージング)にLitmusをインストール
  • チーム内でカオスエンジニアリングの概念を共有
  • 基本的な実験(pod-delete)から開始
  • モニタリング基盤(Prometheus/Grafana)との統合を確立

Phase 2: 実験の拡充(2-4ヶ月)

  • ネットワーク障害、ストレス障害の実験を追加
  • Probe を設定し、自動検証を導入
  • CI/CDパイプラインへの基本的な統合
  • チーム横断でのベストプラクティス共有

Phase 3: 本番環境への展開(4-6ヶ月)

  • 本番環境でのカオス実験を開始(影響範囲を限定)
  • GameDay(計画的なカオス実験イベント)の実施
  • レジリエンススコアの目標設定とトラッキング
  • インシデント対応訓練との統合

Phase 4: 自動化と最適化(6ヶ月以降)

  • 定期的なカオス実験のスケジュール化
  • GitOps による実験管理の自動化
  • カスタム実験の開発
  • 組織全体のレジリエンス文化の醸成

13.2 実験設計の原則

1. 最小影響範囲の原則
   ├── 影響する Pod の割合を制限する(PODS_AFFECTED_PERC)
   ├── 実験時間を最小限にする
   ├── 即座に停止できる仕組みを確保する(engineState: stop)
   └── 段階的に影響範囲を拡大する

2. 観測可能性の原則
   ├── 実験前にベースラインメトリクスを取得する
   ├── 実験中は Continuous Probe で常時監視する
   ├── ダッシュボードをリアルタイムで監視する
   └── 実験結果を必ず記録・レビューする

3. 自動停止の原則
   ├── SLO 違反時の自動停止条件を設定する
   ├── stopOnFailure: true を活用する
   ├── タイムアウトを必ず設定する
   └── PodDisruptionBudget を活用する

13.3 SLO ベースのカオス実験設計

# SLO に基づいた実験設計の例
# SLO: 可用性 99.9%、P99レイテンシ < 500ms、エラー率 < 0.1%

apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: slo-based-chaos
  namespace: default
spec:
  engineState: "active"
  appinfo:
    appns: "default"
    applabel: "app=order-service"
    appkind: "deployment"
  chaosServiceAccount: litmus-admin
  experiments:
    - name: pod-delete
      spec:
        components:
          env:
            - name: TOTAL_CHAOS_DURATION
              value: "120"
            - name: CHAOS_INTERVAL
              value: "30"
            - name: FORCE
              value: "true"
            - name: PODS_AFFECTED_PERC
              value: "30"
        probe:
          # 可用性の検証(SLO: 99.9%)
          - name: "availability-check"
            type: "httpProbe"
            mode: "Continuous"
            runProperties:
              probeTimeout: 5s
              retry: 1
              interval: 3s
              stopOnFailure: true
            httpProbe/inputs:
              url: "http://order-service:8080/health"
              method:
                get:
                  criteria: "=="
                  responseCode: "200"

          # レイテンシの検証(SLO: P99 < 500ms)
          - name: "latency-check"
            type: "promProbe"
            mode: "Continuous"
            runProperties:
              probeTimeout: 10s
              retry: 2
              interval: 15s
              stopOnFailure: false
            promProbe/inputs:
              endpoint: "http://prometheus:9090"
              query: 'histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket{service="order-service"}[2m])) by (le))'
              comparator:
                type: "float"
                criteria: "<="
                value: "0.5"

          # エラー率の検証(SLO: < 0.1%)
          - name: "error-rate-check"
            type: "promProbe"
            mode: "Continuous"
            runProperties:
              probeTimeout: 10s
              retry: 2
              interval: 15s
              stopOnFailure: true
            promProbe/inputs:
              endpoint: "http://prometheus:9090"
              query: 'sum(rate(http_requests_total{service="order-service",status=~"5.."}[2m])) / sum(rate(http_requests_total{service="order-service"}[2m])) * 100'
              comparator:
                type: "float"
                criteria: "<="
                value: "0.1"

13.4 GameDay の運営

GameDay はチームが計画的にカオス実験を実施するイベントである。

GameDay 運営チェックリスト:

事前準備(1週間前)
□ 実験シナリオの選定と文書化
□ 影響範囲の分析とリスク評価
□ ロールバック手順の確認
□ 関係チームへの事前通知
□ モニタリングダッシュボードの準備
□ インシデント対応チームの確保

当日実行
□ 参加者への概要説明
□ ベースラインメトリクスの取得
□ 実験の段階的実行
□ リアルタイムモニタリング
□ 異常検知時の即座停止判断
□ 結果の記録

事後レビュー(1週間以内)
□ 実験結果のレビュー
□ 発見された脆弱性のチケット化
□ アクションアイテムの割り当て
□ レジリエンススコアの記録
□ 次回 GameDay の計画

13.5 セキュリティに関する考慮事項

  1. 最小権限の原則: Chaos Infrastructure の ServiceAccount には必要最小限の権限のみ付与する
  2. ネットワーク分離: ChaosCenter と Chaos Infrastructure 間の通信をTLSで暗号化する
  3. 監査ログ: 全てのカオス実験の実行を監査ログに記録する
  4. 承認ワークフロー: 本番環境での実験は承認プロセスを経る
  5. Secrets管理: クラウド認証情報はKubernetes Secretsまたは外部シークレットマネージャーで管理する
  6. PodSecurityStandards: 実験Podのセキュリティコンテキストを適切に制限する

14. トラブルシューティング

14.1 よくある問題と解決策

14.1.1 Chaos Infrastructure が接続できない

症状: ChaosCenter で Infrastructure のステータスが「Inactive」のまま

原因と対策:

# 1. Subscriber Pod のステータス確認
kubectl get pods -n litmus -l app=subscriber
kubectl logs -n litmus -l app=subscriber

# 2. 接続先URLの確認
kubectl get configmap subscriber-config -n litmus -o yaml
# SERVER_ADDR が正しいか確認

# 3. ネットワーク接続の確認
kubectl exec -n litmus $(kubectl get pod -n litmus -l app=subscriber -o name) \
  -- curl -v http://<CHAOS_CENTER_URL>:8080/api/query

# 4. Access Key の確認
kubectl get secret subscriber-secret -n litmus -o jsonpath='{.data.ACCESS_KEY}' | base64 -d

# 5. ファイアウォール/NetworkPolicy の確認
kubectl get networkpolicies -n litmus

14.1.2 カオス実験が開始されない

症状: ChaosEngine を作成しても実験 Pod が起動しない

# 1. ChaosEngine のステータス確認
kubectl get chaosengine -n <namespace>
kubectl describe chaosengine <engine-name> -n <namespace>

# 2. Chaos Operator のログ確認
kubectl logs -n litmus -l app=chaos-operator

# 3. RBAC の確認
kubectl auth can-i create pods --as=system:serviceaccount:<namespace>:<sa-name> -n <namespace>
kubectl auth can-i delete pods --as=system:serviceaccount:<namespace>:<sa-name> -n <namespace>

# 4. ChaosExperiment CRD の存在確認
kubectl get chaosexperiments -n <namespace>

# 5. リソース不足の確認
kubectl describe node <node-name> | grep -A5 "Allocated resources"

14.1.3 実験が失敗する(Verdict: Fail)

# 1. ChaosResult の詳細確認
kubectl get chaosresult -n <namespace>
kubectl describe chaosresult <result-name> -n <namespace>

# 2. 実験Pod のログ確認
kubectl logs -n <namespace> <experiment-pod-name>
kubectl logs -n <namespace> <experiment-pod-name> -c <container-name>

# 3. Probe の失敗原因確認
kubectl get chaosresult <result-name> -n <namespace> -o jsonpath='{.status.probeStatuses}'

# 4. ターゲットアプリケーションの状態確認
kubectl get pods -n <app-namespace> -l <app-label>
kubectl describe pods -n <app-namespace> -l <app-label>

14.1.4 ネットワーク系実験が動作しない

# 1. コンテナランタイムの確認
kubectl get nodes -o jsonpath='{.items[0].status.nodeInfo.containerRuntimeVersion}'

# 2. NET_ADMIN capability の確認
kubectl get pod <experiment-pod> -n <namespace> -o jsonpath='{.spec.containers[0].securityContext.capabilities}'

# 3. tc (traffic control) コマンドの確認
kubectl exec -n <namespace> <experiment-pod> -- tc qdisc show

# 4. iptables の確認
kubectl exec -n <namespace> <experiment-pod> -- iptables -L -n

14.1.5 Workflow が途中で停止する

# 1. Argo Workflow のステータス確認
kubectl get workflows -n litmus
kubectl describe workflow <workflow-name> -n litmus

# 2. Workflow Controller のログ確認
kubectl logs -n litmus -l app=workflow-controller

# 3. タイムアウト設定の確認
kubectl get workflow <workflow-name> -n litmus -o jsonpath='{.spec.activeDeadlineSeconds}'

# 4. リソースクォータの確認
kubectl describe resourcequota -n litmus

14.2 デバッグコマンド集

# === 全体的な健全性チェック ===

# 全 Litmus コンポーネントのステータス
kubectl get pods -n litmus -o wide

# CRD の確認
kubectl get crd | grep litmuschaos

# ChaosEngine 全一覧
kubectl get chaosengine --all-namespaces

# ChaosResult 全一覧
kubectl get chaosresult --all-namespaces

# === ログ収集 ===

# Chaos Operator ログ
kubectl logs -n litmus deployment/chaos-operator-ce --tail=100

# Subscriber ログ
kubectl logs -n litmus deployment/subscriber --tail=100

# GraphQL Server ログ
kubectl logs -n litmus deployment/litmusportal-server --tail=100

# Auth Server ログ
kubectl logs -n litmus deployment/litmusportal-auth-server --tail=100

# === リソースクリーンアップ ===

# 停止した ChaosEngine のクリーンアップ
kubectl delete chaosengine --field-selector=status.engineStatus=stopped -n <namespace>

# 完了した Workflow のクリーンアップ
kubectl delete workflow --field-selector=status.phase=Succeeded -n litmus

# 失敗した実験Podのクリーンアップ
kubectl delete pods -n <namespace> -l chaosUID --field-selector=status.phase=Failed

14.3 パフォーマンスチューニング

# MongoDB のパフォーマンス最適化
mongodb:
  resources:
    requests:
      cpu: 500m
      memory: 1Gi
    limits:
      cpu: 2000m
      memory: 4Gi
  # WiredTiger キャッシュサイズ
  extraFlags:
    - "--wiredTigerCacheSizeGB=2"
  # インデックス最適化
  initdbScripts:
    create-indexes.js: |
      db.workflow_collection.createIndex({"project_id": 1, "created_at": -1});
      db.chaoshub_collection.createIndex({"project_id": 1});
      db.cluster_collection.createIndex({"project_id": 1, "is_active": 1});

# GraphQL Server のチューニング
portal:
  server:
    graphqlServer:
      resources:
        requests:
          cpu: 500m
          memory: 512Mi
        limits:
          cpu: 2000m
          memory: 2Gi
      genericEnv:
        # 同時実行ワークフロー数の制限
        WORKFLOW_HELPER_IMAGE_VERSION: "3.9.0"
        ARGO_WORKFLOW_CONTROLLER_IMAGE: "argoproj/workflow-controller:v3.4.0"
        ARGO_WORKFLOW_EXECUTOR_IMAGE: "argoproj/argoexec:v3.4.0"

15. Litmus と他のカオスエンジニアリングツールとの比較

15.1 比較表

特性LitmusChaos MeshChaosBladeGremlin
ライセンスApache 2.0Apache 2.0Apache 2.0商用
CNCF ステータスIncubatingIncubatingSandbox-
Web UIChaosCenterDashboard-Console
ワークフローArgo Workflows独自-独自
GitOps対応対応非対応非対応
ChaosHub対応---
マルチクラスタ対応対応非対応対応
Probe/検証4種類HTTPProbe-Health Check
クラウドカオスAWS/GCP/AzureAWSAWS/AzureAWS/GCP/Azure
Linux カオス対応-対応対応
Windows カオス非対応-非対応対応
RBACプロジェクトベースK8s RBAC-チームベース
スケジューリングCRONCRON-CRON
レジリエンススコア対応--対応

15.2 選定ガイドライン

  • Litmus を選ぶ場合: ChaosHub による実験カタログの管理、GitOps統合、マルチクラスタ管理が必要な場合。Web UIによる運用管理を重視する場合
  • Chaos Mesh を選ぶ場合: よりシンプルな CRD ベースの管理で十分な場合。物理時計操作(TimeChaos)が必要な場合
  • ChaosBlade を選ぶ場合: Linux/VM 環境でのカオス実験を中心に行う場合。Alibaba Cloud との統合が必要な場合
  • Gremlin を選ぶ場合: エンタープライズサポートが必要な場合。非Kubernetes環境でのカオス実験が中心の場合

16. まとめと展望

16.1 まとめ

本記事では、LitmusChaosの全容について以下の観点から詳細に解説した。

アーキテクチャ面: ChaosCenter(コントロールプレーン)と Chaos Infrastructure(実行プレーン)の2層構成により、集中管理と分散実行を両立する設計を詳述した。GraphQL Server、Subscriber、Chaos Operator の各コンポーネントが連携してカオス実験のライフサイクルを管理する。

実験の多様性: Pod レベル、Node レベル、Network レベル、HTTP レベル、クラウドプロバイダレベルの幅広いカオス実験を紹介した。各実験の具体的な設定例を示し、パラメータの意味と推奨設定を解説した。

運用面: Probe による自動バリデーション、Resilience Score による定量評価、ChaosHub によるカタログ管理、GitOps/CI/CD統合、マルチテナントRBACなど、エンタープライズ運用に必要な機能を網羅的に説明した。

実践面: インストール手順、カスタム実験の開発方法、段階的導入戦略、GameDay の運営方法、トラブルシューティングガイドなど、実際の導入・運用に必要な知識を提供した。

16.2 Litmus の今後の展望

  1. AIベースのカオス実験推薦: システムの構成やメトリクスを分析し、最適なカオス実験を自動推薦する機能
  2. Steady State Hypothesis の自動検出: 機械学習によるベースライン自動設定
  3. サービスメッシュとの深い統合: Istio、Linkerd との統合によるアプリケーションレベルのカオス実験
  4. eBPF ベースのカオス注入: より軽量で低オーバーヘッドな障害注入メカニズム
  5. マルチクラウド/ハイブリッドクラウド対応の強化: クラウド間の一貫したカオス実験体験
  6. コンプライアンス/ガバナンス機能: 規制要件に対応した実験管理と監査機能

16.3 カオスエンジニアリングの組織的成熟度モデル

Level 0: 未導入
  → カオスエンジニアリングの概念を認識していない

Level 1: 基礎
  → 開発環境で基本的なカオス実験を手動実行
  → 特定のチームのみが実験を実施

Level 2: 標準化
  → ステージング環境での定期的な実験実行
  → CI/CDパイプラインへの基本的な統合
  → 複数チームでの利用開始

Level 3: 体系化
  → 本番環境での計画的なカオス実験
  → SLOベースの実験設計と自動バリデーション
  → GameDayの定期開催
  → レジリエンススコアの組織的追跡

Level 4: 最適化
  → 継続的なカオス実験の自動実行
  → AIベースの実験推薦と最適化
  → カオスエンジニアリング文化の全社浸透
  → インシデント対応とカオス実験の統合

カオスエンジニアリングは、もはや一部の先進的企業のみの実践ではなく、クラウドネイティブシステムを運用する全ての組織にとって不可欠なプラクティスとなりつつある。Litmus はそのための強力なプラットフォームを提供しており、Kubernetes エコシステムにおけるレジリエンス向上の中核ツールとしての地位を確立している。

本記事が、Litmus の導入と活用の一助となれば幸いである。


参考文献