- PVSM.RU - https://www.pvsm.ru -
Прим. перев.: Это продолжение цикла статей от технологического евангелиста из AWS (Adrian Hornsby) про довольно новую ИТ-дисциплину — chaos engineering, — в рамках которой инженеры проводят эксперименты, призванные смягчить последствия сбоев в системах. Первый [1] материал этого цикла рассказывал про концепцию chaos engineering в целом, второй [2] — о том, как эта деятельность способствует позитивным культурным изменениям внутри организаций.
Последний материал посвящён практике хаос-инжиниринга: методам экспериментирования и инструментам для их непосредственной реализации. Несмотря на то, что его перевод уже публиковался на днях на хабре, у нас готова своя версия, которая кажется нам качественной и по-прежнему уместной для размещения. Так весь цикл перевода этих статей был представлен в едином стиле и наши подписчики — читатели прошлых частей — увидят его полностью.
Прим. автора: Хочу выразить искреннюю признательность своему другу Ricardo Sueiras [3] за его вклад в подготовку этой публикации и за то, что он помог мне сдвинуться с мертвой точки. Рикардо, ты крут!
«Мы становимся тем, что лицезреем. Сначала мы формируем свои инструменты, а затем они формируют нас». — Маршалл Маклюэн [4] (канадский философ, прославившийся своими исследованиями в области коммуникаций; первое предложение этой цитаты, впрочем, заимствовано у британского поэта Уильяма Блейка — прим. перев.)
Важно помнить, что смысл хаос-инжиниринга вовсе НЕ в том, чтобы выпустить «обезьянок» на свободу и позволить им внедрять сбои случайным образом и бесцельно. Наоборот, это четко определенный, формализованный научный метод экспериментирования.
«Метод включает в себя внимательное наблюдение, применение строгого скептицизма к предмету наблюдения, учитывая, что сознательные предположения могут исказить интерпретацию наблюдений. Он включает в себя формулировку гипотез при помощи индукции, основанных на этих наблюдениях; экспериментальную и измеримую проверку выводов, следующих из гипотез; а также уточнение (или отказ от) гипотезы в зависимости от результатов экспериментов». — Wikipedia [5]
Хаос-инжиниринг начинается с понимания устойчивого состояния системы. За этим следует формулировка гипотезы и, наконец, проверка и анализ результатов экспериментов ради повышения отказоустойчивости системы.
Этапы хаос-инжиниринга
В первой части [1] данной серии статей я изложил концепцию хаос-инжиниринга и рассмотрел каждый шаг процесса, изображенного выше.
Во второй части [6] — рассказал о направлениях, с которых следует начинать разработку экспериментов, и о том, как выбрать правильную гипотезу.
В этой, третьей, части речь пойдет о самих экспериментах. Будет представлена коллекция инструментов и методов, покрывающих широкий спектр возможностей по «внесению неисправностей [7]» (fault injection или failure injection), необходимый для проведения экспериментов хаос-инжиниринга.
Список нельзя назвать исчерпывающим, однако его вполне достаточно для начала и того, чтобы заложить основу для дальнейших размышлений.
Внедрение неисправностей в систему позволяет понять и проверить, соответствует ли спецификациям её реакция на стрессовые условия. Впервые эта методика использовалась для провоцирования неисправностей на аппаратном уровне [8] — в частности, на уровне контактов — путём изменения электрических сигналов на устройствах.
В разработке программного обеспечения внесение неисправностей помогает повысить отказоустойчивость системы и устранить потенциально слабые места. Этот процесс получил название «устранение неисправностей» (fault removal). Также он помогает прикинуть потенциальные последствия сбоя — то есть его радиус поражения — ещё до того, как нечто подобное случится в production. Это называется «прогнозированием неисправностей» (failure forecasting).
У внесения неисправностей есть несколько важных плюсов. Оно помогает:
Внедрение неисправностей подразделяется на пять категорий:
Далее я рассмотрю каждую категорию и приведу пример внесения неисправности для каждой из них. Кроме того, расскажу о некоторых комплексных инструментах для внесения сбоев и управления ими.
* Примечание: в этой статье не будет рассматриваться внесение неисправностей на уровне персонала. Эту тему затрону в отдельной публикации.
Хотя облачные услуги приучили нас к тому, что ресурсы практически безграничны, вынужден вас разочаровать: это не так. Экземпляр, контейнер, функция и т.д. — независимо от уровня абстракции, ресурсы рано или поздно закончатся. Проверкой устойчивости системы, поставленной в условия жесткой нехватки ресурсов, и занимается подход с названием «исчерпание ресурсов» (resource exhaustion [9]).
Исчерпание ресурсов обычно выглядит как DoS-атака [11] (правда, не совсем привычная), стремящаяся помешать работе целевого хоста. Это довольно популярный способ внесения неисправностей — возможно, по той причине, что его легко реализовать.
Один из моих любимых инструментов — stress-ng [12], реинкарнация оригинальной утилиты [13], которую разработал Amos Waterland.
С помощью stress-ng можно внедрить неисправности в различные физические подсистемы компьютера, а также в интерфейсы ядра ОС, используя «стрессоры» (stressors). Они доступны для: CPU, кэша CPU, устройств, ввода/вывода, прерываний, файловой системы, памяти, сети, операционной системы, конвейеров, планировщиков, виртуальных машин. Страницы руководства [12] включают полное описание всех доступных стресс-тестов, коих насчитывается целых 220 штук!
Вот несколько полезных примером применения stress-ng:
matrixprod
— предлагает отличное сочетание операций с памятью, кэшем и с плавающей запятой. Пожалуй, является лучшим способом «поджарить» CPU.
❯ stress-ng —-cpu 0 --cpu-method matrixprod -t 60s
iomix-bytes
пишет N байтов для каждого процесса-worker'а iomix. Значение N по умолчанию равно 1 Гб и идеально подходит для стресс-теста ввода/вывода. В этом примере я указываю 80 % свободного пространства в файловой системе:
❯ stress-ng --iomix 1 --iomix-bytes 80% -t 60s
vm-bytes
идеально подходит для проведения стресс-тестов памяти. В данном примере stress-ng запускает 9 стрессоров виртуальной памяти. Вместе они «съедают» 90 % доступной памяти на один час (каждый стрессор использует 10 % доступной памяти):
❯ stress-ng --vm 9 --vm-bytes 90% -t 60s
dd
— это утилита для командной строки, созданная для преобразования и копирования файлов. При этом dd может читать (или писать) из специальных файлов устройств, таких как /dev/zero
и /dev/random
, для задач вроде резервного копирования загрузочного сектора жёсткого диска или получения определенного количества случайной информации. Таким образом, её также можно использовать для внесения неисправности в хост и имитации заполнения диска. Помните, как ваши логи съели всё свободное пространство на сервере и привели к падению приложения? Эта утилита способна помочь, но также и навредить.
Используйте dd чрезвычайно осторожно! Ошибка в команде может стереть, уничтожить или перезаписать данные на жёстком диске!
❯ dd if=/dev/urandom of=/burn bs=1M count=65536 iflag=fullblock &
Производительность, отказоустойчивость и масштабируемость API имеют большое значение. В самом деле, API позволяют компаниям совершенствовать свои приложения и развивать бизнес.
Нагрузочное тестирование (load testing [14]) — отличная возможность испытать приложение, прежде чем оно попадёт в production. Также это превосходный метод стресс-тестирования, позволяющий выявить проблемы и ограничения, которые в противном случае могли бы проявиться только при реальной нагрузке.
wrk
[15] — инструмент для бенчмаркинга HTTP, способный генерировать значительную нагрузку на системы. Мне очень нравится нагружать API для health-check'ов — особенно, если это глубокие проверки [16], поскольку они позволяют многое узнать об архитектурных решениях в проекте: как настроен кэш? Как работает ограничение по частоте? Уделяет ли система приоритетное внимание health-check'ам от балансировщиков нагрузки?
Вот отличная отправная точка:
❯ wrk -t12 -c400 -d20s http://127.0.0.1/api/health
Эта команда запускает 12 потоков и держит открытыми 400 HTTP-подключений в течение 20 секунд.
Eight Fallacies of Distributed Computing [17] от Peter'а Deutsch'а — это набор из предположений, которыми руководствуются разработчики при проектировании распределённых систем. Однако они часто оборачиваются против них, вызывая перебои в работе системы и заставляя менять её архитектуру. Вот эти предположения:
Этот список, по сути, представляет собой готовый перечень направлений для внесения неисправностей и проверки способности распределенной системы противостоять сетевым сбоям.
tc
(traffic control) [18] — это инструмент командной строки для конфигурации планировщика пакетов ядра Linux. Он определяет, как пакеты попадают в очередь для передачи и приёма по сетевому интерфейсу. Возможности включают постановку в очередь, применение политик, классификацию, планирование, шейпинг и отбрасывание.
tc можно использовать для имитации задержки и потери пакетов для UDP- или TCP-приложений, а также для ограничения пропускной способности сети для конкретного сервиса с целью имитировать реальное перемещение трафика в интернете.
— Внедряем задержку в 100 мс:
# Запуск
❯ tc qdisc add dev eth0 root netem delay 100ms
# Остановка
❯ tc qdisc del dev eth0 root netem delay 100ms
— Внедряем задержку в 100 мс с дельтой в 50 мс:
# Запуск
❯ tc qdisc add dev eth0 root netem delay 100ms 50ms
# Остановка
❯ tc qdisc del dev eth0 root netem delay 100ms 50ms
— Имитируем повреждение 5 % сетевых пакетов:
# Запуск
❯ tc qdisc add dev eth0 root netem corrupt 5%
# Остановка
❯ tc qdisc del dev eth0 root netem corrupt 5%
— Имитируем потерю 7 % пакетов с корреляцией в 25 %:
# Запуск
❯ tc qdisc add dev eth0 root netem loss 7% 25%
# Остановка
❯ tc qdisc del dev eth0 root netem loss 7% 25%
Примечание: 7 % позволяют сохранить работоспособность TCP.
/etc/hosts
— это простой текстовый файл, сопоставляющий IP-адреса с доменными именами (одна строка на адрес). Для каждого хоста должна быть своя строка со следующей информацией:
IP_адрес каноническое_доменное_имя [алиасы...]
Файл hosts — один из нескольких способов, с помощью которых компьютер сопоставляет сетевые узлы в компьютерной сети и переводит понятные для человека домены в IP-адреса [19]. Как вы уже догадались, он отлично подходит и для запутывания компьютеров. Вот несколько примеров:
— Блокируем доступ к API DynamoDB из экземпляра EC2:
# Запуск
# Копируем /etc/hosts в /etc/host.back
❯ cp /etc/hosts /etc/hosts.back
❯ echo "127.0.0.1 dynamodb.us-east-1.amazonaws.com" >> /etc/hosts
❯ echo "127.0.0.1 dynamodb.us-east-2.amazonaws.com" >> /etc/hosts
❯ echo "127.0.0.1 dynamodb.us-west-1.amazonaws.com" >> /etc/hosts
❯ echo "127.0.0.1 dynamodb.us-west-2.amazonaws.com" >> /etc/hosts
❯ echo "127.0.0.1 dynamodb.eu-west-1.amazonaws.com" >> /etc/hosts
❯ echo "127.0.0.1 dynamodb.eu-north-1.amazonaws.com" >> /etc/hosts
# Остановка
# Возвращаем изначальную версию /etc/hosts
❯ cp /etc/hosts.back /etc/hosts
— Блокируем доступ экземпляра EC2 к API EC2:
# Запуск
# Копируем /etc/hosts в /etc/host.back
❯ cp /etc/hosts /etc/hosts.back
❯ echo "127.0.0.1 ec2.us-east-1.amazonaws.com" >> /etc/hosts
❯ echo "127.0.0.1 ec2.us-east-2.amazonaws.com" >> /etc/hosts
❯ echo "127.0.0.1 ec2.us-west-1.amazonaws.com" >> /etc/hosts
❯ echo "127.0.0.1 ec2.us-west-2.amazonaws.com" >> /etc/hosts
❯ echo "127.0.0.1 ec2.eu-west-1.amazonaws.com" >> /etc/hosts
❯ echo "127.0.0.1 ec2.eu-north-1.amazonaws.com" >> /etc/hosts
# Остановка
# Возвращаем /etc/hosts
❯ cp /etc/hosts.back /etc/hosts
Вот пример работы с этим файлом. Изначально API EC2 доступен, и команда ec2 describe-instances
завершается успешно:
Но как только я добавляю строку 127.0.0.1 ec2.eu-west-1.amazonaws.com
в /etc/hosts
, вызовы перестают доходить до API EC2:
Конечно, этот метод работает для всех endpoint'ов AWS.
Идёт обновление кэша DNS…
… только вам потребуется 24 часа, чтобы его понять.
21 октября 2016 году DDoS-атака на Dyn [20] привела к тому, что значительное число интернет-платформ и сервисов оказались недоступны в Европе и Северной Америке. Согласно отчёту ThousandEyes Global DNS Performance [21] за 2018 год, 60 % компаний и SaaS-провайдеров по-прежнему полагаются на один источник DNS и, следовательно, уязвимы перед сбоями DNS. Поскольку без DNS нет и интернета, разумно имитировать падение этой службы, чтобы проверить устойчивость системы к возможному отказу DNS.
Традиционно для борьбы с DDoS-атаками [22] используется така называемый blackholing — метод, в котором «плохой» сетевой трафик отправляется прямиком в «чёрную дыру» и выбрасывается в пустоту (этакая сетевая версия /dev/null
). Можно воспользоваться им для имитации потери сетевого трафика или отказа протокола, например, службы DNS [23].
С этой работой прекрасно справится iptables [24]. Эта утилита используется для настройки, обслуживания и анализа таблиц с правилами фильтрации IP-пакетов в ядре Linux.
Чтобы отправить DNS-трафик в «чёрную дыру», попробуйте сделать следующее:
# Запуск
❯ iptables -A INPUT -p tcp -m tcp --dport 53 -j DROP
❯ iptables -A INPUT -p udp -m udp --dport 53 -j DROP
# Остановка
❯ iptables -D INPUT -p tcp -m tcp --dport 53 -j DROP
❯ iptables -D INPUT -p udp -m udp --dport 53 -j DROP
Один из главных недостатков инструментов под Linux, таких как tc
и iptables
, состоит в том, что они требуют root-привилегий для своей работы, что может быть проблематично для некоторых организаций и ситуаций. В этом случае на выручку придет Toxiproxy!
Toxiproxy [25] — это TCP-прокси с открытым исходным кодом, разработанный инженерной командой Shopify [26]. Он помогает имитировать хаотические сетевые и системные условия из реальной жизни. Для этого достаточно поместить Toxiproxy между компонентами инфраструктуры, как показано на иллюстрации ниже:
Слайд из выступления [27] Simon'а Eskildsen'а, главы команды production-разработки, Shopify
Этот инструмент специально разработан для окружений с тестами, CI и разработкой, он поддерживает детерминированный или рандомизированный хаос, а также кастомизацию. Toxiproxy манипулирует соединением между клиентом и upstream'ом с помощью так называемых «токсиков» (toxics [28]) и поддерживает настройку через HTTP API [29]. Кроме того, инструмент поставляется с набором предустановленных токсиков.
В примере ниже показывается, как Toxiproxy с помощью downstream-токсика увеличивает задержку на 1000 мс между клиентом Redis, redis-cli и самой Redis:
Начиная с октября 2014 года Toxiproxy с успехом используется во всех development- и test-средах в Shopify. Подробности о Toxiproxy можно узнать из этой записи в блоге [30].
Программы падают. Это общеизвестный факт. Что делать, если произошел сбой? Следует ли зайти на сервер по SSH и перезапустить упавший процесс? Системы контроля процессов позволяют следить за состоянием процесса или изменять его с помощью таких директив, как start, stop, restart. Эти системы обычно реализуются для постоянного контроля за процессом. Одним из таких инструментов является systemd
[31]. Он обеспечивает базовый набор методов для управления процессами в Linux. Supervisord
[32] предлагает аналогичный функционал для UNIX-подобных операционных систем.
Эти инструменты следует использовать при деплое приложений. Конечно, прежде всего надо изучить последствия от падений критических процессов. Убедитесь, что получаете соответствующие уведомления, а процессы перезапускаются в автоматическом режиме:
— «Убийство» Java-процессов:
❯ pkill -KILL -f java
# Альтернативный способ
❯ pkill -f 'java -jar'
— «Убийство» процессов Python:
❯ pkill -KILL -f python
Конечно, с помощью pkill
можно убить практически любой процесс в системе.
Если и есть сбои, жалобы на которые терпеть не может поддержка, так это те, которые имеют отношение к базам данных. Данные ценятся на вес золота, и всякий раз, когда происходит сбой в БД, возрастает риск потери данных клиентов.
В некоторых случаях способность как можно быстрее восстановить данные и вернуть систему в работоспособное состояние может определить судьбу компании. К сожалению, подготовиться ко всему разнообразию сбоев баз данных непросто, и многие из них проявляются только в production.
Впрочем, если вы используете Amazon Aurora [33], то можете проверить отказоустойчивость кластера баз данных Amazon Aurora путем специальных запросов с внедрением ошибок [34].
Запросы со сбоями в виде SQL-команд направляются экземпляру Amazon Aurora и позволяют запланировать «возникновение» одного из следующих событий:
Отправляя запрос со сбоем, вы также указываете желаемую продолжительность имитации неисправности.
— Падение экземпляра Amazon Aurora:
ALTER SYSTEM CRASH [ INSTANCE | DISPATCHER | NODE ];
— Имитация отказа реплики Aurora:
ALTER SYSTEM SIMULATE percentage PERCENT READ REPLICA FAILURE
[ TO ALL | TO "replica name" ]
FOR INTERVAL quantity { YEAR | QUARTER | MONTH | WEEK | DAY | HOUR | MINUTE | SECOND };
— Имитация выхода из строя диска в кластере с БД Aurora:
ALTER SYSTEM SIMULATE percentage PERCENT DISK FAILURE
[ IN DISK index | NODE index ]
FOR INTERVAL quantity { YEAR | QUARTER | MONTH | WEEK | DAY | HOUR | MINUTE | SECOND };
— Имитация повышенной загрузки диска в кластере с БД Aurora:
ALTER SYSTEM SIMULATE percentage PERCENT DISK CONGESTION
BETWEEN minimum AND maximum MILLISECONDS
[ IN DISK index | NODE index ]
FOR INTERVAL quantity { YEAR | QUARTER | MONTH | WEEK | DAY | HOUR | MINUTE | SECOND };
Внедрять сбои может быть непросто, если вы используете serverless-компоненты, поскольку управляемые serverless-сервисы вроде AWS Lambda изначально не поддерживают внесение неисправностей.
Чтобы решить эту проблему, я написал небольшую библиотеку на Python [35] и лямбда-слой [36] для внедрения сбоев в AWS Lambda [37]. Оба в настоящее время поддерживают задержки, ошибки, исключения и внедрение кодов ошибок HTTP.
Само внесение неисправностей осуществляется путём задания следующих параметров в AWS SSM Parameter Store [38]:
{
"isEnabled": true,
"delay": 400,
"error_code": 404,
"exception_msg": "I really failed seriously",
"rate": 1
}
Можно добавить декоратор Python в функцию-обработчик для внедрения неисправности.
— Вызываем исключение:
@inject_exception
def handler_with_exception(event, context):
return {
'statusCode': 200,
'body': 'Hello from Lambda!'
}
>>> handler_with_exception('foo', 'bar')
Injecting exception_type <class "Exception"> with message I really failed seriously a rate of 1
corrupting now
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/.../chaos_lambda.py", line 316, in wrapper
raise _exception_type(_exception_msg)
Exception: I really failed seriously
— Внедряем неправильный код ошибки HTTP:
@inject_statuscode
def handler_with_statuscode(event, context):
return {
'statusCode': 200,
'body': 'Hello from Lambda!'
}
>>> handler_with_statuscode('foo', 'bar')
Injecting Error 404 at a rate of 1
corrupting now
{'statusCode': 404, 'body': 'Hello from Lambda!'}
— Внедряем задержку:
@inject_delay
def handler_with_delay(event, context):
return {
'statusCode': 200,
'body': 'Hello from Lambda!'
}>>> handler_with_delay('foo', 'bar')
Injecting 400 of delay with a rate of 1
Added 402.20ms to handler_with_delay
{'statusCode': 200, 'body': 'Hello from Lambda!'}
Чтобы узнать больше об этой Python-библиотеке, перейдите по ссылке [35].
Lambda по умолчанию использует механизм безопасности для параллельной (concurrent) работы всех функций в определённом регионе для каждой учётной записи. Под параллельной работой подразумевается число выполнений кода функции в любой момент времени. Оно используется для масштабирования вызовов функции в ответ на входящие запросы. Однако его же можно использовать для обратной цели: замедления работы Lambda.
❯ aws lambda put-function-concurrency --function-name <value> --reserved-concurrent-executions 0
Эта команда установит concurrency
на нуль, вынуждая запросы завершаться с ошибкой 429
(«слишком много запросов»).
Этот инструмент для наблюдения за serverless-архитектурой обладает встроенной возможностью внедрять неисправности в serverless-приложения. Thundra [39] использует так называемые span listeners [40] для внедрения сбоев, таких как отсутствие обработчика ошибок для DynamoDB, отсутствие резервного источника данных или отсутствие таймаута для исходящих HTTP-запросов. Я сам не пользовался этим инструментом, однако эта публикация [41] от Yan Cui [42] и это замечательное видео [43] от Marcia Villalba [44] прекрасно описывают процесс работы. Исходя из них, Thundra выглядит многообещающе.
Подводя черту под serverless-разделом, хочу порекомендовать всем отличную статью [45] о сложностях хаос-инжиниринга в serverless-приложениях, которую написал уже упомянутый Yan Cui.
Хаос-инжиниринг начинался в инъекции сбоев на уровне инфраструктуры — как в случае Amazon, так и в случае Netflix [1]. Пожалуй, инфраструктурные сбои: от отключения целого ЦОД и до случайной остановки экземпляров — реализовать проще всего.
И, естественно, первым на ум приходит пример с chaos monkey [46].
На заре своего существования Netflix озаботился разработкой и внедрением правильного подхода к архитектурным решениям. Chaos monkey стала одним из первых приложений, развернутых в AWS, которое следило на состоянием автомасштабируемых stateless-микросервисов. Другими словами, любой экземпляр мог быть остановлен и автоматически заменен без потери состояния. Chaos monkey следила за тем, чтобы никто не нарушал это правило.
Следующий скрипт — по аналогии с хаос-обезьянкой — случайным образом выбирает и останавливает экземпляр в определенной зоне доступности внутри региона:
❯ stop_random_instance(az="eu-west-1a", tag_name="chaos", tag_value="chaos-ready", region="eu-west-1")
import boto3
import random
REGION = 'eu-west-1'
def stop_random_instance(az, tag_name, tag_value, region=REGION):
'''
>>> stop_random_instance(az="eu-west-1a", tag_name='chaos', tag_value="chaos-ready", region='eu-west-1')
['i-0ddce3c81bc836560']
'''
ec2 = boto3.client("ec2", region_name=region)
paginator = ec2.get_paginator('describe_instances')
pages = paginator.paginate(
Filters=[
{
"Name": "availability-zone",
"Values": [
az
]
},
{
"Name": "tag:" + tag_name,
"Values": [
tag_value
]
}
]
)
instance_list = []
for page in pages:
for reservation in page['Reservations']:
for instance in reservation['Instances']:
instance_list.append(instance['InstanceId'])
print("Going to stop any of these instances", instance_list)
selected_instance = random.choice(instance_list)
print("Randomly selected", selected_instance)
response = ec2.stop_instances(InstanceIds=[selected_instance])
return response
Обратите внимание на tag_name
и tag_value
. Подобные маленькие хитрости помогают предотвратить отключение «не того» экземпляра. #lessonlearned
— «Да, было бы классно, если бы вы перезапустили базу…» — Упс, не тот экземпляр...
Высока вероятность, что вы ошеломлены всем разнообразием инструментов, о которых шла речь до настоящего момента. К счастью, есть несколько готовых пакетов по оркестрации и внедрению неисправностей, которые объединяют функциональность вышеперечисленных инструментов, делая это в простой и удобной форме.
Chaos Toolkit [48] — один из моих любимейших инструментов подобного рода. Это целая Open Source-платформа для хаос-инжиниринга, поддерживаемая (на коммерческой основе) прекрасной командой ChaosIQ, [49] включающей в числе прочих Russ Miles [50], Sylvain Hellegouarch [51] и Marc Perrien [52].
Chaos Toolkit предлагает декларативный и расширяемый открытый API для экспериментов по организации хаоса. Он включает в себя драйверы для AWS, Google Cloud Engine, Microsoft Azure, Cloud Foundry, Humio, Prometheus и Gremlin.
Расширения — это набор тестов и последовательностей действий для организации различных экспериментов — например, для случайной остановки экземпляров в определенной зоне доступности, если значение tag-key
равно chaos-ready
.
{
"version": "1.0.0",
"title": "What is the impact of randomly terminating an instance in an AZ",
"description": "terminating EC2 instance at random should not impact my app from running",
"tags": ["ec2"],
"configuration": {
"aws_region": "eu-west-1"
},
"steady-state-hypothesis": {
"title": "more than 0 instance in region",
"probes": [
{
"provider": {
"module": "chaosaws.ec2.probes",
"type": "python",
"func": "count_instances",
"arguments": {
"filters": [
{
"Name": "availability-zone",
"Values": ["eu-west-1c"]
}
]
}
},
"type": "probe",
"name": "count-instances",
"tolerance": [0, 1]
}
]
},
"method": [
{
"type": "action",
"name": "stop-random-instance",
"provider": {
"type": "python",
"module": "chaosaws.ec2.actions",
"func": "stop_instance",
"arguments": {
"az": "eu-west-1c"
},
"filters": [
{
"Name": "tag-key",
"Values": ["chaos-ready"]
}
]
},
"pauses": {
"after": 60
}
}
],
"rollbacks": [
{
"type": "action",
"name": "start-all-instances",
"provider": {
"type": "python",
"module": "chaosaws.ec2.actions",
"func": "start_instances",
"arguments": {
"az": "eu-west-1c"
},
"filters": [
{
"Name": "tag-key",
"Values": ["chaos-ready"]
}
]
}
}
]
}
Запустить этот эксперимент просто:
❯ chaos run experiment_aws_random_instance.json
Преимущество Chaos Toolkit, во-первых, в открытых исходниках (поэтому его легко приспособить для конкретных потребностей). Во-вторых, он прекрасно интегрируется в CI/CD-пайплайн и поддерживает непрерывное хаос-тестирование.
Недостатком Chaos Toolkit'а является его сложность: чтобы начать работать, необходимо разобраться в его особенностях и принципах. Более того, в Toolkit'е нет готовых экспериментов: придётся написать свои собственные. Впрочем, команда ChaosIQ активно работает над устранением этого недостатка.
Другой мой любимый инструмент — Gremlin — включает в себя полный набор режимов внесения неисправностей в простой и удобной для использования форме с интуитивно понятным пользовательским интерфейсом — этакий вариант Chaos-as-a-Service.
Gremlin обеспечивает внедрение ошибок в ресурсы [54], состояния [55], сеть [56] и запросы [57], позволяя экспериментировать с различными частями системы. Он поддерживает bare metal, различных поставщиков облачных услуг, контейнерные среды (включая Kubernetes*), приложения и (в некоторой степени) serverless-вычисления.
* Прим. перев.: Подробнее об использовании Gremlin в контексте Kubernetes (и не только) можно прочитать, например, в этой статье [58].
Бонусом идет отличный контент в блоге проекта [59]. Кроме того, ребята из Gremlin по-настоящему круты и всегда готовы прийти на выручку! Прежде всего это Matthew [60], Kolton [61], Tammy [62], Rich [63], Ana [64] и HML [65].
Работать с Gremlin'ом весьма просто.
Войдите в приложение и выберите Create Attack:
Выберите целевой экземпляр:
Выберите тип неисправности, которую хотите внедрить, и выпустите (unleash) маленького гремлина на свободу!
Должен признать, что всегда любил Gremlin, поскольку он делает хаос-экспериментирование простым и понятным.
Недостатком, на мой взгляд, является ценообразование [66]. Оно не слишком подходит новичкам или для эпизодического (on-demand) использования из-за своей лицензии. Впрочем, недавно появилась бесплатная версия. Другим минусом Gremlin'а является необходимость устанавливать клиента и демона в экземпляры, которые станут целями атаки, что по душе далеко не всем.
Сервис EC2 Run Command [67], представленный в 2015 году, был создан для безопасного и простого администрирования экземпляров EC2. Сегодня он позволяет удаленно и безопасно управлять конфигурацией экземпляров не только типа EC2, но и из гибридных окружений [68]. К ним относятся on-premises-серверы, виртуальные машины и даже ВМ в других облачных окружениях, используемых с Systems Manager.
Run Command позволяет автоматизировать DevOps-задачи или проводить обновления конфигурации независимо от размера вашего парка.
Run Command преимущественно используется для таких задач, как установка и bootstrapping приложений, захват логов или присоединение экземпляров к домену Windows, однако он также хорошо подходит для проведения хаос-экспериментов.
У меня есть запись в блоге [69], посвященная внедрению хаоса с помощью AWS System Manager, а также готовые исходники [70] для экспериментов. Попробуйте — уверен, вам понравится!
Прежде чем закончить эту статью, хочу подчеркнуть несколько важных моментов, касающихся внедрения сбоев.
«Цените хаос независимо от обстоятельств. Найдите для него место в своём путешествии». — Olga Hall, старший менеджер команды Resilience Engineering в Amazon Prime Video.
На этом всё. Спасибо, что дочитали до конца! Надеюсь, вам понравилась третья часть. Жду от вас мнений, комментариев и, конечно, хлопков в ладоши (на Medium [72] — прим. перев.)!
Читайте также в нашем блоге:
Автор: Андрей Сидоров
Источник [74]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/testirovanie-it-sistem/340545
Ссылки в тексте:
[1] Первый: https://habr.com/ru/company/flant/blog/460367/
[2] второй: https://habr.com/ru/company/flant/blog/465107/
[3] Ricardo Sueiras: https://medium.com/@094459
[4] Маршалл Маклюэн: https://ru.wikipedia.org/wiki/%D0%9C%D0%B0%D0%BA%D0%BB%D1%8E%D1%8D%D0%BD,_%D0%9C%D0%B0%D1%80%D1%88%D0%B0%D0%BB%D0%BB
[5] Wikipedia: https://en.wikipedia.org/wiki/Scientific_method
[6] второй части: https://habr.com/en/company/flant/blog/465107/
[7] внесению неисправностей: https://ru.wikipedia.org/wiki/%D0%92%D0%BD%D0%B5%D1%81%D0%B5%D0%BD%D0%B8%D0%B5_%D0%BD%D0%B5%D0%B8%D1%81%D0%BF%D1%80%D0%B0%D0%B2%D0%BD%D0%BE%D1%81%D1%82%D0%B5%D0%B9
[8] провоцирования неисправностей на аппаратном уровне: https://ieeexplore.ieee.org/document/780999/
[9] resource exhaustion: https://en.wikipedia.org/wiki/Resource_exhaustion_attack
[10] Image: https://xkcd.ru/676/
[11] DoS-атака: https://ru.wikipedia.org/wiki/DoS-%D0%B0%D1%82%D0%B0%D0%BA%D0%B0
[12] stress-ng: https://www.mankier.com/1/stress-ng
[13] оригинальной утилиты: https://directory.fsf.org/wiki/Stress
[14] load testing: https://ru.wikipedia.org/wiki/%D0%9D%D0%B0%D0%B3%D1%80%D1%83%D0%B7%D0%BE%D1%87%D0%BD%D0%BE%D0%B5_%D1%82%D0%B5%D1%81%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5
[15] wrk
: https://github.com/wg/wrk
[16] глубокие проверки: https://medium.com/@adhorn/patterns-for-resilient-architecture-part-3-16e8601c488e
[17] Eight Fallacies of Distributed Computing: https://en.wikipedia.org/wiki/Fallacies_of_distributed_computing
[18] tc
(traffic control): http://tldp.org/HOWTO/Traffic-Control-HOWTO/intro.html
[19] IP-адреса: https://ru.wikipedia.org/wiki/IP-%D0%B0%D0%B4%D1%80%D0%B5%D1%81
[20] DDoS-атака на Dyn: https://en.wikipedia.org/wiki/2016_Dyn_cyberattack
[21] отчёту ThousandEyes Global DNS Performance: https://www.thousandeyes.com/resources/2018-global-dns-performance-benchmark-report
[22] DDoS-атаками: https://en.wikipedia.org/wiki/Denial-of-service_attack
[23] службы DNS: https://ru.wikipedia.org/wiki/DNS
[24] iptables: https://linux.die.net/man/8/iptables
[25] Toxiproxy: https://github.com/shopify/toxiproxy
[26] инженерной командой Shopify: https://engineering.shopify.com/
[27] выступления: https://atscaleconference.com/videos/resiliency-testing-with-toxiproxy/
[28] toxics: https://github.com/shopify/toxiproxy#toxics
[29] HTTP API: https://github.com/shopify/toxiproxy#http-api
[30] этой записи в блоге: https://shopifyengineering.myshopify.com/blogs/engineering/building-and-testing-resilient-ruby-on-rails-applications
[31] systemd
: https://en.wikipedia.org/wiki/Systemd
[32] Supervisord
: http://supervisord.org/introduction.html#overview
[33] Amazon Aurora: https://aws.amazon.com/rds/aurora/
[34] специальных запросов с внедрением ошибок: https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Managing.FaultInjectionQueries.html
[35] библиотеку на Python: https://github.com/adhorn/aws-lambda-chaos-injection
[36] лямбда-слой: https://github.com/adhorn/aws-lambda-layer-chaos-injection
[37] AWS Lambda: https://aws.amazon.com/lambda/
[38] AWS SSM Parameter Store: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html
[39] Thundra: https://www.thundra.io/
[40] span listeners: https://docs.thundra.io/docs/python-span-listeners
[41] эта публикация: https://blog.thundra.io/chaos-test-your-lambda-functions-with-thundra
[42] Yan Cui: https://twitter.com/theburningmonk
[43] это замечательное видео: https://www.youtube.com/watch?v=TpoN1wm2bok
[44] Marcia Villalba: https://twitter.com/mavi888uy
[45] отличную статью: https://hackernoon.com/how-can-we-apply-the-principles-of-chaos-engineering-to-aws-lambda-80f87e3237e2
[46] chaos monkey: https://github.com/Netflix/chaosmonkey
[47] gist для stop-random-instance.py: https://gist.github.com/adhorn/dbb0350dcd2cbf6301538a977e3910f6#file-stop-random-instance-py
[48] Chaos Toolkit: https://github.com/chaostoolkit
[49] ChaosIQ,: https://chaosiq.io/
[50] Russ Miles: https://twitter.com/russmiles
[51] Sylvain Hellegouarch: https://twitter.com/lawouach
[52] Marc Perrien: https://twitter.com/mperrien
[53] gist для stop-random-instance-exp.json: https://gist.github.com/adhorn/b13d3a80d0a9deeffb925c1dc7f5204e#file-stop-random-instance-exp-json
[54] ресурсы: https://www.gremlin.com/docs/infrastructure-layer/attacks/#resource-gremlins
[55] состояния: https://www.gremlin.com/docs/infrastructure-layer/attacks/#state-gremlins
[56] сеть: https://www.gremlin.com/docs/infrastructure-layer/attacks/#network-gremlins
[57] запросы: https://www.gremlin.com/docs/application-layer/attacks
[58] этой статье: https://medium.com/better-practices/chaos-d3ef238ec328
[59] блоге проекта: https://www.gremlin.com/blog/
[60] Matthew: https://twitter.com/callmeforni
[61] Kolton: https://twitter.com/KoltonAndrus
[62] Tammy: https://twitter.com/tammybutow
[63] Rich: https://twitter.com/richburroughs
[64] Ana: https://twitter.com/Ana_M_Medina
[65] HML: https://twitter.com/HoReaL
[66] ценообразование: https://www.gremlin.com/pricing/
[67] EC2 Run Command: https://aws.amazon.com/blogs/aws/new-ec2-run-command-remote-instance-management-at-scale/
[68] гибридных окружений: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-managedinstances.html
[69] запись в блоге: https://medium.com/@adhorn/injecting-chaos-to-amazon-ec2-using-amazon-system-manager-ca95ee7878f5
[70] готовые исходники: https://github.com/adhorn/chaos-ssm-documents
[71] Olga Hall: https://twitter.com/ovhall
[72] Medium: https://medium.com/@adhorn/chaos-engineering-part-3-61579e41edd8
[73] Мониторинг и Kubernetes (обзор и видео доклада): https://habr.com/ru/company/flant/blog/412901/
[74] Источник: https://habr.com/ru/post/477994/?utm_source=habrahabr&utm_medium=rss&utm_campaign=477994
Нажмите здесь для печати.