От печали до радости или от идеи до реализации

Как-то очень давно наш отдел автоматизации внутренних процессов посетил админ (ops) с идеей помочь нашим тестировщикам. Он предложил упростить деплой, т.к. было очень неудобно писать ручные curl запросы к gitlab'у с кучей меняющихся параметров. Так заставили нас наша команда решила помочь дружественному отделу и сделать их работу более приятной.

В статье я постараюсь поделиться тем, как мы в Каруне разрабатывали GUI для curl'a, а сделали очень крутой сервис автоматизации. Ещё расскажу, с какими проблемами столкнулись и как их решили (или нет).

А почему не взяли готовые решения? (с)

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

Реализация

В то время основной проект был монолитом с одним отпиленным сервисом "сбоку". Но, к счастью, был развернут kubernetes, который значительно упростил работу с сервисами. Реализация предполагала простейшую идею: дёргаем настроенный админами триггер гитлаба, передавая названия нужных веток к двум репозиториям.

Но тут понеслась...

Естественно процесс на этом не остановился, больше людей проявляло интерес к нашему сервису: QA, админы, программисты всех видов и подвидов. С каждым днём мы получали все больше хотелок. Мы улучшали интерфейс сервиса.

Начало образовываться все больше внешних интеграций. Например, QA нужны были логи, чтобы понимать, кто удалил или создал очередной стэк (стэком мы называем развёрнутый набор сервисов), кого ругать и кого за него спрашивать. Для этого мы подключили API Kubernetes.

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

Для связи с развёрнутыми контейнерами к каждому сервису мы подключили консоль, которая тянулась через kubernetes websocket.

Также необходимо было подключить ssl. Сертификаты стали генерироваться через vault, а далее отправлялись на балансеры и cloudflare.

Матрица зависимостей

Наверное, это представляется очень пафосно, как-то так:

Но на деле с основе лежала простая идея. Параллельно нашему сервису основной проект также стремительно развивался. Монолит постепенно переходил на SOA, образовывались новые микросервисы. Каждый деплой запускал неконтролируемо огромное количество ненужных сервисов, которые были лишними в разворачиваемом стэке. Необходимо было более умное использование ресурсов. Для этого мы создали так называемую "матрицу зависимостей", позволяющую настроить, какие сервисы от каких "зависят". Пользователь смог сам задавать "наборы сервисов". Выбрав при деплое, что ему нужно, он получал действительно только то, что ему нужно.

Например, деплой сервиса статистики разворачивал только необходимый сервис статистики и авторизацию, а не весь монолит с сервисами.

Интерфейс нашей шайтан-машины с заполненными фейк-данными представлен ниже.

Упомяну также об ограничении на количество задеплоенного. Все-таки мощности ограничены, и необходимо было ввести лимит на количество стейджей. Т.к. в стейдже может быть разное количество сервисов (и соответственно контейнеров), то ограничение вводилось как раз на количество контейнеров.

Веб-сокеты

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

Как я уже описал выше, в одном из проектов Каруны осуществлялся переход от монолита к микросервисной архитектуре. Это заставляло использовать все больше и больше репозиториев gitlab'a. Последовательная обработка запросов к гитлабу сильно тормозила разворачивание сервисов. Пользователь очень долго ждал своего стейджа. Т.к. основное взаимодействие с гитлабом осуществлялось через веб-сокет сервер, мы решили внедрить golang. Это позволило распараллелить эти запросы и значительно увеличить скорость создания нового стейджа.

Как. Это. Тестировать.

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

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

Что мы имеем?

После около 3 лет использования продукт развился от "дёргателя апишки" до полноценного инструмента для разворачивания тестового окружения с множеством настроек, удобств, а также пасхалок. Сейчас им пользуются около 100 человек технического отдела. Невозможно переоценить вклад этого сервиса в автоматизацию процессов  в одном из самых нагруженных проектов — он очень велик.

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