Matvey-Kuk
@Matvey-Kuk
Разработчик в Cisco, CA.

Continuous Deploy. Не только вперед по истории коммитов git, но и экстренно назад?

Добрый вечер, товарищи!

Мой вопрос связан с построением процесса деплоя.

Допустим, у нас есть веб - проект, который при помощи jenkins переодически выкатывается из ветки master на боевой сервер. Разумеется, база данных мигрирует и все счастливы.

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

Мы хотим выкатывать приложение постоянно, чтобы избежать "Завтра релиз, всем нервничать!". С небольшой задержкой на тесты и сразу в бой после коммита и так сотни раз в день. Прямо как github =)

Теперь суть вопроса - как большие дяди делают откат на версию назад при попадании неудачного коммита в продакшен? Мы же хотим быстро откатить и обстоятельно за чашечкой кофе разбираться с ошибкой! Мы не хотим лезть по ссш на сервак! Мы не хотим писать свой велосипед, надежность которого в любой необдуманной ситуации равна нулю!

У меня есть идея, что необходим некий чат вроде slack, где будет переписка с ci сервером и в нужный момент мы шлем ему "Fu•k! Deploy previous version! Now!" =)

Какие инструменты? Не возникает ли проблем с базой от миграций туда-сюда? Спасают ли миграционные движки от детских болезней? Если да, то какие?

Спасибо, товарищи!
  • Вопрос задан
  • 4095 просмотров
Решения вопроса 2
@stasmarkin
Server side java engineer
Если честно, я не совсем понял вопрос :) Я попробую ответить на вопрос "как в небольшом веб-проекте делать быстрый откат на предыдущие версии".

Предположение 1: В принципе проект умещается на одной физической машине.
Предположение 2: Ваш веб-проект состоит из веб-сервера и БД (по крайней мере, только они обновляются при деплое). Никаких сбоку стоящих MQ, всякого мидл-вара и прочего взаимодействия с другими системами нет.

Мне кажется оптимальным решением сделать следующим образом:
Для откатывания кода достаточно в Jenkins сделать параметризированую сборку, и передавать в эту задачу хэш ревизии, на которую надо откатиться (лично я первым шагом такой сборки запускаю шелл скрипт "hg update -r ${REV_HASH} --clean", но может можно и через плагинчики в гуе настроить). Докер хорош, но он рассчитан на сильно распределенные системы, а в небольшом проекте мне кажется это оверкилл.

С откатыванием БД вопрос сложнее. Во-первых, потому что в любом случае делать "копию" любой базы -- это в той или иной степени лок. Хотя некоторые базы способны очень быстро делать снэпшоты, например mongoDB способна сделать бэкап без остановки и блокирования read/write без потери консистентности (при некоторых условиях, конечно же). Во-вторых, оптимальное решение будет зависеть от размера вашей базы и нагрузки на нее.
Например, если у вас MySQL на 100 мегобайт, то mysqldump, запускающийся Jenkins'ом перед началом деплоя новой версии, будет очень простым и надежным решением (естессно, с сохранением хэша текущей ревизии, чтобы потом одновременно с кодом откатиться).
Если у вас база 20гигов, то можно поднять рядом второй сервачок со слэйв-базой, и лочить ее при дампе тем же mysqldump'ом.
Если со вторым юнитом не хочется морочиться, а система позволяет заблокировать базу на небольшое время, то можно делать снэпшоты с помощью lvm'а, например. (см. www.lullabot.com/blog/article/mysql-backups-using-...

Из текста, я так понял, что еще интересует вопрос "как в большом проекте делают быстрый откат на предыдущие версии". Я так понимаю, что у "больших дядей" изменить архитектуру БД -- это очень дорогой и трудоемкий процесс. Особенно, если структура обратно не совместима (это же пересчеты всех индексов, огромные объемы информации, ожидание обновления всех реплик и тд). По-поводу деплоя, я так понимаю, у них тоже выбор не очень большой: это либо виртуалки (c докером, или чем-то подобным), либо application platform (либо свои, ли всякие PaaS'ы). Ну, а дальше все равно только одним способом: новые виртуалки/конейнеры включаются, обновляются записи в лоад-балансере, старые виртуалки/конейнеры выключаются.
Ответ написан
Комментировать
Fesor
@Fesor
Full-stack developer (Symfony, Angular)
Docker + Ansible. При деплое поднимаете контейнер с новой версией приложения (старая версия в скоем контейнере и пока работает), накатываете миграции (условие - миграции одной версии не должны вести к неработоспособности старой, иначе у вас проблемы с проектированием базы), подменяете текущий контейнер на новый и тушите его. Если вдруг что-то пошло не так, запускаете скрипт который проведет операцию в обратном направлении.

Если Docker смущает своей молодостью, есть вариант с оформлением приложения в виде DEB-пакета.

А еще есть Capistrano.

p.s. Довольно интересная тема, но на большинстве проектов, с которыми довелось сталкиваться или общаться с разработчиками оных, популярна стратегия "фиксить АСАП!" (за редкими исключениями, причем даже если минута простоя стоит тысячи долларов). Обычно это связано с тем что такие ситуации не случались ибо все предварительно обкатывается на стэйджинге с копией реальных данных.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы