Модульное тестирование производительности в Kubernetes или Как мы выиграли время на чай и здоровый сон для НТ-инженера

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

Всем привет! Меня зовут Сергей Лысов, я занимаюсь тестированием производительности платформы интернета вещей ZIIoT Oil&Gas. Если вы о ней еще не слышали, то велком сюда. А в этой статье я расскажу о том, как мы ускоряли и упрощали ее тестирование через автоматизацию контроля тестов и сборки  отчетов, а также внедрение изолированных тестов. Точнее — с чего мы этот путь начали и куда примерно движемся.

5 главных сложностей тестирования производительности платформы ZIIoT Oil&Gas

Стоить начать с того, что  ZIIoT Oil&Gas — сложное произведение девелоперского искусства, состоящее из более чем 100 микросервисов и объединяющее почти все самые модные ИТ-технологии. Эта особенность делает тестирование производительности платформы непростой задачей. Вот пять основных проблем, от которых мы хотели избавиться полностью или хотя бы частично с помощью автоматизации:

1. Сложный и долгий запуск тестов

Для запуска тестов производительности требуется подготовить стенд, выделить ресурсы нужным сервисам, запустить необходимое количество экземпляров сервисов, настроить платформу для тестирования, собрать контейнер с тестом и задеплоить его в Kubernetes.

2. Ручной контроль выполнения теста 

После запуска теста необходимо контролировать его выполнение: отслеживать ключевые метрики, чтобы вовремя остановить тест, когда системе станет плохо. Можно подумать, что нет ничего криминального в том, что тест будет пинать уже мертвую систему. Однако помимо бесполезной траты ресурсов это еще может вызвать проблемы с системой, переполнение очередей, места для логов и прочие неприятности, для исправления которых потребуются время и нервы инженера нагрузочного тестирования (НТ), а иногда и DevOps’а.

3. Каждый тест требует много вычислительных ресурсов 

В связи с тем, что мы тестируем систему большими компонентами (несколько микросервисов), которые в свою очередь используют другие компоненты, для каждого запуска теста требуется более 100 CPU, а это достаточно много.

4. Ручное формирование отчета 

В тестах обычно задействовано несколько десятков сервисов, большинство — в нескольких экземплярах. Таким образом, даже тест небольшого компонента потребует фиксации нескольких сотен метрик, а также конфигурации по ресурсам и версиям используемых компонентов. Собрать руками пару-тройку сотен графиков и оформить все это в отчет — работа для очень терпеливого инженера, и на нее требуется безумное количество времени. 

5. Позднее обнаружение багов и невозможность тестировать каждую сборку 

На данный момент мы тестируем только стабильные сборки платформы. То есть, отлаживаем и актуализируем тесты, когда выходит RC-версия, зачастую отлавливаем какие-то ошибки на этом этапе и далее прогоняем тесты на стабильной сборке. При таком подходе иногда бывает недостаточно времени на исправление обнаруженных дефектов производительности.

 В первую очередь нам захотелось избавиться от проблем под номерами 2 и 4, так как они отнимали наибольшее количество времени, и мы автоматизировали контроль выполнения теста и формирование отчетов. 

Автоматизация контроля выполнения теста и формирования отчета

Автоматизацией контроля выполнения теста мы хотели добиться того, чтобы тест автоматически останавливался, когда какая то из метрик не удовлетворяет требованиям. К решению этой задачи мы подошли следующим образом:

  • Для начала мы реализовали запуск теста через пайплайн в GitLab CI. Он собирает контейнер с тестом, деплоит его в Kubernetes как Job, но на этом свою работу не заканчивает. 

  • Далее простенький shell-скрипт периодически ходит в Kubernetes  и проверяет, на месте ли pod (на случай, если он упал или его остановили руками). 

  • Этот же скрипт ходит и в систему мониторинга (в нашем случае это VictoriaMetrics) и смотрит ключевые метрики по тестируемому компоненту. Для каждого компонента набор метрик индивидуален. Обычно это 2-3 метрики. Например, это может быть лаг очереди в Kafka, количество ошибок или время отклика. 

  • По каждому из критериев устанавливается пороговое значение, выходя за которое тест останавливается удалением Job в Kubernetes.

    Автоматизация контроля выполнения теста
    Автоматизация контроля выполнения теста

    Для автоматического формирования отчета мы завели отдельный репозиторий со скриптами на Python. Работает это следующим образом:

  • Тот самый пайплайн из предыдущего пункта, когда решает что тест закончен, после остановки теста вызывает вебхук пайплайна автоотчетов и передает ему несколько параметров: временные метки начала и конца теста, название тестируемого компонента и название сценария тестирования. 

  • Затем пайплайн автоотчета идет в Kubernetes и собирает информацию о конфигурации и названия pod’ов, которые относятся к выполняемому тесту. Информация собирается в соответствии с заранее разработанными шаблонами под каждый тестируемый компонент.

  • После этого пайплайн автоотчета идет в Grafana и рендерит нужные графики. Графиков очень много: метрики производительности, метрики серверов, метрики по каждому pod’у. Обычно в отчетах 100-200 графиков. 

  • Завершающий этап — отчет публикуется в Confluence (для публикации использовали библиотеку atlassian-python-api), и мы получаем сообщение в Telegram со ссылкой на него. 

    Автоматическое формирование отчета
    Автоматическое формирование отчета

Изолированные тесты

После того как мы поместили сборку и запуск теста в пайплайн, жить стало немного легче: не требуется контролировать выполнение теста, можно спокойно запускать тест на ночь и ложиться спать. Автоматическое формирование отчета тоже экономит уйму времени и позволяет проводить больше тестов. Очень полезным оказалось и оповещение в Telegram: получив уведомление о завершении одного тестирования, можно сразу же запускать следующее. Однако тестировать каждую сборку мы все еще не могли, но очень хотели. Да и запуск тестов по-прежнему съедал много ресурсов и требовал участия инженера НТ, а этого мы очень не хотели. Поэтому мы придумали внедрить изолированные тесты. Их суть в трех буллитах:

  • Берется один компонент с минимальным окружением. Например, это может быть сервис в отдельном неймспейсе и необходимая для его работы инфраструктура (база данных, очереди и т. п.). Если сервис в своей работе обращается к другим сервисам, заменяем их на заглушки.

  • Запускается короткий тест с небольшим набором кейсов. Можно использовать и много кейсов, но чем больше их будет, тем сложнее потом сравнивать результаты.

  • Автоматически формируется отчет по аналогии с тем, что описано выше, но в меньших масштабах.  

Изолированный тест
Изолированный тест

Кратко опишу, как это работает:

  • Весь процесс начинается с пайплайна разработки. При сборке тега он вызывает вебхук пайплайна тестирования и передает ему два параметра: название собранного тега и почту инициатора сборки. 

  • Затем пайплайн тестирования разворачивает стенд. Он в принципе всегда есть, но все его компоненты выключены. Пайплайн их запускает и устанавливает нужную версию тестируемого сервиса, затем запускает тест деплоем Job в  Kubernetes. 

  • После этого запускается уже знакомый вам по предыдущей главе контроль выполнения теста. Отслеживаются pod и ключевые метрики для тестируемого сервиса. 

  • Как только тест заканчивается, дело переходит к пайплайну автоотчета. Он собирает конфигурацию системы, версии, метрики производительности, метрики сервиса и публикует все в Confluence, а после отправляет письмо со ссылкой на отчет на электронную почту инициатору сборки тега. 

  • Через некоторое время пайплайн сворачивает стенд для экономии ресурсов.

В результате мы получили быстрые сравнительные тесты без участия инженера НТ, которые не требуют много ресурсов. Обращу внимание, что тесты именно сравнительные — их результаты нельзя рассматривать как оценку производительности системы. Но они позволяют сравнивать одну версию с другой, чтобы оперативно понять влияние внесенных доработок на производительность.

Что предстоит сделать

В данной реализации нам сразу стало не хватать автоматического сравнения результатов. Сейчас требуется открыть два отчета и проанализировать их самостоятельно, чтобы сравнить одну версию с другой. В идеале хотелось бы наблюдать динамику от версии к версии на графике, а уже за подробностями переходить к отчетам. Пока мы не придумали, как это сделать, но обязательно придумаем. Еще было бы классно реализовать автоматическую проверку на соответствие требованиям, чтобы моментально получать результат — можно это релизить или нет.

На этом у меня все. Если есть замечания, предложения или желание поделиться своим решением аналогичной задачи, то добро пожаловать в комментарии.

Источник: https://habr.com/ru/companies/zyfra/articles/757890/


Интересные статьи

Интересные статьи

Экосистема Kubernetes очень динамична и включает в себя различные компоненты, взаимодействующие между собой. Управление хранением данных в Kubernetes является отдельной задачей, в рамках которой вводя...
Fix by MacRebisz Привет, я Андрей Квапил, Solution Architect в компании «Флант». Моя специализация — архитектурные решения на базе Kubernetes, в том числе на bare metal, а также разработка и эксп...
Если разработчик веб-сервиса хочет дать максимум удобств и пользы клиентам, ему нужно создать общедоступный API для программной работы с этим сервисом. В экосистеме Java есть один подход ...
В мире природы полно созданий, отличающихся своим необычным методом передвижения, внешним видом, гастрономическими предпочтениями, поведением и т.д. Конечно, для них самих ничего необ...
От переводчика: Как вы можете знать, мы занимаемся разработкой open source фреймворка и средств разработки. Неотъемлемой частью процесса разработки приложений является развертывание, и ...