Litmus 入門

Chaos Mesh少しかじっていましたが、最近話題の Litmus に入門してみます。Litmus には Chaos Mesh にはなかった EC2 Instance の停止Docker Daemon の停止kubelet の停止などができるのが魅力ですね。 (その後 Chaos Mesh でも EC2 や GCE のインスタンス停止などもできるようになっています)

商用 Chaos Engineering ツールを提供している Gremlin が Chaos Engineering tools comparison というドキュメントを公開してくれていて、触ったことがあるものは納得感のある説明でした。Litmus は確かに面倒、Chaos Mesh がセキュリティ的に良くないというのもわかるが、そもそも Production で使おうなどとは思っていなかった。

以下、minikube v1.15.1 での Kubernetes 1.18.8 と litmus 1.10.0 で試しました。

インストール

Helm もありますが、今回は manifest をそのまま適用しました。

kubectl apply -f https://litmuschaos.github.io/litmus/litmus-operator-v1.10.0.yaml

litmus Namespace に chaos-operator-cd Deployment とそれ用の litmus ServiceAccount と CRD が3つ (chaosengines.litmuschaos.io, chaosexperiments.litmuschaos.io, chaosresults.litmuschaos.io) 作成されます。

nginx の deploy

Pod Delete Experiment を実行するために、delete 対象となる Deployment を deploy します。

helm create コマンドで nginx の deployment 用の chart が作成されるのでこれを使います。

kubectl create namespace nginx
helm create nginx
cd nginx
helm install nginx . -n nginx --set replicaCount=3

これで replicas 3 の nginx Deployment がデプロイされます。

❯ kubectl get pod -n nginx
NAME                     READY   STATUS    RESTARTS   AGE
nginx-577ccbcdd5-hsdpj   1/1     Running   0          165m
nginx-577ccbcdd5-lvrrk   1/1     Running   0          165m
nginx-577ccbcdd5-z97jr   1/1     Running   0          165m

Chaos Experiments のインストール

Litmus では experiment を実行する各 namespace に chaosexperiment をインストールする必要があるようです。

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

今回使うのは pod-delete だけですけどね。

Pod Delete Experiment 実行用の ServiceAccount を作成

pod-delete 用の ServiceAccount を作成します。pod-delete に限定しなくてもこの namespace で使う experiment 用の権限を一つにまとめてしまっても良いと思いますけど、まあ今回は pod-delete しかしないので。

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

Experiment 対象となるように Deployment に annotation を設定する

勝手に experiment 対象とされないようにアプリ (Deployment) のオーナーが litmuschaos.io/chaos="true" という annotation をつけないと対象とならないようになっています。安全ですね、と思いかけたけど ChaosEngine リソースの annotationCheckfalse にしたらそんなの無視するみたいです…

kubectl annotate deploy/nginx litmuschaos.io/chaos="true" -n nginx

これが設定されていないと Unable to filter app by specified info, Chaos stopped due to failed app identification とすぐに終了してしまいます (kubectl get events より)。

0s          Normal    ChaosEngineInitialized         chaosengine/nginx-chaos              nginx-chaos-runner created successfully
0s          Warning   ChaosResourcesOperationFailed   chaosengine/nginx-chaos              Unable to filter app by specified info
0s          Warning   ChaosEngineStopped              chaosengine/nginx-chaos              Chaos stopped due to failed app identification

ChaosEngine リソースの作成

ようやく準備ができたので ChaosEngine リソースを作成することでやっと Pod の delete を行うことができます。applabel の値は今回の helm でデプロイした nginx にはついていない label であるため変更しました。

kubectl apply -f - <<EOF
apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
  name: nginx-chaos
  namespace: nginx
spec:
  appinfo:
    appns: 'nginx'
    applabel: 'app.kubernetes.io/name=nginx'  # '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

これを apply すると次のような状況になります。まず、nginx-chaos-runner という Pod が起動され、そこから pod-delete-xxxxxx という Job が作成され pod-delete-xxxxxx-zzzzz という Pod が起動されて label にマッチする Pod を delete します。

❯ kubectl get pod -n nginx
NAME                      READY   STATUS              RESTARTS   AGE
nginx-577ccbcdd5-8spjq    1/1     Running             0          4m14s
nginx-577ccbcdd5-g5xsb    0/1     ContainerCreating   0          2s
nginx-577ccbcdd5-l9mqr    1/1     Running             0          4m23s
nginx-577ccbcdd5-qwk6g    0/1     Terminating         0          7m53s
nginx-chaos-runner        1/1     Running             0          13s
pod-delete-o04orr-k4xm6   1/1     Running             0          10s

対象選択の appinfoappns, appkind は見たままですが、 applabel ですこしハマりました。appkind で指定された Deployment の label にもマッチする必要があるし、そこから作成され、実際に削除される Pod もこの label にマッチする必要がありました。

Deployment の label にマッチしない場合は nginx-chaos-runner がすぐさま終了します。Deployment にはマッチしたが Pod にはマッチしなかった場合は pod-delete-xxxxxx-zzzzz という Pod が3分ほど待機してマッチする Pod が現れるのを待ちます。それでも現れない場合は Application status check failed, err: Unable to find the pods with matching labels, err: というエラーで終了します。

ChaosEngine の env で指定されている値は Supported Experiment Tunables に説明があります。ここで使われているものはコメントが入っていますが TOTAL_CHAOS_DURATION はこの期間(秒) Pod の削除が繰り返されるという意味で、削除と削除の間隔が CHAOS_INTERVAL (秒) です。

TOTAL_CHAOS_DURATION (秒) 経過すると pod-delete-xxxxxx-zzzzz という Pod も pod-delete-xxxxxx という Job も nginx-chaos-runner という Pod も終了します。jobCleanUpPolicydelete であれば消えます。大した情報は入っていませんが、ChaosResult というリソースが作成されます。

❯ kubectl get chaosresult -n nginx
NAME                     AGE
nginx-chaos-pod-delete   6h25m

終了すると engineStatestop になっています。これを再度 active に書き換えると再度実行されます。

以上。他の Experiment や Litmus Portal (User Guide) や Litmus Probes も気になりますね。ただ、Chaos Mesh と比べるとだいぶ面倒。

YouTube に動画がありました。

Built with Hugo
テーマ StackJimmy によって設計されています。