Kubernetesの信頼性を高める! カオスエンジニアリングツール「Krkn」

2025年10月15日(水)
櫻井 遼介
第16回の今回は、Kubernetes向けのカオスエンジニアリングツール「Krkn」について基礎知識から具体的な使い方までを解説します。

はじめに

Kubernetesをはじめとするクラウドネイティブ技術の普及により、私たちの作るシステムはますます便利になる一方で、その裏側は非常に複雑になっています。多くのサービスが連携して動く分散システムでは、個々の部品は正しくても、全体として思わぬ問題が起きることがあります。

開発段階で行うユニットテストやインテグレーションテストは重要ですが、それだけではシステム全体の複雑な動きから生じる障害をすべて事前に見つけ出すのは難しいのが現実です。

そこで役立つのが「カオスエンジニアリング」です。これはただやみくもにシステムを壊すことではありません。本番に近い環境でわざと障害(例えば、サーバーダウンやネットワークの遅延など)を引き起こし、システムがそれにどう耐えるかを観察します。

その一番の目的は、実際の障害が起きてユーザーに影響が出る前に私たちがまだ気づいていないシステムの弱点(いわゆる「未知の未知」)を先に見つけ出し、改善することにあります。この実験を通して「障害が起きたときにアラートが機能するか」「自動復旧の仕組みは期待通りに動くか」といったことを実際に試し、自分たちのシステムに対する信頼性を高めていくことができます。

この記事では、Kubernetes環境で使いやすいカオスエンジニアリングツールの「Krkn」に焦点を当て、その基本的な考え方から仕組み、具体的な使い方までを分かりやすく解説していきます。

Krknとは

KrknはRed Hatによって開発され現在はCloud Native Computing Foundation(CNCF)のサンドボックスプロジェクトとしてホストされている、オープンソースのカオスエンジニアリングツールです。その主な目的はKubernetesクラスタとその上で動作するアプリケーションに意図的に障害を注入し、システムの回復性とパフォーマンスを検証・向上させることにあります。

このツールは主に、次のような役割を持つエンジニアを対象として設計されています。

  • サイトリライアビリティエンジニア(SRE): Kubernetesプラットフォームと、その上でホストされるアプリケーションの信頼性向上を目指す
  • 開発者・エンジニア: 障害シナリオ下におけるアプリケーションのパフォーマンスと堅牢性の向上に焦点を当てる
  • Kubernetes管理者: オンボードされたサービスがベストプラクティスに準拠し、長時間の停止を防ぐことに責任を持つ

Krknの主な特徴

Krknは、Kubernetesにおけるカオスエンジニアリングを実践する上で、多くの強力な特徴を備えています

  • シグナリング
    CI実行中や外部ジョブにおいて、Krknの実行を一時停止または完全に停止させるための機能。これにより、クラスターの負荷テストとKrknの実行タイミングを同期できる
  • パフォーマンスモニタリング
    Krknのカオスシナリオがクラスターの各コンポーネントに与える影響を監視し、ボトルネックを特定する。障害注入中および注入後のクラスターの回復力とパフォーマンスを確認することが重要
  • SLO検証
    PromQLを使用してカオス実行中および実行後にサービスレベル目標(SLO)を検証する。メトリクスに基づいて異常を検知し、深刻度に応じてアラートを発したりエラーで終了したりできる。これにより、テストの合否判定や異常の検出が可能
  • ヘルスチェック
    アプリケーションの可用性とパフォーマンスに対するカオスシナリオの影響をリアルタイムで可視化。定義された間隔で指定されたURLを定期的にチェックし、結果をテレメトリに記録する
  • テレメトリ
    Krknの実行終了時にクラスター構成と実行されたシナリオに関する基本的な詳細情報を収集・表示する。AWS S3バケットまたはElasticsearchにテレメトリデータを保存することも可能
  • OCM/ACM連携
    「Open Cluster Management(OCM)」および「Red Hat Advanced Cluster Management for Kubernetes (ACM)」で管理されているクラスターに対して、ManagedCluster Scenariosを通じて障害を注入することをサポートする

この記事ではデモを行いながら、次のような機能について紹介していきます。

  • Kubernetesネイティブな設計
    KrknはKubernetes環境に特化して作られており、Pod、Node、NamespaceといったKubernetesの基本的なリソースに対する障害シナリオを豊富にサポート。これにより、Kubernetes上で発生しうる様々な問題をリアルにシミュレートできる
  • 柔軟なカオスシナリオのカスタマイズ
    ユーザーはYAML形式の設定ファイルで独自のカオスシナリオを定義できる。特定のアプリケーションやインフラの特性に合わせた、きめ細やかなストレステストが可能
  • クラウドとKubernetesの両シナリオに対応
    AWS、Azure、GCPといったクラウドインフラに特有の障害(例:VMインスタンスの停止)と、Kubernetesネイティブな障害(例:Podの削除)の両方をサポートしており、ハイブリッドな障害シナリオを構築できる
  • Chaos Recommenderによるシナリオ提案
    テレメトリデータを分析してアプリケーションに負荷がかかっている箇所などを特定し、最も影響を与えうる効果的なカオスシナリオを提案してくれる「Chaos Recommender」というユニークな機能を備える

😚Krknと連携するKubernetes監視ツールの「Cerberus」についてはこの記事では扱わず、Krkn単体での動作を紹介します。

Krknがサポートするカオスシナリオ

Krknはアプリケーションからインフラ層まで、多岐にわたる障害をシミュレートできます。以下に代表的なシナリオを挙げます。

  • Pod/コンテナレベルの障害
    • Podのランダムな削除、再起動
    • コンテナへの障害注入
  • Nodeレベルの障害
    • Nodeの停止、再起動
    • Nodeの電源断シミュレーション
    • Nodeリソース(CPU/メモリ)の枯渇
  • ネットワーク障害
    • PodやNodeレベルでのネットワーク遅延、パケットロス
  • ストレージ障害
    • 永続ボリューム(PV)の容量枯渇
  • アプリケーション/サービスレベルの障害
    • 特定のアプリケーションプロセスの停止
    • 依存する外部サービスの無効化
  • クラウドプロバイダー特有の障害
    • AWS、Azure、GCPにおけるVMインスタンスの停止・終了

対応しているシナリオの一覧は、こちらのドキュメントに記載されています。

Krknを使ってみよう

それでは、実際にKrknをどのように利用するのか、その基本的な流れを見ていきましょう。

1. 準備

まず、カオス実験の対象となる実行中のKubernetesクラスタが必要です。今回は以下の環境でデモで使用します。

  • GKE Standard (1.33.2-gke.1240000)
  • Krkn v4.0.5

2. インストールと設定

ドキュメントに従って準備を行います。

$ git clone <https://github.com/Krkn-chaos/Krkn.git> --branch v4.0.5
$ cd Krkn 
$ python3 -m venv chaos
$ source chaos/bin/activate
$ pip install -r requirements.txt

リポジトリ内のconfig/config_kubernetes.yamlを確認し、環境に応じて編集します。ここでは次のようにしました。設定可能な項目についてはドキュメントを参照してください。

kraken:
    distribution: kubernetes                  
    kubeconfig_path: ~/.kube/config           
    exit_on_failure: False                    
    port: 8081
    publish_kraken_status: True               
    signal_state: RUN                         
    chaos_scenarios:                          
        - pod_disruption_scenarios:
            - scenarios/kube/pod.yml

cerberus:
    cerberus_enabled: False                        

performance_monitoring:
    prometheus_url:  localhost:9090 # デモ環境ではManaged Service for Prometheusへのプロキシ                                                
    enable_alerts: False                      
    check_critical_alerts: False              
tunings:
    wait_duration: 30                   
    iterations: 1                             
    daemon_mode: False  
health_checks:
    interval: 2
    config:
        - url: <ここにヘルスチェック対象を記載します。デモではLBのIPアドレスを記載します>
          bearer_token: 
          auth:
          exit_on_failure: False
          verify_url: False

3. シナリオの実行(デモ)

ここでは、実際にKrknを使ってPod障害シナリオを実行するデモを行います。簡単な設定を使って使用する流れを確認していきます。

pod_disruption_scenarios
始めに、Podのkillシナリオを指定して動作を確認してみます。手順2でconfigファイルにscenarios/kube/pod.ymlを指定しており、これを実行します。pod.ymlは次のような設定になっています。フィールドについてはドキュメント上で全て説明されていないため、ソースコードを確認したほうが良さそうです。

# yaml-language-server: $schema=../plugin.schema.json
- id: kill-pods
  config:
    name_pattern: ^nginx-.*$ # 対象となるPodの名前パターン
    namespace_pattern: ^default$ # 対象となるPodの名前パターン
    kill: 1 # killするPodの数
    Krkn_pod_recovery_time: 120

対象となるnginxのPodを作成しておきます。

apiVersion: apps/v1 
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2 
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 250m
            memory: 500Mi
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  type: LoadBalancer

準備ができたので、Krknを実行してみます。実行しているシナリオの情報や影響を受けるリソースの情報が出力されながらテストが進行していきます。

$ python3 run_kraken.py --config config/config_kubernetes.yaml 
 _              _              
| | ___ __ __ _| | _____ _ __  
| |/ / '__/ _` | |/ / _ \\ '_ \\ 
|   <| | | (_| |   <  __/ | | |
|_|\\_\\_|  \\__,_|_|\\_\\___|_| |_|
                               

2025-08-29 10:24:29,843 [INFO] Starting kraken
...<出力省略>...
2025-08-29 10:24:31,928 [INFO] Executing scenarios for iteration 0
2025-08-29 10:24:31,928 [INFO] connection set up
127.0.0.1 - - [29/Aug/2025 10:24:31] "GET / HTTP/1.1" 200 -
2025-08-29 10:24:31,932 [INFO] response RUN
2025-08-29 10:24:31,936 [INFO] Running PodDisruptionScenarioPlugin: ['pod_disruption_scenarios'] -> scenarios/kube/pod.yml
2025-08-29 10:24:32,141 [INFO] waiting up to 120 seconds for pod recovery, pod name pattern: ^nginx-.*$ namespace pattern: ^default$
2025-08-29 10:24:32,320 [INFO] ('nginx-deployment-77f7cbd5d8-ssmj8', 'default')
2025-08-29 10:24:32,320 [INFO] Deleting pod nginx-deployment-77f7cbd5d8-ssmj8
2025-08-29 10:24:43,895 [INFO] wating 10 before running the next scenario
2025-08-29 10:24:54,085 [INFO] collecting Kubernetes cluster metadata....
...<出力省略>...

設定ファイルにヘルスチェックの設定をしている場合はヘルスチェックのログも出力されるため、テストによりサービスアクセスに影響があったのかを確認できます。例えば、次の出力からは4秒間500エラーが返されていたことが分かります。

				...出力部分抜粋...
				"timestamp": "2025-08-29T10:26:48Z",
        "health_checks": [
            {
                "url": "<http://x.x.x.x:80>",
                "status": false,
                "status_code": "200",
                "start_timestamp": "2025-08-29T10:26:49.727996",
                "end_timestamp": "2025-08-29T10:26:51.734376",
                "duration": 2.00638
            },
            {
                "url": "<http://x.x.x.x:80>",
                "status": false,
                "status_code": "500",
                "start_timestamp": "2025-08-29T10:26:53.740337",
                "end_timestamp": "2025-08-29T10:26:57.760655",
                "duration": 4.020318
            },
            {
                "url": "<http://x.x.x.x:80>",
                "status": true,
                "status_code": 200,
                "start_timestamp": "2025-08-29T10:26:59.773545",
                "end_timestamp": "2025-08-29T10:27:13.843695",
                "duration": 14.07015
            }
        ],

node_scenarios
次に、ノードに対してイベントを発生してみます。特定のゾーンのノードを指定して停止するイベントです。リポジトリのscenarios/openshift/gcp_node_scenarios.ymlを参考に次のように変更します。ゾーンbのノードが再起動されることを期待します。

node_scenarios:
  - actions:
    - node_reboot_scenario
    node_name:
    label_selector: topology.kubernetes.io/zone=asia-northeast1-b
    instance_count: 1
    timeout: 120
    cloud_type: gcp
    parallel: true
    kube_check: true

設定ファイルを更新して、シナリオを指定します。

kraken:
    distribution: kubernetes                               # Distribution can be kubernetes or openshift
    kubeconfig_path: ~/.kube/config                        # Path to kubeconfig
    exit_on_failure: False                                 # Exit when a post action scenario fails
    port: 8081
    publish_kraken_status: True                            # Can be accessed at <http://0.0.0.0:8081>>
    signal_state: RUN                                      # Will wait for the RUN signal when set to PAUSE before running the scenarios, refer docs/signal.md for more details
    signal_address: 0.0.0.0                                # Signal listening address
    chaos_scenarios:                                       # List of policies/chaos scenarios to load
        - node_scenarios:
            - scenarios/openshift/gcp_node_scenarios.yml

実行前にノードの状態を確認します。3つのゾーンの1つずつノードがあることが確認できます。

$ kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\\t"}{.metadata.labels.topology\\.gke\\.io/zone}{"\\n"}{end}'
gke-cluster-1-default-pool-0b86d23b-twk9        asia-northeast1-a
gke-cluster-1-default-pool-a9ae1baf-30xg        asia-northeast1-b
gke-cluster-1-default-pool-f11c1613-jpl8        asia-northeast1-c

シナリオを実行します。指定したasia-northeast1-bのノードにイベントが発生していることが分かります。

$ python3 run_kraken.py --config config/config_kubernetes.yaml 

...<出力省略>...

{
    "telemetry": {
        "scenarios": [
            {
                "start_timestamp": 1756465020,
                "end_timestamp": 1756465147,
                "scenario": "scenarios/openshift/gcp_node_scenarios.yml",
                "scenario_type": "node_scenarios",
                "exit_status": 0,
                "parameters_base64": "",
                "parameters": {
                    "node_scenarios": [
                        {
                            "actions": [
                                "node_reboot_scenario"
                            ],
                            "cloud_type": "gcp",
                            "instance_count": 1,
                            "kube_check": true,
                            "label_selector": "topology.kubernetes.io/zone=asia-northeast1-b",
                            "node_name": null,
                            "parallel": true,
                            "timeout": 120
                        }
                    ]
                },
								...
                "affected_nodes": [
                    {
                        "node_name": "gke-cluster-1-default-pool-a9ae1baf-30xg", # asia-northeast1-bのノードが影響を受けたことを確認できる
                        "node_id": "gke-cluster-1-default-pool-a9ae1baf-30xg",
                        "not_ready_time": 120.04839873313904,
                        "ready_time": 0.16450238227844238,
                        "stopped_time": 0.0,
                        "running_time": 1.3358662128448486,
                        "terminating_time": 0.0
...<出力省略>...
$ kubectl get node -w
NAME                                       STATUS     ROLES    AGE     VERSION
gke-cluster-1-default-pool-0b86d23b-twk9   Ready      <none>   16m     v1.33.2-gke.1240000
gke-cluster-1-default-pool-a9ae1baf-30xg   Ready      <none>   9m27s   v1.33.2-gke.1240000
gke-cluster-1-default-pool-f11c1613-jpl8   Ready      <none>   16m     v1.33.2-gke.1240000
gke-cluster-1-default-pool-a9ae1baf-30xg   NotReady   <none>   9m59s   v1.33.2-gke.1240000
gke-cluster-1-default-pool-a9ae1baf-30xg   NotReady   <none>   10m     v1.33.2-gke.1240000
gke-cluster-1-default-pool-a9ae1baf-30xg   Ready      <none>   10m     v1.33.2-gke.1240000
gke-cluster-1-default-pool-a9ae1baf-30xg   Ready      <none>   10m     v1.33.2-gke.1240000

他にも様々なシナリオを指定することが可能で、リポジトリにはサンプルとして複数用意されています。シナリオファイルを自分の環境に合うように編集し、実行するリストに組み込んでいくことで目的のテストを行えるようになります。

付録: Chaos Recommendation Toolについて
どのようなシナリオが適しているかを推奨してくれるツールがKrknリポジトリで提供されています。このツールはPrometheusのクエリを使用してアプリケーションを評価し、関連するテストケースを推奨します。具体的な動作の雰囲気を理解するため、簡単にデモ環境への実行結果のみ紹介します。実行方法についてはドキュメントを参照してください。

以下の出力からはapplication_outage、node_network_chaos、pod_network_chaosが推奨として挙げられました。

$ python3 utils/chaos_recommender/chaos_recommender.py -c config/recommender_config.yaml  
...<出力省略>...
    "analysis_outputs": [
        {
            "namespace": "default",
            "queries": {
                "cpu_query": "sum (rate (container_cpu_usage_seconds_total{image!=\\"\\", namespace=\\"default\\"}[10m])) by (pod) *1000",
                "cpu_limit_query": "(sum by (pod) (kube_pod_container_resource_limits{resource=\\"cpu\\", namespace=\\"default\\"}))*1000",
                "memory_query": "sum by (pod) (avg_over_time(container_memory_usage_bytes{image!=\\"\\", namespace=\\"default\\"}[10m]))",
                "memory_limit_query": "sum by (pod) (kube_pod_container_resource_limits{resource=\\"memory\\", namespace=\\"default\\"})  ",
                "network_query": "sum by (pod) ((avg_over_time(container_network_transmit_bytes_total{namespace=\\"default\\"}[10m])) +         (avg_over_time(container_network_receive_bytes_total{namespace=\\"default\\"}[10m])))"
            },
            "profiling": {
                "cpu_outliers": [],
                "memory_outliers": [],
                "network_outliers": [
                    "nginx-deployment-68f6b85cbb-txvg8"
                ]
            },
            "heatmap_analysis": {
                "services_with_cpu_heatmap_above_threshold": [],
                "services_with_mem_heatmap_above_threshold": []
            },
            "recommendations": {
                "outliers_network_recommendations": {
                    "outliers_networks": [
                        "nginx-deployment-68f6b85cbb-txvg8"
                    ],
                    "tests": [
                        "application_outage",
                        "node_network_chaos",
                        "pod_network_chaos"
                    ]
                }
            }
        }
    ]
}

おわりに

本記事では、Kubernetes向けのカオスエンジニアリングツール「Krkn」について紹介しました。Krknを活用することで、開発チームやSREチームはシステムの潜在的な弱点を発見し、より回復性の高い、堅牢なサービスを構築できるようになります。ぜひ、ご自身の環境でKrknを試し、カオスエンジニアリングの世界に足を踏み入れてみてください。

【参考】
株式会社スリーシェイク Sreake事業部
インフラエンジニアとしてWebホスティング運用を経験した後、3-shakeのSreake事業部にJoin。Google Cloud、特にGKEの活用支援を行っています。 ---
スリーシェイクは、ITインフラ領域の技術力に強みをもつテクノロジーカンパニーです。SREコンサルティング事業「Sreake」では、AWS/Google Cloud/Kubernetesに精通したプロフェッショナルが技術戦略から設計・開発・運用を一貫してサポートしています。また、ノーコード型ETLツール「Reckoner」、フリーランスエンジニア特化型人材紹介サービス「Relance」、セキュリティサービス「Securify」を提供しています。
会社HP: https://3-shake.com/

連載バックナンバー

仮想化/コンテナ技術解説
第16回

Kubernetesの信頼性を高める! カオスエンジニアリングツール「Krkn」

2025/10/15
第16回の今回は、Kubernetes向けのカオスエンジニアリングツール「Krkn」について基礎知識から具体的な使い方までを解説します。
仮想化/コンテナ技術解説
第15回

「kube-bench」でKubernetesクラスタのCISベンチマーク準拠を確認する

2025/7/2
第15回の今回は、「kube-bench」でKubernetesクラスタのセキュリティベンチマークを取得し、CIS Benchmarkのベストプラクティスに準拠しているか確認する方法について紹介します。
仮想化/コンテナ技術解説
第14回

「vCluster」で仮想Kubernetesクラスターを構築する

2025/4/24
第14回の今回は、Kubernetes上で仮想的なクラスターを構築する「vCluster」を利用して、短時間で軽量な仮想クラスターを構築する方法について紹介します。

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています