Litmus 101 - Chaos Engineering Framework

# KubeCon NA Virtual 2020におけるLitmus

KubeCon NA Virtual 2020にて、Litmus+Argoの話が大変興味深かったため、Chaos Engineering FrameworkであるLitmusについて整理することにした。

講演概要: [https://kccncna20.sched.com/event/ekDC/constructing-chaos-workflows-with-argo-and-litmuschaos-umasankar-mukkara-mayadata-sumit-nagal-intuit?iframe=no&w=100%&sidebar=yes&bg=no](https://kccncna20.sched.com/event/ekDC/constructing-chaos-workflows-with-argo-and-litmuschaos-umasankar-mukkara-mayadata-sumit-nagal-intuit?iframe=no&w=100%25&sidebar=yes&bg=no)

講演資料: [https://static.sched.com/hosted_files/kccncna20/c7/KubeCon Slides - Litmus%2BArgo.pdf](https://static.sched.com/hosted_files/kccncna20/c7/KubeCon%20Slides%20-%20Litmus%2BArgo.pdf)

# What's Litmus

LitmusはCloud NativeなChaos Engineering Frameworkです。システムにおける未知のバグや脆弱性を発見し、システムのResilience(回復性)を向上させることに役立てられます。

アイコンのひよこが、なんともいえないかわいさです。

![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94861/a48ac7e3-f602-c58c-8a0a-e85edf46d4dd.png)


# What's Chaos Engineering

IT分野においては、大規模な分散システムが当たり前になってきており、これらの複雑なシステムに対してどのように信頼性を担保できるかが注目されています。

この課題の解決策としてChaos Engineeringが注目されてきています。

Chaos Engineeringとは、混沌とした状態にも耐えうる信頼性の高いシステムを構築するために、システム上でさまざまな実験を行う学問または手法のことを指す言葉です。

参考: [https://principlesofchaos.org](https://principlesofchaos.org/)

# Architecrute of Litmus

下記は公式に記載されているアーキテクチャ図です。

順を追ってみていきます。

まずは、上半分からみていきます。

![Untitled 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94861/2749cb97-a98a-087c-4ad8-777283c3b11d.png)


Chaos OperatorはLitmus関連のCRDを管理するOperatorです。

このOperatorが、ChaosEngineをウォッチし管理します。

ChaosEngineはアプリケーションに対して、Chaos Experimentsを紐づける役割を持っています。

これにより、どのChaos Experimentsをどのアプリケーションに対して実行するかを特定できます。

右上のChaos Hubについては以降で詳しくみていきます。

左側のApplicationsは、Chaos Experimentsの適用対象のアプリケーションです。ここでアプリケーションといっていますが、Kubernetesのノードなどもここに含まれるような広い概念に見えます。(後述しますが、Kubernetesノード向けのChaos Experimentsもあるため)

![Untitled 2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94861/68dcb87a-b0fe-0246-a083-eba9b608d7c9.png)


下部分についてもみていきます。

実際のChaos Experimentsの適用は、Chaos Runnerによって制御されます。

Chaos Experiments用のJobリソースが作成され、アプリケーションへの適用結果をChaos Resultとして出力します。

![Untitled 1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94861/41138504-b8fe-159d-c16a-955d56949d76.png)


# Chaos Hub

DockerHubがDocker Image置き場なように、ChaosHubはChaosの実験セット(Chaos Experiments)が置いてあります。

かわいいひよこがお出迎えしてくれます

[https://hub.litmuschaos.io](https://hub.litmuschaos.io/)

![Untitled 3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94861/0c3c942f-c49c-b15b-d006-843911d9a7df.png)



## Chaos Experimentsとは

ざっくり言うと、「用途ごとのシステムテスト群」です。

2020/11/20現在39のChaos Experimentsが公開されていますが、下記はその一部です。

- podの削除
- メモリ枯渇
- 通信遮断
- etc

このように、Chaos(混沌とした)という語感がミスリーディングなくらい、整理されています。(アイコンもおしゃれです。

それぞれのChaos Experimentsは下記の3カテゴリに分かれています。

- [Generic Chaos](https://docs.litmuschaos.io/docs/chaoshub/#generic-chaos)
- [Application Chaos](https://docs.litmuschaos.io/docs/chaoshub/#application-chaos)
- [Platform Chaos](https://docs.litmuschaos.io/docs/chaoshub/#platform-chaos)

![Untitled 4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94861/cd5c1c09-5ac1-7766-79ad-6855431ee2ad.png)


## 各Chaos Experimentsのページ

先程のアイコンをクリックすると、各Experimentのページにて詳細が見れます。

例えば、Chaos Experimentsがどんなテストをしてくれるかが書かれています。

Pod-deleteのページの場合、「指定したアプリケーションに対して、ランダムなPod削除操作を行う」ようです。

Deploymentのレプリカに対して強制的(Forced),もしくはGraceful(洗練された)Pod停止を引き起こせることが記載されています。

![Untitled 5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94861/6ecbf703-5cdd-26c8-c428-0699f0dace5b.png)


さらにスクロールすると、実際にChaos Experiment(と必要なリソース)をコピペで導入する方法が書かれています。

ChaosExperiment自体はChaosExperiment CRD, CRとして導入されます。

ここに記載されているコマンドを、忙しい人向け、Getting Startedの章にて実行していきます。

![Untitled 6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94861/1c99c3f2-817d-03ae-245e-767368e0cbca.png)


# 忙しい人向け

以降で実施するコマンドはKataKodaにて同様のことを15分程度確認できます。

[https://www.katacoda.com/litmusbot/scenarios/getting-started-with-litmus#](https://www.katacoda.com/litmusbot/scenarios/getting-started-with-litmus#)

# Getting Started

クラスタを作成します

ここはお好きな方法で。

```bash
❯ kind create cluster
```

基本的に下記のページ通りです。

一部、分岐する表現や、Noteがちょろっと書かれているので、何も考えなくても実行できる状態のコマンドにしたものを紹介します。

[Getting Started with Litmus · Litmus Docs](https://docs.litmuschaos.io/docs/getstarted/#install-litmus)

Litmus自体のインストール。

```bash
❯ kubectl apply -f https://litmuschaos.github.io/litmus/litmus-operator-v1.10.0.yaml
namespace/litmus created
serviceaccount/litmus created
clusterrole.rbac.authorization.k8s.io/litmus created
clusterrolebinding.rbac.authorization.k8s.io/litmus created
deployment.apps/chaos-operator-ce created
customresourcedefinition.apiextensions.k8s.io/chaosengines.litmuschaos.io created
customresourcedefinition.apiextensions.k8s.io/chaosexperiments.litmuschaos.io created
customresourcedefinition.apiextensions.k8s.io/chaosresults.litmuschaos.io created
```

Chaos Operatorが動作していることを確認できます。

```bash
❯ kubectl get pods -n litmus
NAME                                READY   STATUS    RESTARTS   AGE
chaos-operator-ce-5f998db95-dkrst   1/1     Running   0          56s
```

作業簡略化のため、namespaceを移動します。

```bash
❯ kubens litmus
Context "kind-kind" modified.
Active namespace is "litmus".
```

CRDとAPIがそれぞれ3つできていることを確認します。

```bash
❯ kubectl get crds | grep chaos
chaosengines.litmuschaos.io       2020-11-20T08:33:02Z
chaosexperiments.litmuschaos.io   2020-11-20T08:33:02Z
chaosresults.litmuschaos.io       2020-11-20T08:33:02Z

❯ kubectl api-resources | grep chaos
chaosengines                                   litmuschaos.io                 true         ChaosEngine
chaosexperiments                               litmuschaos.io                 true         ChaosExperiment
chaosresults                                   litmuschaos.io                 true         ChaosResult
```

# Install Chaos Experiments

Chaos Experimentsをデプロイします。

ここで指定しているものは、Chaos Hub内のgeneric/all-experimentsです。

[https://hub.litmuschaos.io/generic/all-experiments](https://hub.litmuschaos.io/generic/all-experiments)

```bash
❯ k create namespace nginx
namespace/nginx created

❯ kubectl apply -f https://hub.litmuschaos.io/api/chaos/1.10.0?file=charts/generic/experiments.yaml -n nginx
chaosexperiment.litmuschaos.io/pod-memory-hog created
chaosexperiment.litmuschaos.io/container-kill created
chaosexperiment.litmuschaos.io/node-cpu-hog created
chaosexperiment.litmuschaos.io/k8-pod-delete created
chaosexperiment.litmuschaos.io/pod-network-duplication created
chaosexperiment.litmuschaos.io/node-taint created
chaosexperiment.litmuschaos.io/k8-service-kill created
chaosexperiment.litmuschaos.io/pod-network-loss created
chaosexperiment.litmuschaos.io/kubelet-service-kill created
chaosexperiment.litmuschaos.io/disk-fill created
chaosexperiment.litmuschaos.io/disk-loss created
chaosexperiment.litmuschaos.io/pod-autoscaler created
chaosexperiment.litmuschaos.io/node-io-stress created
chaosexperiment.litmuschaos.io/pod-io-stress created
chaosexperiment.litmuschaos.io/docker-service-kill created
chaosexperiment.litmuschaos.io/pod-network-latency created
chaosexperiment.litmuschaos.io/node-memory-hog created
chaosexperiment.litmuschaos.io/pod-delete created
chaosexperiment.litmuschaos.io/pod-cpu-hog created
chaosexperiment.litmuschaos.io/node-drain created
chaosexperiment.litmuschaos.io/pod-network-corruption created
```

21個のChaos Experimentsが導入された。

この個数は、Chaos Hubにてgenericと検索した際に出てくる個数-1になる(all-experimentsも表示されるため)。

```bash
❯ kubectl get chaosexperiments -n nginx
NAME                      AGE
container-kill            43s
disk-fill                 43s
disk-loss                 43s
docker-service-kill       43s
k8-pod-delete             43s
k8-service-kill           43s
kubelet-service-kill      43s
node-cpu-hog              43s
node-drain                43s
node-io-stress            43s
node-memory-hog           43s
node-taint                43s
pod-autoscaler            43s
pod-cpu-hog               43s
pod-delete                43s
pod-io-stress             43s
pod-memory-hog            44s
pod-network-corruption    43s
pod-network-duplication   43s
pod-network-latency       43s
pod-network-loss          43s
```

## Setup Service Account

rbacを適用します。簡単のためファイルが作成されないようにしています。

```bash
❯ kubectl apply -f - << EOF
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: pod-delete-sa
  namespace: nginx
  labels:
    name: pod-delete-sa
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-delete-sa
  namespace: nginx
  labels:
    name: pod-delete-sa
rules:
- apiGroups: ["","litmuschaos.io","batch","apps"]
  resources: ["pods","deployments","pods/log","events","jobs","chaosengines","chaosexperiments","chaosresults"]
  verbs: ["create","list","get","patch","update","delete","deletecollection"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: pod-delete-sa
  namespace: nginx
  labels:
    name: pod-delete-sa
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: pod-delete-sa
subjects:
- kind: ServiceAccount
  name: pod-delete-sa
  namespace: nginx
EOF

serviceaccount/pod-delete-sa created
role.rbac.authorization.k8s.io/pod-delete-sa created
rolebinding.rbac.authorization.k8s.io/pod-delete-sa created
```

## Deploy Your Application

Chaos Experimentsを適用するアプリケーションとしてnginxを起動します。

実際には、信頼性を高めたいアプリケーションがここに指定されていくことになります。

```bash
❯ k create deploy nginx -n nginx --image nginx
deployment.apps/nginx created
```

## Annotate your application

Chaos Experimentsの影響範囲を限定したり、セキュリティ観点の指標の1つとして、実行対象のアプリケーションにannotationをつけてあげる必要があります。

```bash
❯ kubectl annotate deploy/nginx litmuschaos.io/chaos="true" -n nginx
deployment.apps/nginx annotated
```

## Prepare ChaosEngine

ChaosEngineはアプリケーションをChaos Experimentsに接続してくれます。

詳細は割愛しますが、さまざまな設定項目があることが伺えます。

これを実行した段階で、Chaos Experimentsが実行され始めることになります。

```bash
❯ kubectl apply -f - << EOF
apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: nginx-chaos
  namespace: nginx
spec:
  appinfo:
    appns: 'nginx'
    applabel: 'app=nginx'
    appkind: 'deployment'
  # It can be true/false
  annotationCheck: 'true'
  # It can be active/stop
  engineState: 'active'
  #ex. values: ns1:name=percona,ns2:run=nginx
  auxiliaryAppInfo: ''
  chaosServiceAccount: pod-delete-sa
  monitoring: false
  # It can be delete/retain
  jobCleanUpPolicy: 'delete'
  experiments:
    - name: pod-delete
      spec:
        components:
          env:
            # set chaos duration (in sec) as desired
            - name: TOTAL_CHAOS_DURATION
              value: '30'

            # set chaos interval (in sec) as desired
            - name: CHAOS_INTERVAL
              value: '10'
              
            # pod failures without '--force' & default terminationGracePeriodSeconds
            - name: FORCE
              value: 'false'
EOF

chaosengine.litmuschaos.io/nginx-chaos created
```

様子を見てみます。

何やら、nginxの他にchaos-runnerやpod-deleteというようなPodができています。

しばらくすると、それらのPodは消えます。

```bash
❯ k get po -n nginx
NAME                      READY   STATUS    RESTARTS   AGE
nginx-chaos-runner        1/1     Running   0          39s
nginx-f89759699-xvfkx     1/1     Running   0          8s
pod-delete-gvnw25-68wpx   1/1     Running   0          28s

❯ k get po -n nginx   
NAME                    READY   STATUS    RESTARTS   AGE
nginx-f89759699-8h4bh   1/1     Running   0          45s
```

## Chaos Result

Chaos Experimentsの実行結果は、Chaos Result CRに書き込まれます。

完了していればEventとしてPassというステータスを確認できます。

実際にはここで、システムが壊れてくれれば、より信頼性の高いシステムにするための対策を打てることになります。

```bash
❯ kubectl describe chaosresult nginx-chaos-pod-delete -n nginx | grep Spec -A20
Spec:
  Engine:      nginx-chaos
  Experiment:  pod-delete
Status:
  Experimentstatus:
    Fail Step:  N/A
    Phase:      Completed
    Verdict:    Pass
Events:
  Type    Reason   Age    From                     Message
  ----    ------   ----   ----                     -------
  Normal  Awaited  2m48s  pod-delete-gvnw25-68wpx  experiment: pod-delete, Result: Awaited
  Normal  Pass     118s   pod-delete-gvnw25-68wpx  experiment: pod-delete, Result: Pass
```

## Clean up

```bash
❯ kind delete cluster
```

# Chaos Monitoring

Getting Startedで見てきた結果を、視覚的に確認することで知見を得やすくすることが期待できます。

Chaos experimentsを実行した際のメトリクスをウォッチすることで、テスト時のクラスタの様子をよりグラフィカルに見ることができます。

[https://docs.litmuschaos.io/docs/next/monitoring/#monitoring-chaos](https://docs.litmuschaos.io/docs/next/monitoring/#monitoring-chaos)

Chaos Experiments実行時に、CPU使用率がどれくらい上昇したのかなど、アドホックにメトリクスを見ることができます。

下記の例だと、赤い帯部分がChaos Runner実行時を示していてわかりやすいですね。

![Untitled 7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94861/20a8481d-36f1-0bc2-d9d9-ad461f1c1294.png)


# Litmusの今後

## KubeCon NA Virtual 2020における言及

2021年に注目される技術5選のうち、1つにChaos Exngineeringが含まれています。

今後も他のツールが出てくる可能性がありますが、Litmusがラップする形になっていくかと思われます。

## Roadmap

Roadmapに記載されている内容について、気になる部分だけ抜粋します。

明確な時期は記載されていませんが、Near Termに実装予定とのこと。

[https://github.com/litmuschaos/litmus/blob/master/ROADMAP.md](https://github.com/litmuschaos/litmus/blob/master/ROADMAP.md)

### Litmus用のUIを提供

[https://github.com/litmuschaos/litmus/wiki/portal-design-spec#litmus-portal-design-specification](https://github.com/litmuschaos/litmus/wiki/portal-design-spec#litmus-portal-design-specification)

(ログイン画面しかわかりませんが)Litmus用のWebUIが提供され、そこで諸々の操作を行えるようになることが期待できます。

![Untitled 8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94861/f79c9393-fec1-b766-09ad-93fe253ac371.png)


### OpenEBS、Kafka、Cassandra向けのChaosResultをGrafanaダッシュボードで表示

別途Chaos-Exporter(Prometheus Exporter)を用意することで、Chaos ResultをGrafanaでみられるようにするエンハンスメントです。

今もメトリクスを見ることをできますが、既成のダッシュボードとして提供されるようになります。

[https://github.com/litmuschaos/litmus/issues/1280](https://github.com/litmuschaos/litmus/issues/1280)

### 機能ごとにSIGを作成して、開発を促進

今後の開発がさらに加速することを期待できます。

# まとめ

Chaos Engineering FrameworkであるLitmusの概要について紹介した。

CNCFとしても、2021年に注目すべき技術としてChaos Engineeringがあげられていることから、今後さらに開発が進むことが予想される。

現時点でもChaos Hubには39個のChaos Experimentsがあるが、今後はApplication固有のものが増えていくことが期待できる。