Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Предсказывать системные бои становится всё сложнее. Чтобы предотвратить остановки в работе, крупные и малые компании обратились к chaos engineering в качестве решения.
Chaos engineering позволяет вам прогнозировать и выявлять потенциальные сбои, намеренно внося неисправности в систему. Таким образом можно находить и устранять сбои ещё до того, как они превратятся в простои. Chaos engineering — растущая тенденция для DevOps и IT-команд. Даже такие компании, как Netflix и Amazon, используют эти принципы при разработке своих продуктов.
Если вы новичок в chaos engineering, вы пришли по верному адресу. Сегодня мы подробно познакомим вас с принципами его работы и покажем, как начать работу с Kubernetes.
Вы узнаете:
Что такое Chaos Engineering?
Об инструментах Chaos Engineering
О принципах и процессах Chaos Engineering
О примере Chaos Engineering: приложении Kubernetes
Чему нужно учиться дальше
Что такое Chaos Engineering?
Chaos engineering — это дисциплина, основанная на проведении опытов над системой. С помощью Chaos engineering мы намеренно пытаемся вывести нашу систему из строя при определённых нагрузках для того, чтобы определить потенциальные сбои, найти слабые места и повысить отказоустойчивость.
Chaos engineering отличается от тестирования программного обеспечения или внедрения ошибок. Он нужен для выполнения всевозможных требований и предсказания непредвиденных ситуаций, включающих скачки трафика, условия гонки и многое другое.
Во время использования Chaos engineering мы пытаемся выяснить, как вся система реагирует на отказ отдельного компонента.
Например, Chaos engineering помогает ответить на вопросы функциональности:
Что происходит, когда сервис по какой-то причине становится недоступным?
Каким будет результат сбоев, если приложение получит слишком много трафика или если оно недоступно?
Столкнемся ли мы с каскадными ошибками, если из-за единой точки отказа приложение выйдет из строя?
Что происходит, когда наше приложение выходит из строя?
Что происходит, когда возникают неполадки с сетью?
Предыстория: Chaos Engineering был разработан Netflix в 2008 году, когда потоковый сервис по подписке был переведен в общедоступное облако. Инженеры Netflix отметили, что им нужны новые способы тестирования системы на отказоустойчивость. Поэтому в 2011 году они придумали Chaos Monkey — инструмент для проверки устойчивости облачных систем путем создания сбоев в инфраструктуре и бизнес‑системе.
С тех пор Chaos Engineering получил развитие, и такие компании, как Google, Facebook, Amazon и Microsoft, внедрили аналогичные модели тестирования.
Преимущества Chaos Engineering
Chaos Engineering предлагает преимущества, которые недоступны при других формах тестирования программного обеспечения или тестирования сбоев. Тесты на сбой могут проверять только одно условие в двоичной структуре. Это не позволяет тестировать систему в условиях беспрецедентных или неожиданных нагрузок.
С другой стороны, хаос-инжиниринг объясняет реальные сбои и проблемы. С его помощью можно решить текущие проблемы и получить новое представление о приложении для будущих улучшений.
Эксперименты с хаосом уменьшают количество отказов и отключений, одновременно улучшая само понимание устройства системы. Chaos Engineering улучшает доступность и надежность сервиса, поэтому клиенты меньше страдают от простоев. Он также помогает предотвратить потерю доходов и снизить затраты на обслуживание на уровне бизнеса.
Инструменты Chaos Engineering
Chaos Engineering — это еще не тот сегмент рынка, который устоялся и хорошо развит. Тем не менее, существует ряд инструментов, из которых мы можем выбирать.
Один из самых известных инструментов для Chaos Engineering — это Simian Army, разработанный Netflix. Simian Army подходит для облачных сервисов и AWS. Он может генерировать сбои и обнаруживать отклонения от нормы. Подобным занимается и Chaos Monkey от Netflix — это инструмент устойчивости к случайным сбоям.
PowerfulSeal — это мощный инструмент для тестирования кластеров Kubernetes, а Litmus можно использовать для stateful рабочих нагрузок в Kubernetes. Pumba используется с Docker для тестирования хаоса и эмуляции сети. Gremlin предлагает платформу Chaos Engineering, которая теперь поддерживает тестирование в кластерах Kubernetes.
Chaos Dingo используют для Microsoft Azure, а прокси-сервер «Chaos HTTP proxy» нужен для внесения сбоев в HTTP-запросы.
Принципы и процесс Chaos Engineering
По мере того, как с годами все больше команд проводили эксперименты, они научились наиболее эффективно применять подходы Chaos Engineering к своим системам. Эти передовые практики стали основными принципами Chaos Engineering. Давайте рассмотрим их.
Постройте гипотезу steady state
После построения steady state можно выполнять потенциально опасные действия с задержкой в сети, приложениями, узлами или любым другим компонентом системы.
Создавайте острые ситуации для подтверждения, что гипотеза steady state верна. Вы сможете предположить, что когда система находится в определенном состоянии, она выполняет действия и завершает такую же проверку, чтобы подтвердить, что состояние не изменилось.
Моделируйте реальные события
Применяйте Chaos Engineering на основе реальных событий. Другими словами, копируйте только те события, которые могут произойти в вашей системе. Например, это может быть сбой приложения, нарушение работы сети или отказ узла.
Проведите эксперименты в продакшене
Проводите эксперименты с хаосом в продакшене. Если вы проводите эксперименты с хаосом только на окружениях разработки и для интеграции, вы не можете получить реальную картину того, как ведет себя промышленная система.
Автоматизируйте эксперименты и запускайте их непрерывно
Автоматизируйте эксперименты с хаосом, чтобы они выполнялись непрерывно или как составная часть конвейеров непрерывной поставки. Это может означать каждый час, каждые несколько часов, каждый день, каждую неделю или каждый раз, когда в нашей системе происходит какое-то событие. Проводите эксперименты каждый раз, когда развёртываете новую версию.
Минимизируйте радиус поражения
Когда вы начинаете эксперименты с хаосом, начните с малого и наращивайте масштаб параллельно с тем, как растет уверенность ваша в системе. В конце концов, вам следует провести эксперименты во всей системе.
Резюме главных принципов:
постройте гипотезу о стабильном состоянии;
моделируйте реальные события;
проводите эксперименты в продакшене;
автоматизируйте эксперименты и запускайте их непрерывно;
минимизируйте радиус поражения.
Процесс Chaos Engineering
Общий процесс Chaos Engineering выглядит следующим образом:
Определение гипотезы устойчивого состояния: вам нужно начать с представления о том, что может пойти не так. Начните с выбора ошибки для внедрения в систему и спрогнозируйте результат, когда она будет внедрена в работающую систему.
Подтверждение стабильного состояния и моделирование некоторых реальных событий: выполните тесты с использованием реальных сценариев, чтобы увидеть, как ваша система ведет себя при определенных стрессовых условиях или обстоятельствах.
Еще раз подтвердите стабильное состояние: нам нужно подтвердить, какие изменения произошли, поэтому повторная проверка дает нам представление о поведении системы.
Сбор показателей и наблюдение за информационными панелями: вам нужно измерить надежность и доступность вашей системы. Используйте ключевые показатели производительности, которые соотносятся с клиентским опытом. Например, мы хотим измерить сбой в соответствии с нашей гипотезой, изучив такие факторы, как влияние на задержку или количество запросов в секунду.
Внесение изменений и исправление проблемы. После проведения эксперимента вы должны хорошо понимать, что работает, а что нужно изменить. Теперь мы можем определить, что приведет к недоступности сервиса, и мы точно знаем, что нарушает работу системы. Итак, исправим это и попробуем еще раз с новым экспериментом.
Пример Chaos Engineering
Разберём теорию на реальном примере, чтобы лучше понять Chaos Engineering. Для этого будем использовать Kubernetes. Сначала создадим кластер Kubernetes, затем развернем наше приложение и уничтожим его. А дальше — покажем, как определять стабильные состояния.
Примечание. Если вы новичок в Kubernetes, мы рекомендуем пройти курс «Kubernetes: База», прежде чем продолжить изучение хаоса.
Создайте кластер Kubernetes
Нам нужен кластер Kubernetes для уничтожения. Вы можете выбрать Minikube, Docker Desktop, AKS, EKS и GKE. Ниже мы используем Docker Desktop для создания кластера. Если вы хотите узнать, как создать кластер с помощью других инструментов, обратитесь к курсу The DevOps Toolkit: Kubernetes Chaos Engineering.
# Source: https://gist.github.com/f753c0093a0893a1459da663949df618
####################
# Create A Cluster #
####################
# Open Docker Preferences, select the Kubernetes tab, and select the "Enable Kubernetes" checkbox
# Open Docker Preferences, select the Resources > Advanced tab, set CPUs to 4, and Memory to 6.0 GiB, and press the "Apply & Restart" button
#######################
# Destroy the cluster #
#######################
# Open Docker Troubleshoot, and select the "Reset Kubernetes cluster" button
# Select *Quit Docker Desktop*
Клонирование и осмотр репозитория
Нам нужно развернуть демонстрационное приложение, которое мы подготовили ниже. Мы собираемся клонировать репозиторий vfarcic/go-demo-8
, созданный Виктором Фарчичем (Viktor Farcic).
git clone https://github.com/vfarcic/go-demo-8.git
Далее мы заходим в каталог, куда склонировали репозиторий.
cd go-demo-8
git pull
Теперь создадим пространство имен k8s с именем go-demo-8.
kubectl create namespace go-demo-8
Давайте кратко рассмотрим приложение, которое мы собираемся развернуть, расположенное в каталоге terminate-pods
в файле с именем pod.yaml
.
---
apiVersion: v1
kind: Pod
metadata:
name: go-demo-8
labels:
app: go-demo-8
spec:
containers:
- name: go-demo-8
image: vfarcic/go-demo-8:0.0.1
env:
- name: DB
value: go-demo-8-db
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /
port: 8080
readinessProbe:
httpGet:
path: /
port: 8080
resources:
limits:
cpu: 100m
memory: 50Mi
requests:
cpu: 50m
memory: 20Mi
Это приложение определяется как один pod с одним контейнером go-demo-8
. Он включает в себя так же и другие ресурсы, такие как livenessProbe
и readinessProbe
.
Применение манифеста к кластеру
Теперь мы применяем этот манифест к нашему кластеру внутри пространства имен go-demo-8. Это запустит наше приложение как под.
kubectl --namespace go-demo-8 apply --filename k8s/terminate-pods/pod.yaml
А теперь пришло время что-нибудь сломать и уничтожить наше приложение!
Установите плагин Chaos Toolkit Kubernetes
Чтобы провести эксперименты с хаосом в нашем приложении, мы можем использовать плагин Chaos Toolkit для Kubernetes. Этот инструментарий не поддерживает базовый Kubernetes. Нам нужен плагин для функций, выходящих за рамки базовых готовых функций. Давайте установим плагин Kubernetes, используя pip
.
pip install -U chaostoolkit-kubernetes
Примечание. Изучите плагин Chaos Toolkit с помощью команды discover
, чтобы увидеть все его функции, параметры и аргументы.
Завершение работы экземпляров приложения
Давайте начнем разрушения. Посмотрите на первый манифест, который мы будем использовать, расположенное в каталоге chaos
файла terminate-pod.yaml
.
cat chaos/terminate-pod.yaml
Команда даст нам следующий вывод:
version: 1.0.0
title: What happens if we terminate a Pod?
description: If a Pod is terminated, a new one should be created in its places.
tags:
- k8s
- pod
method:
- type: action
name: terminate-pod
provider:
type: python
module: chaosk8s.pod.actions
func: terminate_pods
arguments:
label_selector: app=go-demo-8
rand: true
ns: go-demo-8
Теперь, когда мы ознакомились с определением, давайте запустим terminate-pod.yaml.
chaos run chaos/terminate-pod.yaml
Вывод будет такой:
[... INFO] Validating the experiment's syntax
[... INFO] Experiment looks valid
[... INFO] Running experiment: What happens if we terminate a Pod?
[... INFO] No steady state hypothesis defined. That's ok, just exploring.
[... INFO] Action: terminate-pod
[... INFO] No steady state hypothesis defined. That's ok, just exploring.
[... INFO] Let's rollback...
[... INFO] No declared rollbacks, let's move on.
[... INFO] Experiment ended with status: completed
После первоначальной проверки манифеста был проведен эксперимент под названием What happens if we terminate a Pod?
и обнаружено, что есть no steady state hypothesis defined
. Судя по выводу, есть только одно действие — terminate-pod.
Затем был произведен возврат к steady state hypothesis
и плагин определил, что это состояние не определено. Далее была произведена попытка rollback
и, оказалось, что она не может быть выполнена. Все, что мы сделали до сих пор, — это выполнили действие по завершению работы пода. Мы можем увидеть результат в последней строке: experiment ended with status: complete
.
Теперь давайте выведем код выхода предыдущей команды. Если мы получим 0, это означает успех в Linux. Эти коды выхода сообщают системе, неудача это или успех!
Посмотрим на поды в нашем пространстве имен.
kubectl --namespace go-demo-8 get pods
В выводе указано, что no resources
были найдены в go-demo-8 namespace.
Мы развернули единственный под и провели эксперимент, в результате которого он был уничтожен. Мы не проводили никаких проверок. А также мы выполнили одно действие для завершения работы пода, которое было успешным.
Определение стабильных состояний
Всё, что мы сделали выше — уничтожили под. Однако цель инженерии хаоса — найти слабые места в наших кластерах. Поэтому мы обычно определяем стабильное состояние, соответствие которому проверяем до и после эксперимента.
Если состояние до и после одинаково, мы можем сделать вывод, что наш кластер отказоустойчив в этом случае. В случае Chaos Toolkit мы достигаем этого путем определения steady state hypothesis
.
Давайте посмотрим на манифест, который определяет состояние, которое будет проверяться до и после действия.
cat chaos/terminate-pod-ssh.yaml
Результат даст нам:
> steady-state-hypothesis:
> title: Pod exists
> probes:
> - name: pod-exists
> type: probe
> tolerance: 1
> provider:
> type: python
> func: count_pods
> module: chaosk8s.pod.probes
> arguments:
> label_selector: app=go-demo-8
> ns: go-demo-8
В манифесте есть новый раздел steady-state-hypothesis
. Теперь мы можем провести настоящий эксперимент с хаосом, чтобы проверить наше стабильное состояние
Запуск эксперимента с хаосом и проверка вывода
Давайте проведем эксперимент с хаосом, чтобы увидеть правильный результат.
chaos run chaos/terminate-pod-ssh.yaml
Получаем следующее:
[... INFO] Validating the experiment's syntax
[... INFO] Experiment looks valid
[... INFO] Running experiment: What happens if we terminate a Pod?
[... INFO] Steady state hypothesis: Pod exists
[... INFO] Probe: pod-exists
[... CRITICAL] Steady state probe 'pod-exists' is not in the given tolerance so failing this experiment
[... INFO] Let's rollback...
[... INFO] No declared rollbacks, let's move on.
[... INFO] Experiment ended with status: failed
Здесь есть критически важная проблема: Steady state probe ’pod-exists’ is not in the given tolerance
. Проверка не удалась, прежде чем мы выполнили действия, потому что мы уничтожили под. Итак, наш эксперимент провалился и подтвердил, что начальное состояние не соответствует тому, что мы хотим.
Итак, давайте применим манифест terminate-pods/pod.yaml
, чтобы воссоздать под. Затем мы сможем увидеть, что произойдет, когда мы повторно запустим эксперимент с steady-state-hypothesis.
kubectl --namespace go-demo-8 apply --filename k8s/terminate-pods/pod.yaml
Повторение эксперимента
С заново запущенным подом повторно запустим эксперимент.
chaos run chaos/terminate-pod-ssh.yaml
Результат выглядит следующим образом:
[... INFO] Validating the experiment's syntax
[... INFO] Experiment looks valid
[... INFO] Running experiment: What happens if we terminate a Pod?
[... INFO] Steady state hypothesis: Pod exists
[... INFO] Probe: pod-exists
[... INFO] Steady state hypothesis is met!
[... INFO] Action: terminate-pod
[... INFO] Steady state hypothesis: Pod exists
[... INFO] Probe: pod-exists
[... INFO] Steady state hypothesis is met!
[... INFO] Let's rollback...
[... INFO] No declared rollbacks, let's move on.
[... INFO] Experiment ended with status: completed
Теперь мы видим, что проба pod-exists
подтвердила правильное состояние и действие terminate-pod
было выполнено. Мы также можем видеть, что была проведена новая проверка на соответствие стабильному состоянию. Под существовал и до действия, и после. Но как может под существовать, если мы его уничтожили?
Добавление задержки
Эксперимент не провалился, потому что наши проверки и действия выполнялись одно за другим. Kubernetes не успел полностью удалить под. Итак, нам нужно добавить паузу, чтобы эксперимент стал более полезным. Давайте посмотрим на YAML.
cat chaos/terminate-pod-pause.yaml
Это дает нам следующий результат:
> pauses:
> after: 10
Мы видим здесь, что мы добавили раздел pauses
после того action
, которое завершает под. Теперь, когда мы выполняем действие по завершению работы пода, система будет ждать 10 секунд перед проверкой нашего состояния.
Проведите эксперимент с задержки
Посмотрим, что мы получим, если проведем этот эксперимент с задержкой.
chaos run chaos/terminate-pod-pause.yaml
Это дает нам следующий результат:
[... INFO] Validating the experiment's syntax
[... INFO] Experiment looks valid
[... INFO] Running experiment: What happens if we terminate a Pod?
[... INFO] Steady state hypothesis: Pod exists
[... INFO] Probe: pod-exists
[... INFO] Steady state hypothesis is met!
[... INFO] Action: terminate-pod
[... INFO] Pausing after activity for 10s...
[... INFO] Steady state hypothesis: Pod exists
[... INFO] Probe: pod-exists
[... CRITICAL] Steady state probe 'pod-exists' is not in the given tolerance so failing this experiment
[... INFO] Let's rollback...
[... INFO] No declared rollbacks, let's move on.
[... INFO] Experiment ended with status: deviated
[... INFO] The steady-state has deviated, a weakness may have been discovered
На этот раз проверка была неуспешна и выдала, что steady state probe ’pod-exists’ is not in the given tolerance so failing this experiment
. Теперь мы дали Kubernetes достаточно времени, чтобы удалить под, а затем проверили, существует ли под.
Система вернулась к нам с сообщением, что пода нет. Мы можем вывести код выхода последней команды, чтобы убедиться, что она действительно не сработала.
Что изучить дальше
Круто! Мы уничтожили наше приложение, используя стабильное состояние, а также изучили основы Chaos Engineering. Далее необходимо исправить ошибки, которые мы создали, чтобы сделать приложение отказоустойчивым.
Нужно разобраться в каждой из проблем в системе.
На курсе «Chaos Engineering» мы как раз рассматриваем технологии хаос-инжиниринга и показываем, как их использовать. Новый поток стартует 15 мая 2023 года. Курс полезен разработчикам, архитекторам и техлидами, которые хотят улучшить устойчивость систем к различным нештатным ситуациям. На курсе также разберём:
Каждую из проблем в системе, вроде деградации сети, забивание диска логами и т. д.
Ожидаемый результат и проверку того, что он трастовый.
Практику по Chaos Blade.
Работу с Cloud native приложениями.
Узнать подробности и записаться: https://slurm.club/3U9ZeB4
С этого момента можно применять все виды разрушений и проверок приложения, такие как:
различные этапы и условия проверок;
эксперименты с доступностью;
очистка (drain) узлов кластера;
выполнение случайного хаоса.
Счастливого обучения!