На связи команда перфоманс-тестинга. Нам важно развитие профессиональных стандартов и профессионального комьюнити. В конце октября мы провели митап на тему нагрузочного тестирования. В статье расскажем про доклады спикеров и дадим ссылки на все материалы.
На митапе обсудили, как автоматизировать запуски тестирования производительности в Kubernetes с помощью GitLab CI и объяснили, почему нельзя просто взять и нагрузить Kubernetes. Затронули применение деструктивных тестов в рамках нагрузочного тестирования и разобрали деструктивное тестирование на примере одной из систем. В конце встречи провели круглый стол на тему «Тренды нагрузочного тестирования в 2023 году».
Автоматизация запуска тестирования производительности в Kubernetes
Сергей Данилов рассказал о предпосылках внедрения Kubernetes и нагрузочного тестирования в нем, разобрал путь от идеи до решения и проблем, с которыми столкнулись. А еще рассказал, как реализовали процесс в Gitlab CI в нашей команде.
Предпосылки внедрения:
Сложности доставки аппаратных ресурсов в короткий срок и их оптимизация.
Решение вопросов масштабирования.
Унификация запуска нагрузочного тестирования после внедрения k8s. Можно использовать те же ресурсы и бонусы, что и ваше приложение от размещения в нем.
Все объекты k8s задаются с помощью конфигурационных файлов, которые описывают структуру сущности объектов:
Pod — минимальный абстрактный объект k8s, содержит в себе один или несколько контейнеров.
Service объединяет поды в группу и определяет доступ к ним.
Ingress описывает правила проксирования трафика от внешнего пользователя до сервисов внутри k8s.
Чтобы протестировать нагрузку на сервис, нужно вместо клиента подставить какой-то инструмент, например Gatling. Потом сгенерировать пользовательский трафик, отправить его на Ingress. Если все работает — данные уходят в сервис, поды реагируют.
Выше описан пример простого тестового приложения, но если возьмем продовую среду — там все намного сложнее.
Чтобы избежать полной недоступности, мы решили отправлять трафик в обход Ingress, нагружать напрямую Service и запускать тесты внутри namespase.
Еще несколько полезных абстракций:
Deployment — описывает работающее приложение, манифест похож на предыдущие абстракции, но в нем описывается количество реплик.
Job — предназначен для выполнения разовых задач, например миграций или бэкапов.
ConfigMap — ресурс для хранения и внедрения конфигурации в контейнеры, можно передавать как Key value, так и списком параметры из файла.
Проблемы, с которыми столкнулись при внедрении.
Проблема: сборка docker image — один docker image не подходит для более чем 150 проектов. Проекты и скрипты могут изменяться, и неясно, как это поддерживать.
Решение: собрать проект внутри docker image. Пакуем туда Gatling и различные утилиты, а сами скрипты нагрузочного тестирования копируем на этапе выполнения нагрузочного контейнера.
Проблема: как деплоить и что выбрать в качестве сущности деплоя — deployment или job. Кроме того, могут существовать дополнительные требования по поводу деплоймента: например, создавать deployment минимум с двумя подами, и тогда появляется проблема для анализа результатов.
Решение: попробовали использовать deployment, но необходимо дополнительно удалять созданные артефакты. Job выполняет задачу один раз и удаляет артефакты сам.
Проблема: как разделить различные окружения — запуск нагрузочного тестирования в dev- и prod-окружениях. Создавать отдельные docker image и манифесты под каждый стенд слишком затратно.
Решение: использовать Kustomize — инструмент для настройки объектов Kubernetes с помощью конфигурационных файлов, разложенных по слоям. Еще используем утилиту SED — редактор для преобразования текстовых данных, чтобы автоматически подставлять нужные нам параметры.
Проблема: как передавать параметры из Gitlab CI в k8s, потому что иначе эти параметры не знают о существовании друг друга.
Решение: создать скриптом ConfigMap и добавить его в манифест.
Проблема: логи Gatling. Когда мы запускаем нагрузку, в Gatling пишется очень много логов. Корневой раздел внутри docker-контейнера в нашей инсталляции k8s только read-only, потому что, если записывать в корень данные неконтролируемо, можно получить переполнение дискового пространства на хосте.
Решение: использовать Volume emptyDir. Отличие emptyDir в том, что он живет, пока живет под, который его использует. Еще переопределили параметры запуска sbt: если параметры не определить, то запись будет идти в домашнюю директорию.
Реализация в Gitlab CI по упрощенной схеме выглядит так:
Подробнее про Cosmos от Иоанна Ахальцева:
В планах — сделать следующие шаги автоматическими:
Запуск тестового стенда для нагрузочного тестирования в k8s.
Проведение нагрузочного тестирования.
Сохранение результатов.
Удаление тестового стенда.
Так экономится значительное количество ресурсов, потому что нам не нужно держать отдельную нагрузочную станцию для Gatling и сам стенд будет запускаться только при необходимости.
Kubernetes оказался не таким сложным, как может показаться на первый взгляд. Все проблемы решаются, если не забывать об ограничениях.
Почитать про Gatling можно в подборке статей на Хабре:
Деструктивное тестирование в рамках тестирования производительности
Руслан Гимазиев, старший инженер по нагрузочному тестированию в Performance Lab, рассказал о деструктивном тестировании, что оно собой представляет, чем отличается от нагрузочного и какие трудности бывают в деструктивном тестировании.
Деструктивный тест — это проверка системы в различных разрушительных условиях. Такие тесты помогают понять поведение системы в разных состояниях инфраструктуры, предоставить дополнительную информацию о проблемах и разработать рекомендации по полученным данным. А еще деструктивные тесты могут уменьшить время простоя системы и сохранить деньги бизнесу.
Главное отличие деструктивного тестирования от нагрузочного — условия, в которых проводится тестирование. Задача деструктивного тестирования — ухудшить условия работы системы так, как это может случиться в реальной жизни, и посмотреть, что произойдет.
Пример деструктивного тестирования системы N
Описание: банковский продукт, который принимает финансовые сообщения клиентов и обрабатывает их в определенном формате для передачи в ЦБ и другие организации. Клиент может быть как внутренний, так и внешний.
Чтобы провести деструктивное нагрузочное тестирование, мы разработали:
50 скриптов для эмуляции работы сервисов;
2 эмулятора Wiremock — 156 API-эмуляторов и IBM MQ client. Реализовали два разных ответа для разных счетов клиентов и один объемный ответ;
3 развернутые сервисные внешние системы — Kafka, IBM MQ и Logstash;
3 системы мониторинга для двух БД — Telegraf, Oracle Enterprise Manager и Lab128;
5 сценариев для наполнения БД и три сценария для проведения тестов.
Мы разделили все варианты тестов на три группы по сложности, важности и применимости к системе. Выбрали самые важные и получили такой список тестов:
С разными значениями latency от клиента.
С медленными ответами внешних систем.
3. С различной шириной канала передачи входящих и исходящих пакетов от клиента:
Проведенные тесты показали, что скорость для нормальной работы нашего приложения должна быть не менее 512 Кбит/с, задержка latency до 1000 мс и время ожидания клиента не меньше 120 секунд.
Деструктивное тестирование помогает подложить подушку безопасности и понять, в правильном ли месте она установлена.
Вместо заключения
После выступления спикеров провели круглый стол про тренды нагрузочного тестирования в 2023 году. Борис Селезнев, Вячеслав Смирнов и Иоанн Ахальцев обсудили, как выглядят процессы нагрузочного тестирования со стороны бизнеса и команд, которые этим занимаются. Поговорили о том, как бизнес хочет видеть команду тестирования, и ответили на вопросы в чате.
Послушать выступление целиком или скачать презентации спикеров можно на странице мероприятия.
Мы в Тинькофф не только активно применяем, но и много разрабатываем различные инструменты по тестированию производительности. Также мы развиваем наше комьюнити, обмениваемся кейсами и экспертизой, проводим профессиональные встречи и ведем чатик по QA в нашем Телеграме. Чувствуйте себя свободно и не бойтесь задавать вопросы в комментариях.