DevOps и CI/CD
Смысл CI/CD состоит в безопасном откате, а не в скорости. Анатомия конвейера, среды и секреты, контейнеры, наблюдаемость и письменная передача.
Ценность конвейера выкладки измеряется не тем, как быстро вы попадаете в продакшен, а тем, за сколько минут вы возвращаетесь обратно, когда туда уходит неудачная версия. Конвейер, который нельзя развернуть назад, не является автоматизацией: он представляет собой механизм, разносящий ошибку быстрее. Поэтому первым шагом в каждом нашем конвейере записывается не выкладка, а откат: какой командой, чьими правами и как вернуться к предыдущей версии, не трогая миграции базы данных. Команда, у которой нет письменного ответа на этот вопрос, вместе с частотой релизов накапливает и риск. Разделы ниже разбирают части конвейера, управление средами и секретами, контейнеры, наблюдаемость и эксплуатацию после передачи.
Смысл CI/CD состоит в безопасном откате, а не в скорости
CI/CD, то есть непрерывная интеграция и непрерывная доставка, описывает систему, которая автоматически тестирует изменения кода и выкладывает их в продакшен; но эта автоматизация не снижает долю ошибок, она лишь меняет их цену, потому что та же ошибка случается и в системе, которую выкладывают руками, а разница в том, что можно сделать после. Оценивая конвейер, мы задаём три вопроса: возвращается ли версия приложения к предыдущему образу одной командой, написано ли изменение базы данных так, чтобы его можно было отменить, и можно ли на каналах без отката, таких как мобильные магазины, выключить функцию флагом. Ответы на эти три вопроса не совпадают. Версия приложения возвращается за минуты. Миграция, удаляющая колонку, не возвращается, поэтому схему сначала расширяют, а сужают отдельным более поздним шагом. Мобильная сборка, опубликованная в магазине, не откатывается вовсе и выходит под выключателем. Проект Lextum AI показывает тот же принцип на стороне продукта: все изменения документов на платформе записываются так, что их можно проследить и отменить, и видно, кто, когда и что изменил. От инфраструктуры мы ждём ровно того же.
Из каких частей состоит конвейер выкладки
Шесть заголовков ниже охватывают все решения, которые принимаются при построении конвейера выкладки. Первые три описывают сам конвейер: шаги от сборки до развёртывания, способ разделения сред и формат пакета, в котором едет приложение. Следующие два относятся к тому, что окружает конвейер: слой измерений, показывающий, что произошло после релиза, и права доступа. Шестой заголовок является местом проверки остальных пяти, потому что описывает действия в момент отказа.
Анатомия конвейера: сборка, тесты, образ, развёртывание
Конвейер выкладки состоит из четырёх шагов, и каждый шаг обладает правом остановить остальные. Сборка доказывает, что код поднимается в общей среде, а не на ноутбуке одного разработчика. Если шаг тестов красный, движение прекращается: тест, который можно пропустить, не является тестом. Шаг образа превращает результат в один версионированный пакет, благодаря чему протестированное и выложенное оказываются одним и тем же артефактом. Шаг развёртывания переносит этот пакет в целевую среду. Такое разделение служит опорой всего подхода: как только пакет отделён от среды, один и тот же образ последовательно проходит тестовую, предпродуктивную и продуктивную среды, и пересборка под каждую среду больше не нужна.
Управление средами и конфигурацией
Разница между средами должна жить в конфигурации, а не в коде. Приложение читает из переменных окружения, к какой базе подключаться, какой адрес сервиса вызывать и какая функция включена. Ветвление внутри кода по имени среды означает путь, который впервые исполнится в продакшене. Мы поднимаем как минимум две среды: предпродуктивную, совпадающую с продуктивной по схеме и миграциям, и саму продуктивную. Предпродуктивная отличается только данными и масштабом. Конфигурация версионируется так же, как код, потому что причиной инцидента чаще оказывается незаписанное изменение настройки, а не изменение кода.
Контейнеры и оркестрация
Контейнеры существуют, чтобы убрать фразу «у меня работало». Приложение, среда исполнения и зависимости соединяются в один образ, и этот образ одинаково открывается и на ноутбуке разработчика, и на продуктивном сервере. Оркестрация является отдельным решением и нужна не каждому проекту. Приложению из одного сервиса с предсказуемым трафиком Kubernetes приносит больше эксплуатационной нагрузки, чем выгоды. Обоснование появляется тогда, когда несколько сервисов масштабируются независимо, когда развёртывание должно проходить без простоя и когда ожидается автоматическое восстановление. Если источником проблемы служит не конвейер, а нагрузка, работа переходит в Масштабирование бэкенда, где обсуждают архитектуру, доступ к данным и кеширование.
Наблюдаемость: логи, метрики, оповещения
Фраза «вроде работает» не является измерением после релиза. Мы поднимаем три слоя: структурированные логи, метрики ошибок и задержек, а также оповещения, которые при превышении порога действительно доходят до человека. Если оповещение не доходит ни до кого, дашборд остаётся украшением. К этому же слою относится отметка каждой версии в тех же данных. Когда доля ошибок растёт, первый вопрос звучит так: после какой версии это началось. Если ответа нет на графике, поиски растягиваются на часы. Порогов мы держим немного и ставим их там, где требуется действие, потому что постоянно звенящее оповещение рано или поздно отключают.
Управление секретами и доступом
Ключ, однажды попавший в репозиторий, остаётся в истории даже после удаления строки, поэтому единственным верным действием служит его отзыв и выпуск нового. Пароли базы, ключи платёжного провайдера и облачные учётные данные хранятся не в репозитории кода, а в хранилище секретов, которое читает конвейер, и разделяются по средам: ключ предпродуктивной среды не должен доставать до продуктивных данных. Право выкладки в продакшен назначается поимённо и оставляет запись. Цель заключается не в сокращении числа людей, способных выкладывать, а в том, чтобы потом можно было прочитать, кто и когда выложил.
Откат и реакция на инцидент
Откат не является планом, который пишут во время инцидента. Он представляет собой обычный шаг конвейера и отрабатывается также вне инцидентов. Предыдущий образ держат наготове, команда развёртывания принимает параметр версии, а возврат выполняется одним действием. Сторона базы данных рассматривается отдельно: миграции пишутся с прямым и обратным направлением, а шаги, теряющие данные, откладываются в отдельный релиз. В момент инцидента порядок действий фиксирован: сначала откат, потом поиск причины. Обратный порядок обходится дороже всего, потому что диагностика на сломанной системе идёт медленно и под давлением. Короткая запись, сделанная после инцидента, остаётся единственным средством против повторения той же ошибки по той же причине.
Как частота релизов связана с хрупкостью
Частые релизы не делают систему хрупкой, хрупкой её делают крупные релизы. Риск задаётся не количеством выкладок, а размером изменения, которое едет за один раз. Когда ломается релиз, копившийся неделями, никто не знает, какое изменение его сломало, и откат уносит вместе с ним десятки работающих доработок. При маленьких и частых релизах отменяемое изменение очевидно. Предпосылкой здесь служит то, что выкладка перестаёт быть событием: если ради каждого релиза собирается команда, частота недостижима изначально. Особенно заметно это в системах, которым простой недоступен. Проект Anneekspres представляет собой маркетплейс: покупатели оформляют заказы, пока продавцы обновляют остатки, и такой роскоши, как плановое окно обслуживания, там нет. Платформа была построена на очереди сообщений RabbitMQ, управлении данными в PostgreSQL и конвейерах Jenkins, и высокая доступность вместе с быстрым развёртыванием выходят из этой же конструкции.
Преимущества управления инфраструктурой как кодом
Сервер, собранный руками, превращается в недокументированную систему в тот день, когда собравший его человек уходит. Запись инфраструктуры в виде кода переносит ответ на вопрос «что стоит на этом сервере» из человеческой памяти в репозиторий. С помощью таких инструментов, как Terraform, описания сервера, сети, группы безопасности и базы данных получают версии: изменение сначала читают как текст и только потом применяют. Выигрыш заметен в трёх местах. Первое касается повторяемости: поднятие второй среды перестаёт быть недельной работой и сводится к одной команде. Второе касается проверяемости: время и причина изменения настройки остаются в записи. Третье описывает сценарий катастрофы: вопрос «за сколько часов вернётся полностью стёртый сервер» получает измеренный ответ вместо догадки. Подтвердить все три пункта можно единственным способом, а именно построив инфраструктуру с нуля хотя бы один раз.
Передача: как вы эксплуатируете конвейер
Конвейер выкладки принадлежит вам только тогда, когда он работает в ваших учётных записях. Репозиторий, облачный аккаунт, домен и хранилище секретов открываются на ваше имя: мы получаем доступ, но не владение. При передаче письменно отдаются четыре вещи: что конвейер делает по шагам, как новый разработчик доходит от чистой машины до релиза, какой командой выполняется откат и у кого есть право выкладки в каждую среду. К этому добавляется дежурство: какое оповещение к кому уходит и что делается в первые двадцать минут. Одних документов недостаточно, поэтому до передачи мы вместе с вашей командой проводим минимум один настоящий релиз и один настоящий откат. Инженерный подход работы вплотную к системам заказчика мы разобрали в статье о роли Forward Deployed Engineer, и передача продолжает ту же логику.
Наши критерии выбора инструмента
Инструмент выбирается по тому, где уже живёт проект, а не по привычке. Если код лежит на GitHub и содержать отдельную машину-раннер желания нет, GitHub Actions оказывается самым коротким путём. Для конвейеров, которые работают на собственном сервере, длятся долго или содержат нестандартные шаги, Jenkins остаётся разумным выбором: в шести из девяти привязанных к этой услуге проектов автоматизация CI/CD построена на Jenkins, а серверная сторона работает на Ubuntu. У остальных трёх список технологий другой, потому что один и тот же конвейер мы никуда не копируем. Docker убирает разницу между средами и становится выбором по умолчанию, когда решение о контейнеризации принято. Kubernetes и Azure зависят от обоснования: несколько сервисов, независимое масштабирование или корпоративная облачная политика. Место размещения выбираете вы, а не мы: управляемая SaaS-инфраструктура Lextum AI построена на AWS, в других проектах выбор оказался иным.
Как это работало на практике
Перечисленные работы находятся в эксплуатации или завершены. Подробности каждой лежат на отдельной странице в разделе «Истории успеха».
- Lextum AI: микросервисная архитектура с асинхронной обработкой через RabbitMQ, интерфейс на Next.js, сервисы на .NET и управляемая SaaS-инфраструктура на AWS с автоматизацией CI/CD на Jenkins. Структура готова к корпоративному использованию под высокой нагрузкой.
- Anneekspres: инфраструктура маркетплейса на очереди сообщений RabbitMQ, управлении данными в PostgreSQL и конвейерах Jenkins, с высокой доступностью и быстрым развёртыванием.
- Biletico: кеширование на Redis поверх стека Next.js и Node.js, автоматизация CI/CD на конвейерах Jenkins, каждое обновление проходит тесты до выхода в продакшен.
- Welldone: мобильное приложение на Flutter, панель управления на React и сервисы на .NET на масштабируемой серверной инфраструктуре Ubuntu с автоматизацией CI/CD на Jenkins. Вся операция от заказа до отгрузки ведётся на одной платформе.
- World Summer Schools: облачная масштабируемая инфраструктура на стеке Next.js, .NET и PostgreSQL с автоматизацией CI/CD на Jenkins. Инфраструктура готова к росту числа программ и пользователей.
- BiTalih: платформа производства контента на Next.js и MongoDB с инфраструктурой выкладки на Jenkins и Ubuntu.
Преимущества
- Шаг отката, записанный раньше шага выкладки
- В продакшен уходит ровно тот образ, который тестировали
- Конфигурация и секреты разделены по средам
- Логи, метрики и оповещения, требующие действия
- Инфраструктура, записанная кодом и версионированная
- Конвейер в ваших аккаунтах и письменная передача
Часто задаваемые вопросы
Сколько занимает настройка CI/CD и как она оценивается?
Останутся ли конвейер и инфраструктура у нас?
Если работа прервётся на середине, можно ли пользоваться уже сделанным?
Кто эксплуатирует конвейер и кто несёт дежурство?
Нужен ли конвейер CI/CD каждому проекту?
Можно ли поднять это, не трогая работающую систему?
Как мы предоставляем эту услугу
Технологии, которые мы используем
Смотреть всеDocker
Платформа для упаковки приложений в контейнеры, обеспечивающая согласованность между окружениями разработки, тестирования и production.
Kubernetes
Платформа оркестрации контейнеров. Управление корпоративной инфраструктурой с автоматическим масштабированием, self-healing и развертыванием без простоев.
Next.js
Full-stack фреймворк на основе React. Создание production-приложений с SSR, SSG, App Router и Edge Runtime.
Примеры наших проектов
Смотреть всеLextum AI - Управление юридическими документами на основе искусственного интеллекта
SaaS-платформа для юристов с генерацией документов на основе ИИ, проверкой договоров, совместной работой в реальном времени, голосовыми/видеозвонками и версионированием.
Biletico - Платформа продажи билетов на мероприятия для детей
Платформа продажи билетов на мероприятия для детей. Доведена от почти нулевой функциональности до полноценного запуска благодаря схеме рассадки на основе canvas, безопасной интеграции платежей и полной переработке UX.
Welldone - Система управления промышленной прачечной
Решение из мобильного приложения и веб-панели, цифровизирующее процессы приема заказов, отгрузки, размещения на стеллажах и упаковки на единой платформе.
Обсудим ваш проект
Как применить эту услугу к вашему проекту?
Заполните форму заявки для бесплатной 30-минутной консультации.