- PVSM.RU - https://www.pvsm.ru -

Это вторая и заключительная часть знакомства с доступными сегодня Open Source-утилитами для организации хаос-инжиниринга в Kubernetes-кластерах. В первой статье [1] было вкратце рассказано о появлении самой дисциплины — chaos engineering, — а также рассмотрены kube-monkey, chaoskube и Chaos Mesh. Теперь этот список пополнится обзором Litmus Chaos, Chaos Toolkit, мини-подборкой из хаос-игр и перечислением пяти других вариантов, заслуживающих внимания инженеров, заинтересованных в разовой или постоянной проверке своей инфраструктуры на устойчивость.
NB: Нумерацию проектов продолжим в соответствии с первой частью.
Litmus — еще один оператор, который создает, управляет и наблюдает за хаосом в Kubernetes. Делает он это, используя три типа Custom Resources:
ChaosExperiment описывает сам эксперимент, действия и их расписание;ChaosEngine объединяет приложение или Kubernetes-узел с конкретным ChaosExperiment;ChaosResult — ресурс, который хранит результаты эксперимента и в дальнейшем экспортируется оператором как метрика для Prometheus.Наглядная схема, как работает Litmus:

Теперь же о практике. Установим оператор, следуя документации [3]:
$ kubectl apply -f https://litmuschaos.github.io/litmus/litmus-operator-v1.9.0.yaml
$ kubectl -n litmus get po
NAME READY STATUS RESTARTS AGE
chaos-operator-ce-797875d477-b4cwx 1/1 Running 0 88s
Проверим наличие CRD:
$ kubectl get crds | grep chaos
chaosengines.litmuschaos.io 2020-10-27T08:58:39Z
chaosexperiments.litmuschaos.io 2020-10-27T08:58:39Z
chaosresults.litmuschaos.io 2020-10-27T08:58:39Z
В специальном хранилище под названием ChaosHub [4] уже есть большое количество готовых экспериментов. Создадим отдельный namespace для экспериментов и последуем дальше за руководством, развернув эксперименты с хаба:
$ kubectl create ns nginx
$ kubectl apply -f https://hub.litmuschaos.io/api/chaos/1.9.0?file=charts/generic/experiments.yaml -n nginx
chaosexperiment.litmuschaos.io/pod-network-duplication created
chaosexperiment.litmuschaos.io/node-drain created
chaosexperiment.litmuschaos.io/node-io-stress created
chaosexperiment.litmuschaos.io/disk-fill created
chaosexperiment.litmuschaos.io/k8-pod-delete created
chaosexperiment.litmuschaos.io/node-taint created
chaosexperiment.litmuschaos.io/pod-autoscaler created
chaosexperiment.litmuschaos.io/pod-cpu-hog created
chaosexperiment.litmuschaos.io/pod-memory-hog created
chaosexperiment.litmuschaos.io/pod-network-corruption created
chaosexperiment.litmuschaos.io/pod-delete created
chaosexperiment.litmuschaos.io/pod-network-loss created
chaosexperiment.litmuschaos.io/disk-loss created
chaosexperiment.litmuschaos.io/k8-pod-delete unchanged
chaosexperiment.litmuschaos.io/pod-io-stress created
chaosexperiment.litmuschaos.io/k8-service-kill created
chaosexperiment.litmuschaos.io/pod-network-latency created
chaosexperiment.litmuschaos.io/k8-pod-delete unchanged
chaosexperiment.litmuschaos.io/k8-pod-delete unchanged
chaosexperiment.litmuschaos.io/node-cpu-hog created
chaosexperiment.litmuschaos.io/docker-service-kill created
chaosexperiment.litmuschaos.io/kubelet-service-kill created
chaosexperiment.litmuschaos.io/k8-pod-delete unchanged
chaosexperiment.litmuschaos.io/node-memory-hog created
chaosexperiment.litmuschaos.io/k8-pod-delete configured
chaosexperiment.litmuschaos.io/container-kill created
В этом весьма обширном YAML-файле содержится набор экспериментов, один из которых дублирует пакеты, приходящие в pod, другой — опустошает узел с приложением, третий — придавливает диск того же узла и так далее. Все эксперименты — ресурсы, находящиеся в пространстве имен (т.е. namespaced).
Дальнейшие шаги из того же руководства [5] — добавим service account в наш namespace и сделаем более расширенный список прав на ресурсы (мы хотим больше хаоса!):
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: chaos-spawn
namespace: nginx
labels:
name: chaos-spawn
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: chaos-spawn
namespace: nginx
labels:
name: chaos-spawn
rules:
- apiGroups: ["","litmuschaos.io","batch","apps"]
resources: ["nodes","pods","deployments","pods/log","pods/exec","events","jobs","chaosengines","chaosexperiments","chaosresults"]
verbs: ["create","list","get","patch","update","delete","deletecollection"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: chaos-spawn
namespace: nginx
labels:
name: chaos-spawn
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: chaos-spawn
subjects:
- kind: ServiceAccount
name: chaos-spawn
namespace: nginx
$ kubectl apply -f rbac.yaml
serviceaccount/pod-delete-sa created
role.rbac.authorization.k8s.io/pod-delete-sa created
rolebinding.rbac.authorization.k8s.io/pod-delete-sa created
В качестве жертвы попробуем:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
Убедимся, что этот Deployment выкатился:
$ kubectl -n nginx get po
NAME READY STATUS RESTARTS AGE
nginx-deployment-85ff79dd56-9bcnn 1/1 Running 0 7s
nginx-deployment-85ff79dd56-lq8r5 1/1 Running 0 7s
nginx-deployment-85ff79dd56-pjwvd 1/1 Running 0 7s
Для ограничения радиуса поражения используется аннотирование ресурса:
$ kubectl -n nginx annotate deploy/nginx-deployment litmuschaos.io/chaos="true"
deployment.apps/nginx-deployment annotated
Следуя документации [6], делаем ChaosEngine (напомню, что это CR, который объединяет приложение с хаос-экспериментами):
apiVersion: litmuschaos.io/v1alpha1
kind: ChaosEngine
metadata:
name: nginx-chaos
namespace: nginx
spec:
appinfo:
appns: 'nginx'
applabel: 'app=nginx'
appkind: 'deployment'
annotationCheck: 'true'
engineState: 'active'
auxiliaryAppInfo: ''
chaosServiceAccount: chaos-spawn
monitoring: false
experiments:
- name: pod-delete
spec:
components:
env:
# set chaos duration (in sec) as desired
- name: TOTAL_CHAOS_DURATION
value: '30'
- name: FORCE
value: 'false'
- name: pod-cpu-hog
spec:
components:
env:
- name: CPU_CORES
value: '4'
- name: TARGET_CONTAINER
value: 'nginx'
- name: pod-memory-hog
spec:
components:
env:
- name: TARGET_CONTAINER
value: 'nginx'
Эксперименты в стандартном варианте этого ресурса показались мне нежным поглаживанием: хочется попробовать что-то более интересное, поэтому мы убьём приложение и немного нагрузим память и CPU.
Отдельно отмечу отсутствие строчки jobCleanUpPolicy: 'delete' в описании ChaosEngine — она нужна, чтобы оператор не удалял «хаосита» после работы и мы увидели, что происходит:
$ kubectl -n nginx get po
NAME READY STATUS RESTARTS AGE
nginx-chaos-runner 0/1 Completed 0 4m28s
nginx-deployment-85ff79dd56-lq8r5 1/1 Running 0 32m
nginx-deployment-85ff79dd56-nt9n9 1/1 Running 0 3m3s
nginx-deployment-85ff79dd56-ptt54 1/1 Running 0 3m32s
Итак, «хаосит» приводит друзей:
$ kubectl -n nginx get po
NAME READY STATUS RESTARTS AGE
nginx-chaos-runner 1/1 Running 0 15s
nginx-deployment-85ff79dd56-2kjgb 1/1 Running 0 2m18s
nginx-deployment-85ff79dd56-gmhn8 1/1 Running 0 2m34s
nginx-deployment-85ff79dd56-vt4jx 0/1 ContainerCreating 0 1s
nginx-deployment-85ff79dd56-wmfdx 1/1 Terminating 0 2m7s
pod-delete-vsxwf0-p9rt9 1/1 Running 0 7s
$ kubectl -n nginx get po
NAME READY STATUS RESTARTS AGE
nginx-chaos-runner 1/1 Running 0 87s
nginx-deployment-85ff79dd56-2kjgb 1/1 Running 0 3m30s
nginx-deployment-85ff79dd56-8nbll 1/1 Running 0 51s
nginx-deployment-85ff79dd56-gmhn8 1/1 Running 0 3m46s
pod-cpu-hog-lqds5k-d8hg6 1/1 Running 0 17s
Фрагмент логов выжигателя CPU:
time="2020-11-09T19:48:06Z" level=info msg="[Chaos]:Number of pods targeted: 1"
time="2020-11-09T19:48:06Z" level=info msg="[Chaos]: The Target application details" container=nginx Pod=nginx-deployment-85ff79dd56-8nbll CPU CORE=4
time="2020-11-09T19:48:06Z" level=info msg="[Chaos]:Waiting for: 60s"
Однако наш друг Prometheus говорит, что четыре обещанных ядра этот «свинтус» (hog) съесть не смог:

Причина осталось неизвестной, но может быть, мы когда-нибудь исследуем эту (по умолчанию используется https://github.com/alexei-led/pumba [7]) или другую реализацию контейнерной хаос-обезьяны…
Что у нас происходит?
$ kubectl -n nginx get po
NAME READY STATUS RESTARTS AGE
nginx-chaos-runner 1/1 Running 0 2m41s
nginx-deployment-85ff79dd56-2kjgb 1/1 Running 0 4m44s
nginx-deployment-85ff79dd56-8nbll 1/1 Running 0 2m5s
nginx-deployment-85ff79dd56-gmhn8 1/1 Running 0 5m
pod-memory-hog-r3ngl5-kjhl7 1/1 Running 0 5s
Фрагмент логов «кабана», отъедающего память:
time="2020-11-09T19:49:33Z" level=info msg="[Chaos]:Number of pods targeted: 1"
time="2020-11-09T19:49:33Z" level=info msg="[Chaos]: The Target application details" container=nginx Pod=nginx-deployment-85ff79dd56-8nbll Memory Consumption(MB)=500
time="2020-11-09T19:49:33Z" level=info msg="[Chaos]:Waiting for: 60s"
time="2020-11-09T19:49:33Z" level=info msg="The memory consumption is: 500"
С памятью всё точно:

На этом эксперимент закончен:
$ kubectl -n nginx get po
NAME READY STATUS RESTARTS AGE
nginx-chaos-runner 0/1 Completed 0 4m20s
nginx-deployment-85ff79dd56-2kjgb 1/1 Running 0 6m23s
nginx-deployment-85ff79dd56-8nbll 1/1 Running 0 3m44s
nginx-deployment-85ff79dd56-gmhn8 1/1 Running 0 6m39s
А вот и официальные результаты вскрытия:
$ kubectl -n nginx get chaosresults.litmuschaos.io
NAME AGE
nginx-chaos-pod-cpu-hog 8m48s
nginx-chaos-pod-delete 9m49s
nginx-chaos-pod-memory-hog 7m21s
Вердикт для этого примера — «Pass»:
$ kubectl -n nginx get chaosresults.litmuschaos.io
NAME AGE
nginx-chaos-pod-cpu-hog 8m48s
nginx-chaos-pod-delete 9m49s
nginx-chaos-pod-memory-hog 7m21s
$ kubectl -n nginx describe chaosresults.litmuschaos.io nginx-chaos-pod-delete
Name: nginx-chaos-pod-delete
Namespace: nginx
Labels: app.kubernetes.io/component=experiment-job
app.kubernetes.io/part-of=litmus
app.kubernetes.io/version=1.9.1
chaosUID=26c21578-2470-4f08-957f-94267cadc4ff
controller-uid=7ef7d1c0-79c8-4e21-acfc-711b6b83f918
job-name=pod-delete-vsxwf0
name=nginx-chaos-pod-delete
Annotations: <none>
API Version: litmuschaos.io/v1alpha1
Kind: ChaosResult
Metadata:
Creation Timestamp: 2020-11-09T19:47:01Z
Generation: 2
Resource Version: 17209743
Self Link: /apis/litmuschaos.io/v1alpha1/namespaces/nginx/chaosresults/nginx-chaos-pod-delete
UID: 8e60299b-1751-42a3-a22b-29f5a64d86b5
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 10m pod-delete-vsxwf0-p9rt9 experiment: pod-delete, Result: Awaited
Normal Pass 9m42s pod-delete-vsxwf0-p9rt9 experiment: pod-delete, Result: Pass
Если этого показалось, то знайте, что в комплекте Litmus — прекрасное руководство [8], как замониторить хаос-эксперименты полным набором Prometheus + Grafana с имеющимися экспортерами и панелями. При наличии такового можно добавить всё это в уже имеющийся в кластере комплект, но потребуются некоторое время, напильник и рубанок.
Говоря про Litmus в целом, это не самый простой в освоении инструмент, но при внимательном чтении документации всё должно получиться. Кажется, проект предлагает все нужные для тотальной победы хаоса инструменты… всё необходимое для проведения полноценных хаос-экспериментов. А для понимания их результатов есть и отчёты в виде ChaosResults, и логи у всех запускаемых pod'ов (они действительно подробны).
P.S. Именно этот проект стал инициатором недавнего появления группы Kubernetes Chaos Engineering Meetup Group [9].
Это набор инструментов на Python, с помощью которых можно разрабатывать Open API для проведения хаос-экспериментов. У него есть большое количество расширений для разных облачных провайдеров и окружений, в числе которых — интересный нам chaostoolkit-kubernetes [11] (здесь уже GitHub-звёзд заметно меньше: ~150).
Установить Chaos Toolkit Operator для Kubernetes можно с помощью Kustomize (https://docs.chaostoolkit.org/deployment/k8s/operator/ [12]):
$ curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
$ ./kustomize build kubernetes-crd/manifests/overlays/generic-rbac | kubectl apply -f
У родительского проекта имеется очень неплохая документация с примерами (https://github.com/chaostoolkit/chaostoolkit-tutorials [13]).
Однако в целом это не конечное приложение для тех, кто эксплуатирует Kubernetes (или другую инфраструктуру), а именно набор инструментов для разработчика на Python, с продуманным подходом и большим количеством возможностей.
Также у проекта был раньше активен репозиторий ChaosHub, но сейчас он оказался в архиве (https://github.com/chaostoolkit/chaoshub-archive [14]):

Обзор завершит очень необычный инструмент, потому что он сделан в виде… игры!
Итак, скачиваем и устанавливаем чарт (указывая хост для Ingress и whitelist со списком пространств имен, разрешённых для работы приложения):
$ git clone https://github.com/lucky-sideburn/KubeInvaders.git
$ kubectl create namespace kubeinvaders
$ helm install --set-string target_namespace="test-monkeys" --namespace kubeinvaders --set ingress.hostName=invaders.kube.test.io --name kubeinvaders .
После этого достаточно зайти по указанному URL, чтобы увидеть впечатляющий способ убивать pod'ы:

Да! Это легендарная видеоигра Space Invaders [16]. Pod'ы в ней выступают как инопланетные захватчики, а мы должны спасти Землю! (Ну, или просто потестировать, убивая pod'ы вручную или включив автопилот…)
Есть возможность усложнить игру:

Всё настраивается очень просто, есть клиенты для MacOS и Linux. В целом же, пусть с точки зрения функциональных возможностей приложение не так уж богато, сам процесс проходит гораздо веселее.
Как выяснилось, это далеко не единственный способ сделать хаос-инжиниринг веселым. Еще большую популярность среди желающих «поиграть в хаос» в Kubernetes (1200+ звёзд на GitHub) уже получил проект Kube DOOM [17], из названия которого понятна и суть: убивать pod'ы можно в старом добром шутере.

А чтобы список хаос-игр с Kubernetes был ещё более полным и разнообразным, закончим эту мини-категорию ссылкой на Cheeky Monkey [18].
Среди других проектов, которые по разным причинам не были включены в список выше, выделю:
Уже доступен достаточно широкий спектр решений для хаос-экспериментов в Kubernetes: от простых «убивалок» до готовых операторов с разнообразными способами нанести вред всем окружениям и платформы для разработчика собственных хаос-экспериментов. Каждый сможет найти для себя что-то подходящее.
Я бы выделил два варианта использования инструмента для хаос-инжиниринга (в K8s):
Вредите, разрушайте, ломайте, наносите добро — делайте свои приложения и инфраструктуры устойчивыми к любым невзгодам!
Читайте также в нашем блоге:
Автор: bmar
Источник [28]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/open-source/359212
Ссылки в тексте:
[1] первой статье: https://habr.com/ru/company/flant/blog/527664/
[2] https://github.com/litmuschaos/litmus: https://github.com/litmuschaos/litmus
[3] документации: https://docs.litmuschaos.io/docs/next/getstarted.html#install-litmus
[4] ChaosHub: https://hub.litmuschaos.io/
[5] того же руководства: https://docs.litmuschaos.io/docs/next/getstarted.html#setup-service-account
[6] документации: https://docs.litmuschaos.io/docs/next/getstarted.html#prepare-chaosengine
[7] https://github.com/alexei-led/pumba: https://github.com/alexei-led/pumba
[8] прекрасное руководство: https://docs.litmuschaos.io/docs/next/monitoring/
[9] Kubernetes Chaos Engineering Meetup Group: https://community.cncf.io/kubernetes-chaos-engineering-meetup-group/
[10] https://github.com/chaostoolkit/chaostoolkit/: https://github.com/chaostoolkit/chaostoolkit/
[11] chaostoolkit-kubernetes: https://github.com/chaostoolkit/chaostoolkit-kubernetes
[12] https://docs.chaostoolkit.org/deployment/k8s/operator/: https://docs.chaostoolkit.org/deployment/k8s/operator/
[13] https://github.com/chaostoolkit/chaostoolkit-tutorials: https://github.com/chaostoolkit/chaostoolkit-tutorials
[14] https://github.com/chaostoolkit/chaoshub-archive: https://github.com/chaostoolkit/chaoshub-archive
[15] https://github.com/lucky-sideburn/KubeInvaders: https://github.com/lucky-sideburn/KubeInvaders
[16] Space Invaders: https://ru.wikipedia.org/wiki/Space_Invaders
[17] Kube DOOM: https://github.com/storax/kubedoom
[18] Cheeky Monkey: https://github.com/richstokes/cheekymonkey
[19] PowerfulSeal: https://github.com/powerfulseal/powerfulseal
[20] Pod-reaper: https://github.com/target/pod-reaper
[21] этом продвинутом примере: https://github.com/target/pod-reaper/blob/master/examples/complex-deployment.yml
[22] Kube-entropy: https://github.com/alexlokshin/kube-entropy
[23] Fabric8 Chaos Monkey: https://fabric8.io/guide/chaosMonkey.html
[24] Kubernetes от Gremlin: https://www.gremlin.com/kubernetes/
[25] Chaos Engineering: искусство умышленного разрушения. Часть 1: https://habr.com/ru/company/flant/blog/460367/
[26] Chaos Engineering: искусство умышленного разрушения. Часть 2: https://habr.com/ru/company/flant/blog/465107/
[27] Chaos Engineering: искусство умышленного разрушения. Часть 3: https://habr.com/ru/company/flant/blog/477994/
[28] Источник: https://habr.com/ru/post/529062/?utm_source=habrahabr&utm_medium=rss&utm_campaign=529062
Нажмите здесь для печати.