Kubernetes ネイティブなカオスエンジニアリングツール Chaos Mesh を使ってみる

Netflix が提唱した耐障害テスト技法 Chaos Engineering。実行環境に実際に障害を発生させてアプリケーションの復旧をテストする方法です。

Chaos Mesh は Kubernetes クラスターで稼働するアプリケーションをターゲットに Chaos Engineering テストを実行できるツールです。CNCF でホストされており、最近 v1.0 に到達しました。

chaos-mesh.org

以下のような障害発生の Experiment を実施できます。

  • PodChaos : Pod に定期的にエラーを発生させたり、Kill したりする
  • NetworkChaos : Pod のネットワークを遮断したり、遅延やロスを発生させる
  • StressChaos : Pod に負荷をかける
  • TimeChaos : 時刻取得のシステムコールを置き換えて時刻同期を狂わせる
  • IOChaos : IO エラーを発生させる
  • KernelChaos : Linux Kernel レベルのエラーを発生させる (デフォルトでは無効化されておりプロダクション環境での使用は禁止)

v1.0.1 現在、素の Pod への Chaos 注入はサポートされておらず、deployment, statefulset, daemonset が対象とのことです。

Docker Desktop for Mac の Kubernetes 環境で動かしてみました。

ドキュメントにしたがって、インストール*1

% curl -sSL https://mirrors.chaos-mesh.org/v1.0.1/web-show/deploy.sh | sh

Install Chaos Mesh chaos-mesh
   :
Waiting for pod running
Chaos Mesh chaos-mesh is installed successfully

無事デプロイされ、namespace chaos-testing に次のような Pod や Service が起動しました。

% kubectl -n chaos-testing get po,svc,deploy
NAME                                            READY   STATUS    RESTARTS   AGE
pod/chaos-controller-manager-86c96f985f-pvjcv   1/1     Running   0          11m
pod/chaos-daemon-9n9mb                          1/1     Running   0          11m
pod/chaos-dashboard-5d8dff7df9-5hp6h            1/1     Running   0          11m

NAME                                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                       AGE
service/chaos-dashboard                 NodePort    10.97.228.5      <none>        2333:31287/TCP                11m
service/chaos-mesh-controller-manager   ClusterIP   10.106.150.179   <none>        10081/TCP,10080/TCP,443/TCP   11m

NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/chaos-controller-manager   1/1     1            1           11m
deployment.apps/chaos-dashboard            1/1     1            1           11m

次のような CRD (Custom Resource Definition) が適用されています。IO, Kernel, Network, Pod, Pod Network, Stress, Time などの Chaos type があるのがわかります。

% kubectl get crd
NAME                             CREATED AT
iochaos.chaos-mesh.org           2020-10-22T15:03:17Z
kernelchaos.chaos-mesh.org       2020-10-22T15:03:18Z
networkchaos.chaos-mesh.org      2020-10-22T15:03:18Z
podchaos.chaos-mesh.org          2020-10-22T15:03:18Z
podiochaos.chaos-mesh.org        2020-10-22T15:03:18Z
podnetworkchaos.chaos-mesh.org   2020-10-22T15:03:18Z
stresschaos.chaos-mesh.org       2020-10-22T15:03:18Z
timechaos.chaos-mesh.org         2020-10-22T15:03:18Z

Network chaos を引き起こすサンプルマニフェスト。NetworkChaos という CRD として適用され、10ms のレイテンシを web-show というラベルの Pod に 60秒毎に30秒の間発生させます。

apiVersion: chaos-mesh.org/v1alpha1
kind: NetworkChaos
metadata:
  name: web-show-network-delay
spec:
  action: delay # the specific chaos action to inject
  mode: one # the mode to run chaos action; supported modes are one/all/fixed/fixed-percent/random-max-percent
  selector: # pods where to inject chaos actions
    namespaces:
      - default
    labelSelectors:
      "app": "web-show"  # the label of the pod for chaos injection
  delay:
    latency: "10ms"
  duration: "30s" # duration for the injected chaos experiment
  scheduler: # scheduler rules for the running time of the chaos experiments about pods.
    cron: "@every 60s"

ターゲットとなる web-show アプリをデプロイ。これは、kube-system Pod に ping してレイテンシーを表示する React アプリです。

% curl -sSL https://mirrors.chaos-mesh.org/v1.0.1/web-show/deploy.sh | sh
service/web-show created
deployment.apps/web-show created
 :
Waiting for pod running

localhost:8081 に接続するとこんな感じで、レイテンシーの推移が表示されます。

f:id:kondoumh:20201023080812p:plain

この状態で先ほどの Network Chaos のサンプルを apply してみます。

% kubectl apply -f network-delay.yaml

Network Chaos の引き起こしたレイテンシが一定間隔で発生しているのが見て取れます。

f:id:kondoumh:20201023083219p:plain

Chaos Mesh のダッシュボードは Node Port で公開されているため port-forward して画面を表示します。

% kubectl port-forward -n chaos-testing svc/chaos-dashboard 2333:2333
Forwarding from 127.0.0.1:2333 -> 2333
Forwarding from [::1]:2333 -> 2333

localhost:2333 に接続するとダッシュボードが表示され、適用中の Experiment (この場合は Network Chaos) が確認できます。

f:id:kondoumh:20201023083729p:plain

タイムラインや詳細情報を閲覧できます。

f:id:kondoumh:20201023084221p:plain

f:id:kondoumh:20201023084243p:plain

このように Chaos Mesh はターゲットの Kubernetes アプリケーションに対して様々な障害を注入することで耐障害性をテストすることができます。ダッシュボードも見やすくて完成度が高い印象です。リリース前のシステムテストなどに組み込めば、アプリケーションのウィークポイントを発見したり、運用時の障害復旧のリハーサルにも活用できそうです。

*1:Helm でも導入可能です。