はじめに
最近ではAWSでもカオスエンジニアリングを実行するフルマネージドサービスである AWS Fault Injection Simulatorがリリースされるなど、カオスエンジニアリングという言葉をよく目にするようになりました。
カオスエンジニアリングとは、分散システムにおいてシステムが不安定な状態に耐えることのできる環境を構築するための検証の規律、ということらしいです。
カオスエンジニアリングの原則
https://principlesofchaos.org/ja/
カオスエンジニアリングを実践しているNetflixでは、chaos monkeyというツールを開発し、実際に本番環境に対して障害を発生させてシステム障害の安定性を高める取り組みを行なっているようです。
個人的見解ですが、カオスエンジニアリングは障害が発生してもサービスを継続して提供できるような環境を作るための取り組み、といったものだと思っています。
そんなカオスエンジニアリングを実施するためのツールとして、kubernetes上でカオスエンジニアリング Chaos Mesh があるとの知見を得ましたので、実際にApple Siliconが搭載されているmacbook Proで動かしながら何ができるのかを見てみました。
Chaos Meshとは
Chaos MeshはChaos Mesh公式ページによるとkubernets用のカオスエンジニアリングプラットフォーム、と説明されています。
特徴としては以下の点が挙げられます。
-
使いやすさ
- アプリケーションのデプロイのロジックを変更することなく、実際に動作している環境で試験を行える。
- 試験の動作を簡単に調整でき、試験を行う人は試験状態をリアルタイムで観察できるようになっており素早くロールバックできる。
- ダッシュボードが豊富で、手書きの定義をすることなく数クリックで試験を実施できる。
-
Kubernetes用に設計されている
- CRD(Custom Resource Definition)に則って試験の定義をする。
- CRDに乗っ取ることでKubernetesの機能を自然に統合できる。
-
さまざまな種類の障害を発生させることができる
- Chaos Meshは分散システムの観点から始まり、分散システムで起こりうる障害を十分に考慮しているため、分散システムで起こりうる様々な障害を発生できるようにしている。
-
コントローラブル
- Chaos MeshはRBAC(role-based access control)を提供するため、実験を行う人の権限を設定できる。
- namespaceのブラックリスト、ホワイトリストを設定でき、実験の被害範囲を細かく制御できる。
個人としてはコントローラブルであることから障害を発生させる範囲が限定的にできるのと、ロールバックがすぐにできるところが良い点だと思いました。
注入できる障害
公式ドキュメントの基本的な機能が公式ドキュメントにまとめられていましたので、どのようなものがあるのかを見てみました。
具体的には以下のような障害の注入に対応しているようです。
中でもAWSやGCPの障害をシミュレートできるのは非常に興味深く、突然Worker Nodeが再起動をする場合も想定できるのは非常に役立ちそうですね。
基本的なリソースの障害
- PodChaos
- Podの再起動やPodの永続的な使用不能状態、特定のPodのコンテナの障害など、Podの障害のシミュレート
- NetworkChaos
- ネットワークの遅延、パケットの損失や障害、ネットワークパーティションなどの障害のシミュレート
- DNSChaos
- DNSの名前解決失敗や、誤ったIPアドレスが返却される障害のシミュレート
- HTTPChaos
- HTTP通信の待ち時間や失敗をシミュレート
- StressChaos
- CPUやメモリの負荷をシミュレート
- IOChaos
- I/Oの遅延や読み書きの失敗、アプリケーションファイルのI/Oの失敗をシミュレート
- TimeChaos
- タイムジャンプ例外のシミュレート
- KernelChaos
- アプリケーションのメモリ割り当ての例外など、カーネルの障害をシミュレートする
プラットフォームの障害
- AWSChaos
- AWSノードの再起動など、AWSの障害をシミュレート
- GCPChaos
- GCPノードの再起動など、GCPの障害をシミュレート
アプリケーションの障害
- JVMChaos
- 関数呼び出しの遅延など、JVMアプリケーションの障害をシミュレート
実際に障害を注入してみる
ローカルPCにkubernetes環境を用意し、ダッシュボードを操作しながらnginx-b
のnginx
コンテナで障害を発生させてみたいと思います。
ローカルPCのセットアップ
ローカルPCとkubernetes環境は以下のものを用意しました。
- PC
- macbook Pro M1 Pro
- 8core 16GB
- macOS Monterey(12.0.1)
- macbook Pro M1 Pro
- Kubernetes環境
- minikube(v1.24.0)
- kubectl
- Client Version: v1.21.7
- Server Version: v1.22.3
- Chaos Mesh
- v2.1.0
テスト用のnginxのデプロイ
Chaos Meshの障害注入対象として、nginxのPodを2つデプロイしたいと思います。
m-e-n-d/test-nginx-deployment
こちらのmanifestをapplyし、nginx-a
のPodとnginx-b
のPodを事前にChaos Meshをデプロイするクラスターと同じクラスターに配置しておきます。
Chaos Meshのインストール
ローカルPCにChaos Meshをインストールします。
こちらはminikubeでインストールをする際のコマンドですが、kind
やk3s
、Microk8s
を使用する際はQuick Startを参考にそれぞれにあったものを入れてください。
注意
こちらを実行する際には現在設定しているkubeconfigのcontextを設定しているクラスターに対してインストールが実行されます。
インストールを実施する際には現在設定しているcontextを意図したクラスターに向けるようにしておきましょう。
curl -sSL https://mirrors.chaos-mesh.org/v2.1.0/install.sh | bash
インストールが完了しましたらクラスターのchaos-testing
のnamespaceにPodが配置されていますので確認してみましょう。
$ kubectl get po -n chaos-testing
NAME READY STATUS RESTARTS AGE
chaos-controller-manager-7d86885d5f-2zrtf 1/1 Running 0 5m41s
chaos-controller-manager-7d86885d5f-6gx2v 1/1 Running 0 5m41s
chaos-controller-manager-7d86885d5f-hlzlq 1/1 Running 0 5m41s
chaos-daemon-x2g7c 1/1 Running 0 5m41s
chaos-dashboard-b8c66f994-mls8x 1/1 Running 0 5m41s
ダッシュボードを見てみる
ダッシュボードのPodが立ち上がっているので、ダッシュボードがどのようなものか見てみます。
serviceを見てみると以下のようにdashboardのserviceが作成されているので、kubectl port-forward
でローカルIPからアクセスできるようにしてみます。
$ kubectl get service -n chaos-testing
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
chaos-daemon ClusterIP None <none> 31767/TCP,31766/TCP 8m33s
chaos-dashboard NodePort 10.99.50.123 <none> 2333:30978/TCP 8m33s
chaos-mesh-controller-manager ClusterIP 10.99.140.46 <none> 443/TCP,10081/TCP,10082/TCP,10080/TCP 8m33s
http://localhost:2333 でアクセスできるようにします。
$ kubectl port-forward -n chaos-testing svc/chaos-dashboard 2333:2333
Forwarding from 127.0.0.1:2333 -> 2333
Forwarding from [::1]:2333 -> 2333
.....
ここまでできたら以下の画像のようなダッシュボードが見れるはずですのでアクセスしてみましょう。
http://localhost:2333
おお....
障害を注入する
ダッシュボード左のメニューからExperimentsを開き、「NEW EXPERIMENT」を開きます。
以下のように設定を行い「SUBMIT」をクリックします。
さらに下部にある Experiment Infoは以下のように設定しました。
ここで「SUBMIT」をクリックし、nginx-b
のnginx
コンテナをKILL
してみたいと思います。
$ kubectl get po -n test-nginx
NAME READY STATUS RESTARTS AGE
test-nginx-a-6bd7d4685b-mjjrv 1/1 Running 0 4m32s
test-nginx-b-6745d55ffc-zc6fv 1/1 Running 1 (69s ago) 4m31s
するとこのようにPodがコンテナが終了したことで再起動され、nginx-b
のPodのRESTARTS
が1
になっていました。
events
の方を確認してみると、以下のようになっておりました。
これはChaos Meshが正常にPodの終了ができたというログが出ているみたいですね。
Chaos Meshのダッシュボードにも実験が終了したときのログが残っていました。
設定と一緒に、設定内容のYAMLまで出力されるみたいです。
ファイル管理ができるようになるのは非常にありがたいですね。
まとめ
Chaos MeshではGUIだけで障害を発生させることができ、範囲も細かく設定することで想定外の障害を発生させないためのつくりになっていることがわかりました。
これにより、カオスエンジニアリングを行ううえで、比較的安心して障害を注入することができそうですね。
まだまだ発展途中のツールなので、今後のアップデートにも期待できます。
あと今回の内容はあくまでクイックスタートの内容ですので、しっかりと始めたい場合はChaos Meshの公式ドキュメントを見ることをお勧めします。