Blue/green-розгортання з плаваючими IP
Класичний патерн blue/green: тримайте поточний продакшн за плаваючим IP, розгорніть нову версію на окремій VM, запустіть на ній smoke-тести, поки на неї ще не йде публічний трафік, а тоді перекиньте плаваючий IP зі старої VM на нову. Трафік переходить за ~2 секунди. Якщо щось піде не так, перекиньте IP назад.
Ця інструкція розрахована на навантаження з однією VM (одна продакшн-VM, одна staging-VM). Для навантажень із кількома VM за балансувальником навантаження див. сторінку Балансувальники навантаження — патерн той самий, але натомість ви перемикаєте цільові пули LB.
Що знадобиться
- Дві VM в одному регіоні. Назвемо їх
blue(зараз обслуговує трафік) іgreen(наступна версія). - Плаваючий IP, зараз підʼєднаний до
blue. - DNS-запис A, що вказує на плаваючий IP.
- Встановлений CLI
nimbusабо curl із заданим $NIMBUS_KEY.
export NIMBUS_KEY="nn_live_xxxxxxxxxxxxxxxx"
export BLUE_ID="vm_01HG7Y3..." # currently serving
export GREEN_ID="vm_01HG7Y4..." # new version
export FLOATING_IP_ID="ip_01HG7..."1 · Підготуйте VM green
Запустіть нову версію з оновленим кодом/конфігурацією, але без підʼєднаного плаваючого IP. На цьому етапі це окрема VM із публічним IP за замовчуванням; з продакшну на неї нічого не надходить.
Розгорніть на ній застосунок, виконайте міграції бази даних (якщо вони прямо сумісні — див. «міграції схеми» нижче), прогрійте кеші, виконайте всю стартову роботу, яка має відбутися до появи трафіку.
2 · Проведіть smoke-тести на green
Звертайтеся безпосередньо до публічного IP, який green має за замовчуванням:
GREEN_IP=$(curl -s https://api.nimbusnexus.net/v1/vms/$GREEN_ID \
-H "Authorization: Bearer $NIMBUS_KEY" | jq -r '.ipv4')
curl -H "Host: app.example.com" "http://$GREEN_IP/healthz"
curl -H "Host: app.example.com" "http://$GREEN_IP/api/critical-endpoint"Заголовок Host дає змогу перевірити поведінку, що залежить від канонічного імені хоста (напр., маршрутизацію, CORS, усе, що привʼязано до сертифіката), не змінюючи DNS. Якщо ваш сервіс вимагає HTTPS і ви привʼязали сертифікат до app.example.com, заздалегідь налаштуйте сертифікат на green (підійде Let's Encrypt із challenge HTTP-01 на IP green за замовчуванням).
Запустіть усі інші тести, які ви запускали б перед переведенням версії в продакшн:
- Повний набір smoke-тестів
- Перевірка підключення до бази даних (особливо якщо green працює з іншою конфігурацією пулера зʼєднань)
- Перевірка підпису вебхуків (якщо ви ротували секрет)
3 · Перекиньте плаваючий IP
Це і є cutover. Один виклик API:
curl -X POST https://api.nimbusnexus.net/v1/floating-ips/$FLOATING_IP_ID/attach \
-H "Authorization: Bearer $NIMBUS_KEY" \
-H "Content-Type: application/json" \
-d "{ \"vm_id\": \"$GREEN_ID\" }"Що відбувається:
- Плаваючий IP відʼєднується від
blue(цей IP був однією з її публічних адрес) - Плаваючий IP підʼєднується до
green - Зміни поширюються мережею за ~2 секунди; запити на IP починає обслуговувати green
- TCP-зʼєднання з IP старої VM лишаються відкритими, доки не закриються через простій (для HTTP keepalive зазвичай 30–60 секунд); нові зʼєднання потрапляють на green
Для більшості HTTP-навантажень це фактично розгортання без даунтайму. Наявні зʼєднання завершують свої запити на blue; нові запити потрапляють на green. Користувачів із довготривалими зʼєднаннями (SSE, WebSocket) їхні клієнти перепідключають автоматично.
4 · Стежте за green під навантаженням
Переглядайте логи green у реальному часі, стежте за частотою помилок і графіком запитів у дашборді. Тут проявляються аномалії реального трафіку, яких не виявили smoke-тести.
Дешево відкотитися можна протягом перших ~5 хвилин. Після цього blue — це «старий код, що працює без трафіку», і ви за нього платите; тож доведеться вибрати одне з двох:
- Перевести green у продакшн і зупинити blue (основний сценарій)
- Зупинити обидві VM і почати спочатку (рідко)
5 · Зупиніть blue
Якщо все зелене (буквально), зупиніть blue, щоб більше за нього не платити:
curl -X POST https://api.nimbusnexus.net/v1/vms/$BLUE_ID/stop \
-H "Authorization: Bearer $NIMBUS_KEY"Не робіть delete одразу. Зупинені VM коштують ~10 % від вартості запущених (лише сховище), і протягом ~24 годин їх можна знову запустити через start для швидкого відкату. Через 24 години видаліть їх.
Шлях відкату
Якщо green поводиться неправильно під навантаженням, відкат симетричний:
curl -X POST https://api.nimbusnexus.net/v1/floating-ips/$FLOATING_IP_ID/attach \
-H "Authorization: Bearer $NIMBUS_KEY" \
-H "Content-Type: application/json" \
-d "{ \"vm_id\": \"$BLUE_ID\" }"Ті самі ~2 секунди — і трафік знову на blue. Відкотитися складніше, якщо міграції бази даних не були прямо сумісними — тримайте міграції схеми окремо від розгортань коду, і можливість відкату залишиться.
Міграції схеми
Патерн, завдяки якому blue/green чисто працює зі змінами схеми: відокремте міграцію від розгортання.
Кожна зміна схеми — це два PR з інтервалом в один тиждень:
- PR із міграцією. Зворотно сумісна міграція схеми. Нові таблиці, нові стовпці, що допускають NULL, нові індекси. Старий код і далі працює з новою схемою. Розгортайте його звичайним шляхом (blue/green не потрібен — завдяки зворотній сумісності міграцію можна безпечно випустити окремо).
- PR із кодом. Код, що використовує нову схему. Розгортайте його через blue/green.
Коли треба видалити стовпець або змінити тип, послідовність зворотна: код перестає використовувати стовпець → розгортання коду → міграція видаляє стовпець. Завжди два PR, рознесені в часі. Між ними завжди можна безпечно зупинитися.
Цей патерн вимагає більше роботи, ніж «завжди розгортати схему й код разом», але зберігає безпечний відкат, а саме для цього blue/green і потрібен.
Наступні кроки
- Довідник плаваючих IP — усі ендпоінти ресурсу, завдяки якому цей патерн можливий.
- Балансувальники навантаження — той самий патерн для кількох VM.
- Failover між регіонами — та сама ідея, застосована до пар у географічно віддалених місцях.