Предыстория
Год назад мы с другом начали работу над нашим совместным бакалаврским дипломом. Его суть заключалась в том, чтобы проанализировать Prometheus метрики, собранные из любой IT системы, и попробовать определить, в какие моменты система испытывала сбои, а в идеале еще и угадать, в чем заключались их причины.
Практически сразу возник вопрос: "А где взять датасет?". Без долгих раздумий было принято решение собрать его самостоятельно и по ходу развернуть свою песочницу, напоминающую продакшен окружение: со своими пользователями и периодическими сбоями.
Как всё это было организовано - расскажу в этой статье.
Декомпозиция
Чтобы задача по развертыванию окружения и сбору данных выглядела хотя бы выполнимо, я сразу же разделил ее на несколько подзадач:
Выбрать приложение для развертывания;
Развернуть приложение и всю инфраструктуру для него;
Настроить сбор метрик как из самого приложения, так и из инфраструктурных компонентов;
Симулировать пользовательскую активность;
Устроить сбои.
Теперь давайте пройдемся по пунктам и посмотрим на конечный результат.
Выбор приложения
Основным требованиями для приложения были:
Возможность экспорта метрик в Prometheus формате;
Наличие какого-нибудь бэкенда и фронтенда, чтобы с приложением можно было взаимодействовать;
Хотя бы 100 звезд на GitHub;
Бесплатность....
Казалось, что приложений таких сотни и тысячи, но на деле пришлось потратить вечер, чтобы по ходу поиска узнавать, что где-то экспорт метрик предусмотрен только в платной версии, где-то приложение просто не поднимается, а где-то приложение слишком тяжеловесное, чтобы уместиться на нашей виртуалке.
По итогу выбор пал на Pretix - open-source платформа для продажи билетов на концерты, выставки и прочие мероприятия.

Развертывание инфраструктуры и сбор метрик
На одной виртуалке мы развернули приложение с его базой данных. Благо, разработчики самого проекта Pretix заботливо поместили docker compose файл в репозиторий проекта, что позволило поднять все одной командой.
Также мы запустили экспортеры метрик из VM и БД. Помимо этого, на отдельной VM расположился наш мониторинг стек в составе Grafana и Prometheus. А еще отдельные виртуалки на будущее были отведены под клиента (то есть скрипт, симулирующий клиента) и скрипты для создания сбоев. Результат можно увидеть на картинке ниже:

По итогу у нас была система, готовая принимать пользовательские запросы.
Симуляция нагрузки
Имитация пользователя
Чтобы создать нашего пользователя, я использовал Selenium - любимую всеми технологию для автоматического тестирования фронта (создания скейперов). Проще говоря, это библиотека, которая позволяет через скрипт открыть браузер и потыкать там кнопки, тем самым симулируя взаимодействия пользователя с UI.
Вооружившись питоном, я написал несколько пользовательских сценариев, в которых скрипт, изображающий человека, регестрировался на сайте, создавал события, покупал билеты и в целом производил действия типичные для платформы по продаже билетов. Таким образом мы и симулировали активность на сайте.
Создание паттерна
Должен признаться, что при взгляде на дашборды различных компаний в Grafana в разрезе нескольких дней, на ум всегда приходила идея, что множество графиков напоминают синусоиду. Никаких подтверждений своим догадкам, кроме поста в Reddit, я не нашел. Тем не менее идею воспроизвести синусоидальный паттерн пользовательского поведения я не оставил.
Для этого я написал функцию, которая генерировала вероятность запуска сценариев в зависимости от текущего времени. Таким образом с какой-то вероятностью в каждую секунду могло запускаться от нуля до восьми сценариев, которые после этого в среднем были активны еще 30 секунд.
Ниже можно увидеть график, отображающий количество активных сценариев в каждую секунду на протяжении трех часов:

Таким образом на нашем сайте будто бы было сразу несколько пользователей, чья активность зависела от времени суток, сжатых в нашем случае до одного часа.
Создание сбоев
На этом этапе мне нужно было придумать 10+ вариантов неполадок системы, после чего автоматизировать их запуск. Тут к месту пришелся опыт хаос инжиниринга.
Для того, чтобы устраивать самому себе сбои было решено использовать Python и Ansible. Ansible отлично подходил для того, чтобы подключаться на VM и что-нибудь ломать изнутри, а Python прекрасно справлялся с задачами атак "снаружи". С помощью двух этих технологий мне удалось симулировать следующие сбои:
tcp и http flood;
Создание задержек между приложением и его БД;
Выедание всех свободных подключений к базе;
Запуск стресс-тестов оперативной памяти на vm;
Создание гигантских файлов на файловой системе VM;
И так далее.
Но после реализации всех неполадок, внутренний голос SRE все еще требовал побольше автоматизаций, поэтому мне пришлось дописать CLI на Go, который примерно раз в 2 часа в случайном порядке запускать неполадки, а затем запрашивать из Grafana API картинку, на которой можно было увидеть влияние нашей нашего рукотворного сбоя.
Например, ниже можно увидеть, как наш tcp flooding привел к увеличению объема сетевого трафика на VM:

Итоги
В конечном итоге сбор датасета для последующего анализа стал одной из основных задач нашей дипломной работы. Написание всех скриптов, настройка окружения и непрекращающийся траблшутинг занял у нас почти полгода, но результат того точно стоил: в итоге на руках была система с безграничным потенциалом для опытов и экспериментов.
inkmaster
А есть ли возможность ознакомиться с кодом инфры и сценариев сбоев/атак? Проект интересный