Chaos Mesh を少しかじっていましたが、最近話題の Litmus に入門してみます。Litmus には Chaos Mesh にはなかった EC2 Instance の停止や Docker Daemon の停止や kubelet の停止などができるのが魅力ですね。
商用 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 リソースの annotationCheck
を false
にしたらそんなの無視するみたいです…
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
対象選択の appinfo
の appns
, 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: <nil> というエラーで終了します。
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 も終了します。jobCleanUpPolicy
が delete
であれば消えます。大した情報は入っていませんが、ChaosResult というリソースが作成されます。
❯ kubectl get chaosresult -n nginx NAME AGE nginx-chaos-pod-delete 6h25m
終了すると engineState
が stop
になっています。これを再度 active
に書き換えると再度実行されます。
以上。他の Experiment や Litmus Portal (User Guide) や Litmus Probes も気になりますね。ただ、Chaos Mesh と比べるとだいぶ面倒。
YouTube に動画がありました。