Chaos Mesh・Kubernetesのカオス上の舞う

# Chaos Mesh・Kubernetesのカオス上の舞う

[`Chaos Mesh`](https://github.com/pingcap/chaos-mesh)は、コンテナ化されたアプリケーシュンのカオステスト、またクラウドネイティブするためのオープンソースツールキットです。

## 基本を理解する

### カオステストが必要な理由

カオスはプロダクション運用環境で頻繁に発生します、マシン障害、ネットワーク障害など。その故障を対応ために、人間は多くの試みをしました。単体テストはコードモジュールの安定性の保障するように、カオステストは故障対応手段の安定性の保証ために。

[マーフィーの法則](https://ja.wikipedia.org/wiki/%E3%83%9E%E3%83%BC%E3%83%95%E3%82%A3%E3%83%BC%E3%81%AE%E6%B3%95%E5%89%87)とは、「失敗する余地があるなら、失敗する」。システムが大複雑で大規模になるほど、潜在的なバグが多くなります。たとえ、プロダクション運用環境と同じサイズの開発環境でも、まだいくつかのバグをミスします。しかし、コストを節約するために、開発環境通常は小さい。ハードドライブが損傷する確率は1時間あたり0.0001％であると仮定します、100台のハードドライブのクラスターが10,000時間実行される、1台のハードディスクが破損する可能性がが高い。でも、開発環境では、その可能性は非常に低い、カオステストはこの障害状況をシミュレートすることである。

### クラウドネイティブの理由

カオスは複数の方法で実装できます、時間のカオスをシミュレートするためにシステム時間調整する、ネットワークのカオスをシミュレートするための`iptables`を使用したファイアウォールのセットアップします。自分の経験からクラウドネイティブを選んだ理由を説明します。

`PingCAP`では、非常に早い段階でカオステストを開始しました。初に、`SSH`経由でマシンにカオスを設定します。

<img width="995" alt="sshで構成されたカオス.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267120/b16896f0-d48c-1b85-4913-96117f035287.png">

あの時、僕は`TiDB`用のカオステストツールを作成しました。[`tidb-ansible`](github.com/pingcap/tidb-ansible/)を使用して`TiDB`を展開する、そして、データベースに接続するロードプログラムを実行します、同時にカオス操作を実行します。

大事な問題は、このテストフレームワークもバグあります。たとえ、`tidb-ansible`を`TiDB`の展開に失敗した、`iptables`のルール削除に失敗したなど（次のテストの環境汚染を引き起こす）。

他の問題があります：

* リソース使用率は低い
* 問題が発生した場合、プログラムの実行状態を記述するために、次のテストを停止します
* ログ収集を行う必要があります
* 複数のクラスターを同時テスト実行出来る、でも新しいのクラスタ、は環境を手動で構成必要があります
* ...

まとめとして、このテストスーツ使用では、多くの場合、手動介入が必要です。

#### クラウドネイティブのアドバンテージ

* `Kubernetes`はリソースを適切に管理し、テストに標準環境を提供します
* [`TiDB Operator`](github.com/pingcap/tidb-operator/)は、`TiDB`クラスタを管理できます
* `Chaos Mesh`、`TiDB Operator`などのユニットに分割

#### クラウドネイティブの欠陥

* 部分的な障害のシミュレートできません、たとえば、電源を切る

### `Chaos Mesh`を試す

#### `Helm`使用して、`Chaos Mesh`展開

公式ドキュメント：[https://github.com/pingcap/chaos-mesh#deploy-chaos-mesh](https://github.com/pingcap/chaos-mesh#deploy-chaos-mesh)

`Helm`チャートを取得する

```sh
git clone https://github.com/pingcap/chaos-mesh.git
cd chaos-mesh/
```

カスタムリソースをインストール

```sh
kubectl apply -f manifests/
# CRD を確認する
kubectl get crd podchaos.pingcap.com
kubectl get crd networkchaos.pingcap.com
kubectl get crd iochaos.pingcap.com
kubectl get crd timechaos.pingcap.com
```

通常、コンテナランタイムは`Docker`。もし他のコンテナランタイム使用する、ドキュメントを参照してください

```sh
# 名前空間を作成する
kubectl create ns chaos-testing
# helm 2.X
helm install helm/chaos-mesh --name=chaos-mesh --namespace=chaos-testing
# helm 3.X
helm install chaos-mesh helm/chaos-mesh --namespace=chaos-testing
# Chaos Mesh pods を確認する
kubectl get pods --namespace chaos-testing -l app.kubernetes.io/instance=chaos-mesh
```

#### テストしてみましょう

テストコンテナを実行する

```sh
kubectl create ns hello-chaos
kubectl -n hello-chaos create deployment kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1
```

カオスを設定する

例：[https://github.com/pingcap/chaos-mesh/blob/master/examples/pod-kill-example.yaml](https://github.com/pingcap/chaos-mesh/blob/master/examples/pod-kill-example.yaml)

```yaml
apiVersion: pingcap.com/v1alpha1
kind: PodChaos
metadata:
  name: hello-pod-kill
  namespace: chaos-testing
spec:
  action: pod-kill
  mode: one
  selector:
    namespaces:
      - hello-chaos
    labelSelectors:
      "app": "kubernetes-bootcamp"
  scheduler:
    cron: "@every 1m"
```

`pod kill`を適用するした、そして動作するか確認する

```sh
# pod kill を適用する
kubectl apply -f hello-pod-kill.yaml
# pod 再起動を確認する
watch -n 1 kubectl -n hello-chaos get pods
```

## 今後の仕事

現在の`Chaos Mesh`にはいくつかの欠陥がであり

* カオスの追加は面倒です
* カオスイベントは視覚的に表示できません

作業効率を向上させます、より良い体験のために、`Chaos Mesh`は将来的に改善されます。