Zero-Downtime Deployment у Kubernetes: налаштування та міграції

Оновлення бойового сервісу не повинно зупиняти продажі, заявки та платежі. Ми налаштовуємо випуск без простою під ключ: готуємо конфігурації, перевіряємо міграції даних і передаємо вашій команді схеми та регламенти випуску. Вікно недоступності скорочується з годин до нуля, а релізи йдуть за розкладом, а не вночі.
Часті запитання

Zero-downtime deployment: що ламається під час викатки в Kubernetes

Zero-downtime deployment ламається не на етапі збірки образу, а в момент, коли под знімають з балансування.

Типовий сценарій: RollingUpdate з maxUnavailable більше нуля відправляє поди на видалення відразу після сигналу, застосунок не встигає доопрацювати активні запити, а балансувальник ще тримає їх у своїх ендпоінтах — з'єднання рвуться на середині відповіді, і частина клієнтів отримує 502 замість даних.

Друга точка відмови — старт контейнера. Застосунок відповідає readiness-пробою раніше, ніж прогрів кеш, підняв пул з'єднань до бази й дочитав конфігурацію.

Трафік уже йде на неготовий под, запити валяться за тайм-аутом, поди йдуть у перезапуск — і сервіс стає недоступним рівно тієї хвилини, коли реліз і без того підняв навантаження на решту реплік.

Третій збійний сценарій — відкат під навантаженням. Стара й нова версії якийсь час працюють з однією схемою: міграція зроблена вперед, застосунок попереднього релізу не знає нових колонок і сипле помилками при оновленні версії. Відкат, який має займати секунди, перетворюється на розбір інциденту й відновлення даних.

Нижче розбираємо, як це закривається: коректне завершення з дренажем з'єднань, чесні проби з прогрівом, порядок міграцій і правила викатки, за яких відсутність простою — властивість конфігурації, а не везіння чергового.

Безперервний реліз без простою: що змінюється в роботі

Простій під час релізу створює не зміна образу, а момент, коли нова версія починає приймати трафік, а стара вже перестала.

Проба готовності тримає екземпляр поза балансуванням до прогріву, хук перед зупинкою дає відкритим з'єднанням закритися, а стратегія оновлення з нульовою часткою недоступних копій зберігає запас за репліками.

Проба готовності, хук перед зупинкою і запас в одну копію — штатні механізми Kubernetes, які й прибирають вікно: сервіс відповідає протягом усієї викатки. Налаштування виду maxUnavailable: 0 при maxSurge: 1 перестає бути ручною домовленістю і стає частиною опису розгортання.

Готовність до навантаження закривається бюджетом переривань: він не дає оновленню або витісненню вузла погасити занадто багато копій одразу, а контейнер, що прогрівається, наповнює кеш до потрапляння екземпляра в ротацію.

Міграції — окреме джерело падінь, і тут працює схема «розширити — переключити — стиснути». Спочатку в схему додається поле, яке розуміють обидві версії коду, потім трафік переводиться на нову логіку, і тільки потім видаляється старе. Реліз перестає бути атомарним стрибком — несумісна схема більше не належить до класів відмов.

Автоматизація випуску версій доводить це до конвеєра: версія описується декларативно, відкат — повернення попереднього опису, а не ручна перезбірка.

На практиці вікно недоступності йде в нуль, випуск версії займає один прохід замість серії узгоджень, а частка відкатів падає в рази — разом із класами «втрата трафіку на старті» та «міграція застосована раніше, ніж код до неї готовий».

Zero-downtime deployment: порівняння стратегій викатки

Вибір стратегії визначається тим, що дорожче саме у вашій системі: швидкість відкату, витрата ресурсів на другий контур або складність маршрутизації трафіку.

Усі режими опираються на один набір примітивів — репліки, перевірки готовності, сервісний балансувальник — і різняться лише порядком, у якому версії змінюють одна одну.

Обмеження тут важливіші за можливості. Поступове оновлення вимагає, щоб старі й нові екземпляри працювали одночасно й розуміли спільні дані, а синьо-зелений і канареечний контури — керованої маршрутизації. Нижче — критерії, за якими ми підбираємо режим під конкретний сервіс.

Стратегія викатки Коли підходить Обмеження
Поступове оновлення Сервіси без власного стану, регулярні релізи Стара і нова версії живуть паралельно: схема даних, формати повідомлень і відповідей мають читатися обома
Синьо-зелений контур Критичні інтерфейси, де потрібен миттєвий відкат перемиканням трафіку Подвійна витрата ресурсів на час викатки, підтримка двох наборів конфігурації та доступів
Канареечний випуск версії Зміни з неочевидним впливом, потрібен замір на частці аудиторії Потрібні метрики за версіями та маршрутизація за часткою трафіку, спостереження подовжує реліз
Повне перестворення Внутрішні та пакетні сервіси, фонові завдання Є вікно недоступності, для зовнішніх інтерфейсів не годиться

Окремо варто міграція схеми: її проводять у три кроки — розширення структури, перенесення даних, зняття старого поля — і тільки після того, як обидві версії застосунку перестали звертатися до попереднього формату.

Етапи впровадження: від аудиту кластера до передачі схем

Етапи йдуть послідовно, і кожен закривається перевіряним результатом — без нього наступний крок не починаємо. Порядок не переставляємо: налаштування викатки до аудиту оточень дає хибну впевненість, а регламент без перевірки на навчальному контурі не переживає першого релізу.

  1. Аудит кластера. Розбираємо, як розгорнуті сервіси: кількість реплік, проби готовності, коректність завершення подів і доля відкритих з'єднань під час зупинки. Вузьке місце зазвичай одне — спільний зовнішній балансувальник без керування часткою трафіку.
  2. План впровадження. Схема оточень, розмежування доступів і секретів, черга змін за сервісами — так, щоб релізи не заважали один одному, а відкат був можливий на будь-якому кроці.
  3. Налаштування викатки. Поетапне оновлення з лімітом на кількість одночасно недоступних реплік, проби готовності з робочими порогами, пауза на закриття з'єднань перед зупинкою контейнера.
  4. Міграції схеми даних. Розбиваємо на сумісні кроки: розширення, перенесення, видалення старого поля. Стара і нова версії сервісу працюють одночасно, відкат не втрачає дані.
  5. Перевірка на навчальному контурі. Прогін релізу під навантаженням і з імітацією відмов: відключення вузла, обрив з'єднань, помилка в новій версії. Вважаємо втрати трафіку та час відновлення.
  6. Передача регламентів. Схеми оточень, конфігурації, порядок релізу та відкату, перелік метрик і умови, за яких викатка зупиняється автоматично.

Після передачі ваші чергові випускають релізи за документованим маршрутом, а ми залишаємося на зв'язку на період перших самостійних викаток.

Що залишається у замовника: конфігурації, схеми, регламенти

Ми не залишаємо замовника з набором усних домовленостей: усе, що визначає поведінку системи під час викатки без простою, живе в репозиторії разом з історією змін.

Інженер, який прийде в команду пізніше, прочитає не «так історично склалося», а причину кожного виставленого параметра.

  • Конфігурації викатки — декларативні описи з параметрами готовності, паузою між хвилями та умовами автоматичного відкату.
  • Схеми оточень — карта стендів, їх відмінностей за даними та навантаженням, порядку просування збірки між ними.
  • Політики доступу — права видані ролям, а не людям: межі «хто запускає викатку, хто читає журнали» переживають зміну складу команди.
  • Документація — шлях запиту через оновлювану версію, обов'язкові перевірки та порядок дій при розбіжності очікуваного й фактичного стану.
  • Регламент чергування — які сигнали переводять чергового в режим відкату, кому йде ескалація і що розбирається після інциденту.
  • Сценарії міграцій — порядок змін схеми даних, сумісний зі старою та новою версією застосунку на час перемикання трафіку.
  • Перевірки перед випуском — набір автоматичних прогонів, без яких збірка не проходить далі тестового контуру.

Кожен пункт — робочий файл, а не опис на словах: його можна порівняти з поточним станом системи й одразу побачити розбіжність.

Кейс: реліз платіжного сервісу без зупинки трафіку

Платіжний сервіс випускали в нічне вікно: прийом платежів зупиняли на 30–40 хвилин, оновлювали, піднімали назад. Коли щось ішло не так, відкатували вручну — ще від сорока хвилин до години, а частину операцій доводилося дораховувати окремо. Кожен такий випуск займав нічну зміну чергових.

Що змінили

У Kubernetes перейшли на стратегію RollingUpdate з параметрами maxUnavailable: 0 і maxSurge: 1: нова репліка потрапляє в балансування тільки після успішної readiness-проби, а стара отримує сигнал на зупинку й доопрацьовує вже прийняті запити.

Міграції схеми винесли зі старту контейнера в окремий крок із блокуванням — паралельні репліки більше не накочують ту саму схему і не валять випуск.

Поля в базі додавали за схемою expand-contract: новий код читає і старі, і нові дані, а несумісні видалення йдуть наступним релізом.

Метрики до і після

Час випуску версії скоротився з 40–60 хвилин нічного вікна до 6–8 хвилин у робочий час. Частка відкатів упала з приблизно кожної п'ятої викатки до однієї з двадцяти, і майже всі вони автоматичні — за метриками помилок, без ручного розбору.

Звернень користувачів до сторінки помилки під час релізу — нуль: з'єднання дочікуються відповіді від живої репліки замість обриву.

Через кілька місяців ручний контроль на викатці прибрали зовсім: черговий підключається, тільки якщо автоматика сама повернула попередню версію й позначила реліз.

Чим викатка нової версії відрізняється від перезапуску сервісу?

Перезапуск застосунку та викатка нової версії — різні операції з різними наслідками. Перезапуск піднімає процеси заново на тому самому образі, версія коду не змінюється.

Зміна версії — це заміна образу в описі робочого навантаження, і тут оркестратор зобов'язаний провести трафік повз старі екземпляри, не вронивши жодного з'єднання.

Різниця видна в тому, як вважається готовність до трафіку. При перезапуску сервіс повертається в балансування, як тільки процес віддав порт.

При оновленні контейнера потрібна проба, що перевіряє не «чи живий процес», а «чи готовий він обслуговувати запит»: з'єднання з базою, прогрітий кеш, доступність залежностей. Без неї нова версія отримує звернення на етапі ініціалізації — звідси помилки на першому ж запиті.

Друга половина завдання — коректне завершення. Старий екземпляр не видаляють відразу: спочатку виводять з балансування, потім надсилають сигнал зупинки і тільки після заданого вікна закривають з'єднання.

Поруште порядок — частина клієнтів обірветься рівно в момент зміни версії, хоча оновлення формально пройшло успішно.

У Kubernetes ці кроки описуються декларативно: скільки копій піднімати паралельно, яку частку можна вивести з ладу, скільки чекати завершення. Це параметри маніфесту, а не ручні дії інженера в момент релізу.

Саме ця різниця відділяє перезапуск від zero-downtime deployment: викатка йде довше, але користувач не бачить простою. Для сервісів з базою додається порядок міграцій — розширення схеми до викатки, видалення застарілих полів після.

Технічні сумніви: міграції схем і зворотна сумісність

Зміна структури даних — те, що по-справжньому ламає zero-downtime deployment. Поки йде викатка, в кластері одночасно живуть поди старого й нового покоління, і обидва працюють з однією базою.

Схема зобов'язана залишатися сумісною з обома версіями коду: інакше нова падає на старих даних, а стара — на нових.

Тому міграції ділимо на етапи. Спочатку розширення: додаємо колонку або таблицю, код пише в старе й нове місце одночасно. Потім фоновий перенос даних порціями, перемикання читання — і тільки окремим релізом видалення старого поля. Відкат застосунку за такої схеми не потребує відкату бази.

Що буде, якщо реліз доведеться відкотити?

Поки міграція на етапі розширення, попередня версія працює без змін — відкат це повернення на попередній образ. Видалення старих колонок виносимо в окремий реліз після періоду спостереження, щоб можливість відкату зберігалася.

Як переконатися, що стара версія не зламається?

У конвеєр додаємо перевірку сумісності: попередній реліз проганяється проти нової схеми на тестовій копії. Важкі зміни — перебудову індексів, зміну типу — виконуємо неблокуючими операціями з лімітом часу, інакше блокування на великій таблиці зупинить запис.

Як версіонується схема?

Таблицею застосованих міграцій і звіркою в конвеєрі: збірка не викатується, якщо версія схеми не збігається з очікуваною. Самі міграції ідемпотентні та застосовуються до старту подів, тому повторний запуск нічого не ламає.

Обговоримо задачу: повернемося з оцінкою та планом впровадження

Щоб оцінка проєкту опиралася на ваш контур, а не на загальні припущення, обговорення задачі починаємо з короткого технічного розбору.

Нам важливо зрозуміти, як збирається реліз, як трафік потрапляє в кластер, які процеси живуть довше окремого пода і що відбувається з базою під час викатки. Зазвичай вистачає однієї розмови та доступу до маніфестів, регламенту релізів і схеми сервісів.

Що варто підготувати до цієї розмови:

  • Як реліз викатується зараз: послідовне оновлення реплік, паралельний контур або частка трафіку на нову версію.
  • Чи налаштовані перевірки готовності і як сервіс доопрацьовує запити, коли под зупиняється.
  • Як застосовуються міграції схеми: окремо від коду, зі зворотною сумісністю або одним кроком.
  • Чи є фонові завдання та черги, які не можна запускати у двох версіях одночасно.
  • Які перевірки проходять до викатки і за якими метриками ви вирішуєте, що реліз удався.
  • Припустиме вікно обслуговування та припустима частка втрачених запитів при перемиканні.

У відповідь повертаємося з оцінкою проєкту: склад робіт за етапами, порядок викатки, точки відкату та перелік змін у конфігурації. План впровадження розбиваємо на кроки так, щоб перший із них уже знімав простій, а решта — закріплювали результат. Опишіть задачу — повернемося з оцінкою та планом.

Наші компетенції:

Останні роботи

  • Розробка сайту компанії B2B ADVANCE
    Розробка сайту компанії B2B ADVANCE
    1542
  • Розробка веб-додатків для компанії FEEDME
    Розробка веб-додатків для компанії FEEDME
    1394
  • Розробка веб-сайту для компанії БЕЛФІНГРУП
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    1081
  • Розробка інтернет магазину для компанії FURNORO
    Розробка інтернет магазину для компанії FURNORO
    1369
  • Розробка логотипу компанії B2B Advance
    Розробка логотипу компанії B2B Advance
    816
  • Розробка веб-додатків для компанії Enviok
    Розробка веб-додатків для компанії Enviok
    1142