Привет, меня зовут Лёша, я работаю в SEMrush в команде SRE, которая занимается обеспечением бесперебойной работы нашего сервиса. Эта история о том, как мы разогнали деплой в 6 раз и сократили затраты на мониторинг в 3 раза. И все это через приручение канареек и самописные инструменты.

Я расскажу, как мы улучшали релизный пайплайн с помощью канареечного деплоя. Так, за пару лет мы прошли путь от «надо бы попробовать» до самописного тулинга.

image

TL;DR


  • Если вы пока не пользуетесь канареечным деплоем, очень рекомендую! Это правильная идея, не очень сложная в реализации.
  • Система мониторинга — хороший кандидат, чтобы стать первой канарейкой.
  • Чтобы мониторинг делал всё, что нам нужно для канареечных целей, мы сделали свой тулинг. Он доступен как Open Source, ссылка есть в конце статьи.
  • Части этой истории я рассказывал на Heisenbug 2019 Piter и DevOops 2019 Piter.

Надо бы попробовать


До описываемой тут истории наш деплой был устроен вот так:

image

наш релизный пайплайн до внедрения канареечного деплоя

Есть ветка, в которой ведётся разработка новой фичи. В какой-то момент разработчик решает, что код готов к доставке пользователю. Тогда код заливается на тестовый стенд, прогоняются автоматические тесты, QA и PO делают ревью. Если всё ОК, происходит автоматическая раскатка по продакшн-окружению. Классика.

Вопрос, который мы постоянно задаём себе в команде SRE: «Насколько этот процесс быстрый и надежный?» Также было несколько моментов, которые мы хотели улучшить.

Хотим улучшить: удобство деплоя


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

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

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

Хотим улучшить: покрытие тестами


Структурно тестовое окружение такое же, как продакшен, но отличия есть:

  • другое железо
  • другая сеть
  • другая база данных
  • другие конфиги

Есть отличия во внутренних и внешних интеграциях. Мы используем разные платёжные системы, отправку почты, поставщиков данных и так далее. Сторонних сервисов много, но не везде есть песочницы. Мы хотели снизить число post-deploy инцидентов, которые случались из-за различий тестового окружения и продакшена.

Зовём на помощь канарейку


Чтобы побороть эти проблемы, мы решили добавить в пул продакшн-серверов ещё одну ноду. План был такой: будем выкатывать туда бета-сборку с новой фичей и заводить туда часть пользователей, чтобы посмотреть, что всё работает корректно. Так у нас появилась канарейка
image

концепция канареечного деплоя

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

По задумке канареечный деплой должен был принести с собой важное улучшение: принятие решения о раскатке фичи по продакшену на основе предварительно собранных метрик.
image
по задумке канареечный пайплайн должен был стать таким

Проводим кастинг на канарейку


Ок, пробуем настроить канареечный деплой. Самый первый вопрос: на ком будем экспериментировать и собирать заветные метрики. Тут навскидку было три варианта.

Первый вариант (решение в лоб) — направить на новую ноду часть реальных пользователей. Не подошло по нескольким причинам. Во-первых, фидбек от пользователей может быть довольно медленным. Нужно будет каждый раз ждать, пока соберётся статистика в достаточном объёме. Во-вторых, у нас в системе есть важные сценарии, которые случаются не так часто. Придётся ждать их появления, чтобы проверить. В-третьих, нам не хотелось портить user experience даже маленькой части пользователей. Отбрасываем вариант.

Второй вариант (отвергнутый) — задействовать наши тесты. Их у нас много. Но тоже не подходит. На продакшн-данных тестировать сложно. К тому же нужно постоянно следить, чтобы в тесты для продакшена не затесались проверки, которые нельзя там запускать. Отбрасываем вариант.

Третий вариант (рабочий) — система мониторинга продакшн-сервисов. Она работает в продакшн-окружении. Всегда актуальна и даёт сигналы, когда что-то сломалось. К ней высокое доверие: дежурные администраторы по сигналу системы мониторинга начинают чинить проблему даже ночью. Берём этот вариант.

Может получиться быстро и надёжно, идём проверять.

Proof of Concept


В качестве системы мониторинга на роль канарейки мы взяли Pingdom, которым тогда пользовались. Сработало! Канареечная концепция реализуется, ничего не ломается. Но вопросы остались.

  • Стало быстрее, но всё равно долго. Браузерные проверки у Pingdom запускаются раз в 5 минут. Если хотим посмотреть два результата подряд, получаем 10 минут. Хотелось быстрее.
  • Дополнительные расходы. Теперь нам приходилось платить за проверки, которые проверяют еще и канареечное окружение.
  • Неудобный дебаг. Pingdom — всё-таки не deploy, а monitoring tool. Плохо встраивался в наш GitLab CI.

Главная проблема — разные инструменты тестирования и мониторинга для продакшена, тестового и канареечного окружения.

Канарейка VS тесты VS мониторинг


С приходом канарейки наш деплойный пайплайн стал выглядеть так:
image

релизный пайплайн после внедрения канареечного деплоя

Для каждого окружения мы имели свой набор инструментов. Каждый нужно поддерживать, при этом все они работают по-разному. Неудобно по нескольким причинам.
Случалась проблема «ненастоящего» браузера. Pingdom использует эмуляции, которые могут отличаться от реального браузера.

image

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

Ещё была проблема с рассинхроном тестов и мониторинга. В команде SRE мы в первую очередь доверяем мониторингу. Ребята из QA ориентируются на тесты. Получается следующее: соответствующие инструменты в каждом окружении работают по-разному и непонятно, за кем последнее слово.

А ещё было тяжело дебажить упавшие тесты. Pingdom – внешний инструмент. Оттуда можно достать ограниченную информацию об инцидентах. Этого не всегда хватало, чтобы разобраться в проблеме. На запросы разработчиков часто приходилось разводить руками.

Чтобы победить эти проблемы, мы решили сделать свой инструмент.

Introducing SEMrush PURR


Нам нужен реальный браузер, единые сценарии тестов и мониторинга, удобный дебаг. Для интеграции с нашим GitLab CI мы хотели иметь возможность запуска из CLI. И, раз такое дело, заодно и возможность запуска по расписанию. Такими были требования к новому инструменту.

Решение: мы взяли Puppeteer, сделали обвязку из NodeJS, добавили Redis для очередей. Инструмент назвали SEMrush PURR (от Puppeteer Runner).

Puppeteer – инструмент от Google; делает та же команда, что Chrome. Это реализация DevTools Protocol для той консоли Chrome, которой мы пользуемся каждый день. На тот момент поддерживались Chrome, Firefox (beta), Edge (alpha).

Puppeteer помог нам решить проблему «ненастоящего» браузера. Запуск из CLI дал возможность встроить запуск SEMrush PURR в пайплайн GitLab CI.

image

запуск SEMrush PURR – финальный шаг пайплайна; если PURR падает, выкладки не происходит

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

image
дебажим упавшие тесты


image
Единые сценарии тестов и мониторинга стали описываться в YAML-файле.

image
YAML-файл со сценариями тестов и мониторинга

Там можно указывать разные параметры (например, домен, который мы тестируем). Тут на скриншоте указано, что работаем с куками и авторизацией.

Для работы по расписанию запускаем наше NodeJS-приложение в Kubernetes. Настраиваем расписание проверки с помощью Redis (библиотека Bull). Результаты проверок отгружаем в Prometheus. Оттуда забираем алерты, если что-то упало.

Варианты запуска по расписанию не ограничиваются только этим стеком. Можно использовать хоть cron, хоть Google Cloud Functions, хоть AWS Lambda. Или захостить у себя на виртуалке.

Унификация пайплайна с SEMrush PURR


В итоге SEMrush PURR дал нам заветное: один и тот же инструмент и сценарии для всех трёх окружений.
image
релизный пайплайн после внедрения SEMrush PURR

Главный результат внедрения SEMrush PURR – сократилось количество post-deploy инцидентов, когда на продакшене оказался код с ошибками.

С канарейкой, но без ограничений Pingdom, время доставки фичи на продакшен снизилось с 60 до 10 минут. Не нужно ждать, пока освободится тестовый стенд; не нужно ходить в другие команды узнавать, что с их тестами.

Мы стали тратить меньше денег на мониторинг. Один миллион транзакций в Pingdom стоил для нас $625. С SEMrush PURR сумма уменьшилась до $225.

Отдельный позитивный момент работы с SEMrush PURR для нас лично то, что конфигурацией проверок занимается наша команда. Так что мы имеем возможность делать частью проверок те вещи, которые важны для продакшн-системы, на наш взгляд.

Дружите с канарейками


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

Если вы уже пользуетесь канареечным деплоем (или вот-вот начнёте), обратите внимание на Puppeteer. Он помог нам получить окружение для мониторинга, близкое к настоящему браузеру пользователя.

Если будете подбирать тулинг, посмотрите на SEMrush PURR. Он доступен на GitHub. Будем рады, если наш инструмент поможет вам сделать канареечный деплой удобнее.