Переїзд сервера без простою
Сервер можна копіювати, поки він обслуговує користувачів, і спинити лише на останні кілька секунд. Ось що це коштує, що для цього потрібно і як заздалегідь зрозуміти, чи підходить ваш сервер.
Що тут означають ці слова
Фізичний сервер ніхто не переносить зовсім без перерви: процеси мають стартувати наново на іншій машині, тож перезавантаження буде. Прибрати можна години копіювання. Старий сервер працює, поки його диски читають, і спиняється лише на останню дельту.
На швидкому каналі ця зупинка — менше двох секунд, виміряно на нашому стенді з Debian 12 і Rocky 9. Додайте одне перезавантаження нового сервера, і це вся перерва.
Як це працює
Утиліта кладе на старий сервер один статичний бінарник, запускає його від root і читає блочні пристрої напряму. Водночас вона стежить за кожним записом, щоб знати, які частини копії застаріли: програма eBPF на блочному шарі там, де ядро це вміє, і ftrace там, де не вміє, аж до CentOS 7.
Після першого проходу переїжджають лише змінені блоки, прохід за проходом, кожен менший за попередній. Коли та дельта, що лишилася, передаватиметься кілька секунд на виміряній швидкості, файлові системи морозяться через fsfreeze, остання дельта переїжджає, і новий сервер підіймається. Процеси під час заморозки не падають: їхні записи просто чекають, а читання працює далі.
Що потрібно
- Root на працюючому сервері, по ssh. Нічого туди не ставиться і на його диски нічого не пишеться.
- Ядро, здатне відстежувати записи: eBPF або ftrace аж до 3.10 з CentOS 7.
- Канал швидший, ніж сервер пише. Це і є справжня умова, і вона вимірюється, а не вгадується.
Команда
Окремого режиму вмикати не треба: утиліта визначає його з того, що старий сервер відповів зі своєї системи, а не з Live OS.
ssh -A root@НОВИЙ-СЕРВЕР
curl -fsSL reloca.to | bash
reloca.to -n root@СТАРИЙ-IP # план, нічого не пишеться
reloca.to root@СТАРИЙ-IP
Коротшу зупинку замовляють через -o converge=5: агент пересилатиме дельти, доки та, що лишилася, не передаватиметься за п'ять секунд або менше. Більше терпіння — -o patience=3600, якщо згодні витратити годину копіювання на коротшу паузу.
Коли воно не збіжиться
Якщо сервер пише на диск швидше, ніж канал забирає дані, чергова дельта не менша за попередню, і чекати марно. Агент міряє обидві швидкості й каже про це замість того, щоб молотити:
the donor writes 20.4 MiB/s, the link carries 14.9 MiB/s (1.37x): the deltas
cannot shrink, this will not converge
Далі він або бере те вікно, яке є, якщо воно коротше за дозволене через -o max-est=, або відмовляється морозити взагалі й лишає старий сервер недоторканим. Обидва результати безпечні: диск нового сервера записаний, старий не спинявся, і переїзд можна повторити в тихі години.
Що справді допомагає, у порядку корисності: переїжджати вночі, коли пишуть менше; взяти швидший канал; або погодитися на off-line режим і чесне вікно обслуговування.
Репетиція, яка дістається задарма
Типово старий сервер морозиться двічі. Після першої заморозки утиліта знімає знімок копії, розморожує донора і проганяє на цьому знімку всю доробку й перевірку, поки старий сервер знову обслуговує користувачів: збирається initramfs, ставиться grub, перевіряється завантажувальний запис і мережа. Лише потім вона доганяє дельти й морозить по-справжньому.
Саме це знаходить незавантажувану ціль, поки у вас ще працюють обидві машини. Коштує одного зайвого вікна заморозки — близько секунди на швидкому каналі й хвилину-дві на повільному; -o precheck=0 його прибирає.
Виміряно, а не обіцяно
Усі ці числа з одного переїзду сервера на CentOS 7.9, де генератор навантаження писав близько 20 МБ/с, а каналу задані справжні затримка і втрати.
| Канал | Збіжність | Вікно заморозки | Весь переїзд |
|---|---|---|---|
| 10 GbE | на третьому проході | 1.7 с | 223 с |
| 400 Мбіт, 20 мс | на четвертому проході | 8.7 с | 341 с |
| 100 Мбіт, 30 мс, 0.05% втрат | не збігається | 100 с | 953 с |
Опція, що керує кожним із цих чисел, — у довіднику опцій.
Спробуйте на своєму переїзді
Утиліта безкоштовна, сухий прогін не змінює нічого, а старий сервер лише читається.