Як перенести сервер на новий VPS без простою
Покрокове перенесення Linux-сервера на новий VPS: інвентаризація, відновлення замість клонування, дамп бази, зниження TTL DNS і перевірка перед перемиканням.
Перенесення сервера на новий VPS як заздалегідь відрепетироване перемикання
Щоб перенести сервер на новий VPS, сприймайте цей процес як заздалегідь відрепетироване перемикання, а не як копіювання. Створіть новий сервер з нуля, двічі синхронізуйте дані, перевірте роботу нового сервера за його власною IP-адресою до зміни DNS, а потім змініть записи й залиште старий сервер запущеним, доки не переконаєтеся в успішності перенесення. Копіювання даних — найпростіша частина. Саме порядок дій визначає, чи пройде перенесення без проблем, чи спричинить значні витрати.
У цьому посібнику описано один Linux-сервер, на якому працюють вебзастосунок і база даних та зберігається сертифікат TLS (transport layer security). Така конфігурація охоплює більшість односерверних середовищ. Задіяно два хости, тому в коментарі до кожного прикладу зазначено, на якому хості його потрібно виконувати. Адреси взято з діапазонів, призначених для документації: 198.51.100.10 — старий сервер, 203.0.113.20 — новий.
Прочитайте весь план дій до початку роботи. Перший крок — зменшення TTL DNS — потрібно виконати за кілька днів до кроку, який має для вас основне значення.
Створіть інвентаризацію до початку робіт
Неможливо відновити сервер, опис якого ви не зафіксували. Приділіть годину та запишіть, що робить старий сервер. Після міграції завжди ламається те, про що ніхто не згадав: завдання cron, виняток у firewall або файл середовища за межами каталогу застосунку.
Виконайте ці команди на старому сервері та збережіть вивід у місці, доступному з нового сервера.
# old server: packages you asked for, not the dependencies they pulled in
apt-mark showmanual > ~/inv-packages.txt
# old server: what runs now, and what starts at boot
systemctl list-units --type=service --state=running --no-pager > ~/inv-services.txt
systemctl list-unit-files --state=enabled --no-pager >> ~/inv-services.txt
systemctl list-timers --all --no-pager > ~/inv-timers.txt
# old server: what is listening, on which address and port
sudo ss -tulpn > ~/inv-ports.txt
# old server: human accounts, skipping the system ones
awk -F: '$3 >= 1000 && $3 < 65534 {print $1, $3, $6, $7}' /etc/passwdapt-mark showmanual — це корисний список, оскільки він містить усе, що було встановлено як залежність. Повний dpkg --get-selections на сервері віком п’ять років може містити дві тисячі рядків і нічого не повідомити про призначення пакетів.
Заплановані завдання зберігаються у двох місцях, тому перевірте обидва. Завдання, яке запускається лише раз на місяць, ви виявите через шість тижнів після міграції.
# old server: per-user crontabs, then the system drop-ins
for u in $(cut -d: -f1 /etc/passwd); do sudo crontab -lu "$u" 2>/dev/null | sed "s/^/$u: /"; done
sudo ls -la /etc/cron.d /etc/cron.daily /etc/cron.hourlyДалі перевірте компоненти, які не є звичайними файлами: правила firewall, сертифікати, бази даних і фактичний обсяг даних, який ви переносите.
# old server
sudo ufw status verbose # or: sudo nft list ruleset
sudo certbot certificates
sudo -u postgres psql -c '\l' # or: sudo mysql -e 'SHOW DATABASES;'
sudo du -xh --max-depth=1 / | sort -hcertbot certificates виводить назву кожного сертифіката, домени, які він охоплює, дату завершення дії та шляхи до файлів на диску. Цей вивід є вашим контрольним списком TLS. du -x працює лише в межах однієї файлової системи, тому не переходить на змонтований том резервних копій і не повертає значення, завищене вдесятеро.
Є два зовнішні компоненти, про які щоразу забувають. По-перше, перевірте всі сторонні системи, які додають IP-адресу вашого сервера до allowlist: платіжний шлюз, керовану базу даних, SMTP relay або партнерський API. Новий сервер матиме нову адресу, тому додайте нову IP-адресу до таких allowlist до перемикання, а не після нього. По-друге, перевірте записи DNS, які створювали не ви, наприклад запис MX або запис SPF, у тексті якого вказано стару IP-адресу.
Чому варто перебудувати систему, а не клонувати стару кореневу файлову систему
Клонування всієї кореневої файлової системи на новий VPS здається швидшим. Так і є — доки не виникають проблеми. Коренева файлова система, яка роками працювала в production, містить конфігурацію, змінену вручну й ніде не задокументовану, пакети з репозиторію, якого вже не існує, і конфігурацію завантаження, підготовлену для віртуального обладнання старої платформи. Ви імпортуєте все це, зокрема й причину міграції.
Перебудова повільніша в перший день, але щодня після цього зменшує витрати. Ви встановлюєте поточний реліз, застосовуєте базове hardening, а потім копіюєте лише дані: каталог застосунку, конфігурацію сайтів, дамп бази даних, сертифікати та завантажені користувачами файли. Усе, що ви не можете пояснити, не переноситься. Почніть налаштування нового сервера так само, як і будь-якого іншого, з перших десяти хвилин на новому VPS, потім додавайте сервіси з інвентаризації по одному й перевіряйте кожен перед додаванням наступного.
Коли відновлення з image або snapshot є правильним рішенням
Є один обґрунтований виняток із правила про повторне розгортання. Якщо старий сервер не завантажується або застосунок більше неможливо зібрати з вихідного коду, практичним рішенням буде відновлення з image або snapshot провайдера. Такий підхід має суттєві обмеження: він працює в межах одного провайдера, часто лише в межах одного сімейства планів, оскільки відновлений диск очікує на віртуальні пристрої та мережеві імена саме цієї платформи.
Snapshot запущеного сервера також має ту саму проблему узгодженості, що й будь-яка інша копія файлів активної бази даних. Розглядайте відновлення з image як спосіб відновлення, а не як план міграції, і прочитайте чому snapshot — це не те саме, що backup, перш ніж будувати на ньому план.
Як переміщуються файли: rsync через SSH
Запустіть rsync на старому сервері та передайте дані на новий. Передавання зручніше, оскільки дані вже зберігаються на старому сервері, і він може прочитати їх усі через sudo.
# old server: dry run first, and read what it says it will do
sudo rsync -aHAX --dry-run --itemize-changes \
-e 'ssh -i /root/.ssh/id_ed25519' \
/srv/app/ deploy@203.0.113.20:/srv/app/
# old server: the real bulk pass
sudo rsync -aHAX --info=progress2 \
-e 'ssh -i /root/.ssh/id_ed25519' \
/srv/app/ deploy@203.0.113.20:/srv/app/Прапорці мають значення. -a зберігає права доступу, часові мітки, символічні посилання та власника. -H зберігає жорсткі посилання як жорсткі посилання, а не розгортає їх в окремі копії. -A копіює POSIX ACL (списки контролю доступу), а -X копіює розширені атрибути. Без останніх двох параметрів файл, який виглядає ідентично, може поводитися інакше, оскільки мітки SELinux і ACL зберігаються в розширених атрибутах, а інші механізми їх не фіксують.
Більшість проблем тут спричиняють дві деталі.
Кінцевий слеш визначає, куди потраплять дані. /srv/app/ означає вміст цього каталогу. /srv/app означає сам каталог. Якщо помилитися, на новому сервері з’явиться /srv/app/app, а застосунок запуститься, а потім повідомить про відсутні файли, оскільки налаштовані для нього шляхи тепер на один рівень коротші.
У sudo тильда позначає домашній каталог root. Запис -e 'ssh -i ~/.ssh/id_ed25519' всередині sudo rsync означає пошук ключа в /root/.ssh, а не у вашому домашньому каталозі. Якщо ключа там немає, SSH виведе Permission denied (publickey), rsync виведе rsync: connection unexpectedly closed і завершиться з ненульовим кодом. Укажіть повний шлях до ключа. Якщо після виправлення шляху це повідомлення автентифікації продовжує з’являтися, помилка publickey має короткий перелік причин, і наступним слід перевірити права доступу до каталогів на новому сервері.
Для власності потрібно прийняти одне рішення. Під час запуску від імені root rsync за замовчуванням зіставляє власника та групу за іменем, тому файл, який належить www-data на старому сервері, стане власністю www-data на новому, навіть якщо числовий UID (ідентифікатор користувача) відрізняється. Для перебудови це потрібна поведінка. Додавайте --numeric-ids лише під час копіювання файлової системи, облікових записів якої немає на цільовому сервері. Потім перевірте результат за допомогою ls -ln, оскільки файл, що належить UID без відповідного облікового запису, відображається лише числом, і кожному сервісу, який його читає, буде відмовлено в доступі.
Запустіть основне копіювання за кілька днів до перенесення, поки старий сервер ще обслуговує трафік. Повторюйте його скільки потрібно: rsync передає лише змінені дані, тому друге копіювання триває хвилини, а не години. Під час фінального копіювання у вікні перемикання додайте --delete, щоб файли, видалені на старому сервері, також зникли на новому.
# old server: final pass, inside the window, after the app has stopped writing
sudo rsync -aHAX --delete --info=progress2 \
-e 'ssh -i /root/.ssh/id_ed25519' \
/srv/app/ deploy@203.0.113.20:/srv/app/--delete видаляє на цільовому сервері файли, яких немає у джерелі. Тому неправильний шлях до джерела разом із --delete може очистити цільовий каталог. Щоразу спочатку запускайте команду з --dry-run. Тривалі передавання також перериваються, якщо розривається SSH-сеанс на вашому ноутбуці. Тому запускайте їх усередині tmux або screen на старому сервері. Додайте --bwlimit=20M, якщо копіювання повністю завантажує канал, поки старий сервер ще обслуговує користувачів.
Як переміщується база даних: власний дамп
База даних — це не каталог файлів, навіть якщо вона має такий вигляд. Це набір файлів, стан у пам’яті та журнал випереджувального запису. Узгодженість гарантується лише в моменти, які визначає сама база даних. Використовуйте її власний інструмент.
Для PostgreSQL потрібні два дампи, оскільки ролі є загальними для всього кластера, а pg_dump їх не містить:
# old server
sudo -u postgres pg_dumpall --globals-only -f /var/backups/globals.sql
sudo -u postgres pg_dump -Fc -f /var/backups/appdb.dump appdb# new server: restore in this order
sudo -u postgres psql -f /var/backups/globals.sql
sudo -u postgres createdb -O appuser appdb
sudo -u postgres pg_restore -d appdb --no-owner /var/backups/appdb.dumpЯкщо пропустити globals.sql, буде відновлено всі таблиці, але жодна роль застосунку не матиме змоги їх читати, оскільки інструкції GRANT посилаються на користувача, якого не існує. -Fc записує архів у custom-форматі. Його читає лише pg_restore, і він дає змогу пізніше відновлювати вибрані таблиці. Відновлюйте дані в тій самій або новішій major-версії. Зворотний перехід, наприклад з 17 на 16, не підтримується. У такому разі pg_restore відхиляє архів із помилкою непідтримуваної версії в заголовку файлу ще до запису будь-яких даних.
MySQL і MariaDB використовують одну команду з чотирма параметрами, які не є типовими:
# old server
sudo mysqldump --single-transaction --routines --triggers --events \
--databases appdb > /var/backups/appdb.sql# new server
sudo mysql < /var/backups/appdb.sql--single-transaction створює узгоджений знімок без блокування операцій запису, але лише для таблиць InnoDB. Таблиця MyISAM у тій самій базі даних копіюється без такої гарантії. Тому перевірте механізми зберігання, перш ніж покладатися на дамп. --routines, --triggers і --events за замовчуванням вимкнені. Це означає, що звичайний дамп відновить дані, але непомітно залишить без відновлення збережені процедури та заплановані події. Користувачі бази даних і їхні дозволи зберігаються в системній базі даних mysql. Дамп --databases appdb до неї не звертається, тому створіть користувачів і дозволи на новому сервері за допомогою CREATE USER і GRANT. MariaDB 11 постачається з тим самим інструментом під назвою mariadb-dump і зберігає mysqldump як symbolic link, тому станом на August 2026 працює будь-яка назва.
SQLite зберігається в одному файлі. Якщо скопіювати його під час запису застосунку, файл буде пошкоджено через неповну узгодженість. Для цього передбачено власний безпечний спосіб:
# old server
sqlite3 /var/lib/app/app.db ".backup '/var/backups/app.db'"Незалежно від рушія, перевірте дамп, перш ніж йому довіряти. Дамп, створення якого завершилося передчасно через заповнення диска, може відновитися без повідомлення про помилку — аж до місця, де його було обрізано.
# old server: a complete mysqldump ends with a line reading "-- Dump completed on ..."
tail -n 3 /var/backups/appdb.sql
# new server: after restore, count rows in a table whose size you know
sudo mysql -e 'SELECT COUNT(*) FROM appdb.orders;'Чому rsync не можна використовувати для запущеної бази даних
rsync копіює файли по одному. Запущена база даних одночасно записує дані в кілька файлів, тому до моменту, коли rsync доходить до останнього файлу, перший уже може бути неактуальним. Копія містить сторінки з різних моментів часу — такого стану база даних ніколи не мала. У результаті сервер або відмовляється запускатися, або, що гірше, запускається, повертає правильні відповіді протягом тижня, а потім завершує роботу, коли запит нарешті звертається до пошкодженої сторінки. До цього моменту жодного попередження може не бути.
Є два безпечні способи перемістити самі файли. Зупиніть базу даних, скопіюйте файли та запустіть її знову. Це правильно й просто, але простій триватиме стільки, скільки потрібно для копіювання. Або скористайтеся інструментом, призначеним для фізичного копіювання запущеного сервера. Для PostgreSQL це pg_basebackup. Він координує роботу із сервером, щоб копія була узгодженою:
# new server: pull a physical copy from the old one
pg_basebackup -h 198.51.100.10 -U replicator -D /var/lib/postgresql/16/main -X stream -PДля цього потрібна роль з атрибутом REPLICATION і відповідний запис pg_hba.conf на старому сервері, тому налаштування складніше, ніж для дампа. Це виправдано, якщо база даних достатньо велика, а створення дампа та відновлення не вкладаються у доступне вікно обслуговування. Для звичайної міграції на один сервер краще використовувати дамп.
Перевипустіть сертифікати до перемикання, а не після нього
TLS-сертифікат прив’язаний до доменного імені, а не до IP-адреси, тому сам файл сертифіката можна без проблем перенести. Поновлення переноситься не так просто. Стандартна HTTP-01 перевірка Certbot просить центр сертифікації отримати файл через порт 80 за іменем, для якого випускається сертифікат. Поки DNS не вказує на новий сервер, цей запит надходить на старий сервер, і поновлення на новому сервері завершується помилкою.
Перший варіант — скопіювати наявні сертифікати та дані про їх поновлення. Вони залишаються чинними до дати завершення строку дії незалежно від того, на якому сервері зберігаються.
# old server
sudo rsync -aHAX -e 'ssh -i /root/.ssh/id_ed25519' \
/etc/letsencrypt/ root@203.0.113.20:/etc/letsencrypt/Кожен файл у /etc/letsencrypt/renewal/ містить назву плагіна-автентифікатора, який видав сертифікат. Тому встановіть той самий плагін на новому сервері (наприклад, python3-certbot-nginx), інакше перше поновлення завершиться помилкою про невідомий автентифікатор. Перевірте, що поновлення працює, перш ніж покладатися на нього:
# new server, after DNS has moved
sudo certbot renew --dry-runДругий варіант — випустити новий сертифікат на новому сервері за допомогою перевірки DNS-01. Вона підтверджує контроль над доменом через TXT-запис і не використовує порт 80. Це працює ще до міграції, поки ім’я вказує на старий сервер. Тому це зручніший варіант, якщо ви можете автоматизувати роботу з DNS-провайдером. У розділі Випуск сертифікатів за допомогою перевірки DNS-01 описано налаштування плагіна та облікових даних.
У будь-якому разі перевірте, що фактично повертає новий сервер, не змінюючи DNS:
# your laptop
echo | openssl s_client -connect 203.0.113.20:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -subject -dates -issuer-servername надсилає SNI (індикацію імені сервера). Саме завдяки цьому вебсервер вибирає правильний virtual host. Якщо не вказати його, ви отримаєте сертифікат за замовчуванням для цієї IP-адреси та невідповідність, яка виглядає як реальна проблема, але нею не є.
Зменште TTL DNS за кілька днів до перемикання
DNS — це місце, де навіть ретельно спланована міграція може завершитися проблемою, оскільки затримка закладена в сам механізм, і в день перемикання її вже не можна скоротити. Резолвер, який кешував ваш A-запис, продовжує використовувати його протягом усього TTL (time to live), переданого разом із записом. Якщо зменшити TTL зараз, це нічого не змінить для резолвера, який десять хвилин тому закешував запис зі старим значенням: він зберігатиме старе значення до завершення старого TTL і лише після цього дізнається про нове, коротше значення. Тому зменште TTL щонайменше за один повний період старого TTL до перемикання. Варіант із запасом — зробити це за день. Якщо ці механізми для вас нові, ознайомтеся з поясненням про записи, резолвери та кешування.
Наведені нижче числа — це арифметичні значення, отримані з самого TTL, а не результати вимірювання.
The data behind this chart
[
{
"label": "TTL 3600 s (common default)",
"ttl_seconds": 3600,
"worst_case_stale_minutes": 60
},
{
"label": "TTL 900 s",
"ttl_seconds": 900,
"worst_case_stale_minutes": 15
},
{
"label": "TTL 300 s (lowered for cutover)",
"ttl_seconds": 300,
"worst_case_stale_minutes": 5
},
{
"label": "TTL 60 s (short window)",
"ttl_seconds": 60,
"worst_case_stale_minutes": 1
}
]Запис із TTL 3600 секунд може спрямовувати користувачів на стару IP-адресу ще 60 хвилин після її зміни. Зменште TTL до 300 секунд, і цей максимальний період скоротиться до 5 хвилин. Вважайте ці значення мінімальним орієнтиром, а не гарантією. Деякі резолвери встановлюють власний мінімальний TTL і ігнорують коротші значення. Деякі середовища виконання застосунків кешують resolved address протягом усього часу роботи процесу. Тому клієнт, запущений до зміни, може не виконати новий запит, доки його не буде перезапущено.
Під час перевірки, чи почав діяти зменшений TTL, читайте відповідь authoritative DNS, а не власний кеш:
# your laptop: ask the zone's own nameserver, so no cache is involved
dig +short NS example.com
dig +noall +answer @$(dig +short NS example.com | head -n1) example.com AДругим полем у цьому рядку відповіді є TTL у секундах. Потім перевірте записи, про які часто забувають: запис AAAA, якщо старий сервер використовував IPv6; ім’я www, коли воно є окремим A-записом, а не CNAME; будь-який MX-запис, що вказує на сам сервер; SPF-запис зі старою IP-адресою; а також reverse DNS (PTR) для нової адреси. Якщо сервер надсилає пошту, налаштуйте PTR через панель керування вашого провайдера до перемикання. Сервери-одержувачі перевіряють цей запис, і відсутній PTR може призвести до відхилення пошти через кілька годин після того, як усе інше вже виглядало справним.
Перевірте новий сервер за його IP-адресою, перш ніж змінювати DNS
Ви можете протестувати весь застосунок на новому сервері, поки DNS усе ще вказує на старий сервер. Перевизначте пошук імені для одного запиту:
# your laptop: force one name to the new IP, for this request only
curl -sS --resolve example.com:443:203.0.113.20 \
-o /dev/null -w '%{http_code} %{ssl_verify_result}\n' https://example.com/--resolve змінює лише адресу, до якої встановлюється з’єднання. Сертифікат TLS усе одно перевіряється для справжнього імені, тому так ви перевіряєте і сертифікат, і сервіс. %{ssl_verify_result} виводить 0, якщо ланцюжок сертифікатів пройшов перевірку.
Щоб переглянути сайт у браузері, перевизначте ім’я для всієї системи. Додайте один рядок до /etc/hosts на ноутбуці або до C:\Windows\System32\drivers\etc\hosts у Windows:
203.0.113.20 example.com www.example.comПотім перевірте застосунок так, як це робив би користувач. Увійдіть у систему. Відкрийте сторінку, яка читає дані з бази даних. Надішліть форму, яка записує дані до бази. Завантажте файл і переконайтеся, що він з’явився на диску. Запустіть дію, яка надсилає електронну пошту, і перевірте, що повідомлення надійшло, оскільки вихідний SMTP із нової IP-адреси часто спричиняє несподівані проблеми. Видаліть рядок із hosts одразу після завершення перевірки. Якщо залишити його, можна витратити годину на налагодження сайту, який усі інші користувачі без проблем бачать.
Перемикання, крок за кроком
- За кілька днів: зменште TTL, виконайте масове копіювання за допомогою rsync, підготуйте новий сервер і протестуйте його через перевизначення hosts.
- У день перемикання, до початку вікна: додайте нову IP-адресу до всіх списків дозволених адрес у сторонніх сервісах і переконайтеся, що завдання резервного копіювання нового сервера налаштоване та використовує ваш репозиторій.
- На початку вікна: увімкніть режим обслуговування застосунку на старому сервері, щоб він припинив приймати операції запису.
- Створіть фінальний дамп бази даних, потім виконайте фінальний прохід rsync з
--delete. - Відновіть дамп на новому сервері та запустіть сервіси.
- Знову протестуйте через
--resolveі перевизначення hosts, зокрема виконайте один реальний запис. - Змініть записи A і AAAA на нову IP-адресу.
- Спостерігайте за обома серверами. У журналі доступу старого сервера видно, хто ще надсилає туди запити, і це число має наближатися до нуля протягом TTL.
- Вимкніть сторінку обслуговування.
- Залиште старий сервер запущеним і не змінюйте його конфігурацію щонайменше тиждень.
Крок із режимом обслуговування часто пропускають, хоча саме він забезпечує захист. Після того як нова база даних прийняла запис, відкат означає або втрату цього запису, або створення дампу нової бази даних і завантаження його назад у стару. Вікно лише для читання тривалістю кілька хвилин — невелика плата. Дві бази даних, у які вже виконувалися записи, вимагатимуть днів ручного узгодження.
План відкату
Відкат — це одна дія: поверніть DNS-записи на 198.51.100.10. Це працює лише завдяки чотирьом речам, які ви зробили раніше.
- Старий сервер досі працює, його сервіси запущені, а дані не пошкоджені. Ви зупинили запис даних на ньому, але не вивели його з експлуатації.
- TTL досі має низьке значення, тому повернення можна виконати так само швидко, як і перехід на новий сервер.
- Ви додали нову IP-адресу до allowlist сторонніх сервісів, а не замінили стару. Якщо видалити стару адресу, відкат не працюватиме на платіжному шлюзі.
- Новий сервер не отримав жодних записів, які ви не можете ідентифікувати, оскільки всі записи досі були лише вашими тестовими транзакціями.
До початку вікна обслуговування визначте, що саме запускає відкат. Достатньо двох умов: будь-яка помилка, причину якої не вдається встановити протягом визначеної кількості хвилин, і будь-яка втрата даних. Якщо заздалегідь записати ці умови, можна уникнути години припущень, через яку десятихвилинний простій перетворюється на тривалий.
Перевірте, чи міграція виконана успішно
Міграція не завершена лише тому, що сайт завантажується. Перевірте те, що може відмовити пізніше.
# new server
systemctl --failed
journalctl -p err -b --no-pager | tail -n 40
sudo certbot certificates
sudo systemctl list-timers --all --no-pagersystemctl --failed reporting 0 loaded units listed — це результат, який вам потрібен. certbot certificates має показувати очікувані дати завершення дії, а list-timers — усі заплановані завдання з вашого переліку з фактичним часом наступного запуску, а не порожнім значенням.
Після цього навмисно один раз перезавантажте новий сервер, спостерігаючи за процесом. Сервіс, який хтось запустив вручну й не ввімкнув для автозапуску, працює бездоганно до першого незапланованого перезавантаження о третій годині ночі.
# new server
sudo reboot
# your laptop, once it comes back
curl -sS -o /dev/null -w '%{http_code}\n' https://example.com/Якщо застосунок працює в контейнерах, ця проблема має інший вигляд, оскільки для повторного запуску compose stack після перезавантаження потрібна явна restart policy.
Остання перевірка — найпростіша для відкладання і найважливіша: завдання резервного копіювання. Міграція, після якої сервер не має резервної копії, лише замінює один ризик іншим. Запустіть резервне копіювання на новому сервері вручну, а потім відновіть із нього один файл у тимчасовий каталог. Репозиторій restic із фактично перевірленим відновленням — це саме той варіант, який допоможе, коли він знадобиться. Якщо ви протягом тижня тримаєте старий і новий сервери паралельно, узгоджений спосіб підключення до кожного хоста та його налаштування не дасть їм розійтися в конфігурації, поки обидва працюють.
Після перемикання: старий сервер і останні завдання
Залиште старий сервер на один-два тижні. Це коштує один місяць тарифного плану, який ви все одно збиралися скасувати, і є єдиним доступним варіантом відкату. Після цього завершіть решту робіт.
- Повторне використання того самого імені хоста у вашому
~/.ssh/configдля нового сервера спричиняєWARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!під час першого підключення, оскільки це ім’я тепер відповідає іншому ключу хоста. Видаліть застарілий запис за допомогоюssh-keygen -R example.com, лише коли точно з’ясуєте причину зміни, а не автоматично, оскільки саме таке попередження виникає під час атаки перехоплення. Міграція також є вдалим моментом, щоб перевірити, які ключі мають доступ до яких ресурсів. Саме для цього призначений матеріал Керування SSH-ключами в невеликому парку серверів. - Зробіть останній знімок або резервну копію старого сервера та збережіть її не в старого провайдера.
- Видаліть стару IP-адресу з перевірок моніторингу, записів SPF і списків дозволених адрес у сторонніх сервісах — саме в такому порядку та в останню чергу.
- Скасовуйте старий тарифний план лише після того, як переконаєтеся, що останню копію можна прочитати в іншому місці.
FAQ
Скільки часу займає міграція сервера на новий VPS?
Відмова в обслуговуванні, яку бачать користувачі, зазвичай охоплює фінальний дамп бази даних, фінальний прохід rsync і запуск сервісу. Для невеликого застосунку це зазвичай займає від десяти до тридцяти хвилин. Загальний час за календарем більший, оскільки DNS TTL потрібно зменшити щонайменше за один попередній період старого TTL до перемикання, а ще безпечніше — за добу. Масове копіювання даних також заплануйте завчасно, за кілька днів. Воно виконується на працюючому сервері, а повторний запуск передає лише дані, змінені після попереднього проходу.
Чи можна виконати rsync працюючої бази даних MySQL або PostgreSQL замість створення дампа?
Ні. rsync копіює файли по одному, тоді як база даних одночасно записує дані в кілька файлів. Тому копія містить сторінки з різних моментів часу та відповідає стану, якого база даних ніколи не мала. База може відмовитися запускатися або запуститися й пізніше завершити роботу з помилкою, коли запит звернеться до пошкодженої сторінки. Використовуйте pg_dump з pg_dumpall --globals-only або mysqldump --single-transaction, або спочатку зупиніть базу даних, а потім скопіюйте файли. Для великого кластера PostgreSQL pg_basebackup створює узгоджену фізичну копію працюючого сервера.
Як перевірити новий VPS до зміни DNS?
Перевизначте пошук імені на власному комп’ютері. Для одного запиту curl --resolve example.com:443:203.0.113.20 https://example.com/ спрямовує з’єднання на нову IP-адресу, але перевіряє сертифікат за справжнім ім’ям. Для тестування в браузері додайте 203.0.113.20 example.com до /etc/hosts на ноутбуці, перевірте вхід, читання з бази даних, запис через форму та завантаження файлу, а потім видаліть цей рядок. Щоб перевірити лише сертифікат, виконайте openssl s_client -connect 203.0.113.20:443 -servername example.com.
Який TTL потрібно встановити та коли його зменшити?
Зменште TTL записів A і AAAA до 300 секунд. Зробіть це щонайменше за один повний період старого TTL до перемикання. Резолвер, який кешував запис до вашої зміни, зберігатиме старе значення протягом решти старого TTL. Тому зменшення TTL за годину до перемикання нічого не дасть, якщо старий TTL становив 86400. Через кілька днів після міграції поверніть TTL до звичайного значення, коли журнал доступу старого сервера перестане містити запити.
Чи потрібно копіювати TLS-сертифікат або створити новий на новому сервері?
Можливі обидва варіанти. Копіювання /etc/letsencrypt/ збереже чинність сертифіката до наявної дати завершення, але на новому сервері потрібно встановити той самий плагін автентифікатора certbot. Інакше перше поновлення завершиться з помилкою. Після перемикання DNS виконайте certbot renew --dry-run, щоб це перевірити. Створення нового сертифіката є простішим варіантом, якщо можна використати перевірку DNS-01, оскільки вона підтверджує контроль через запис TXT і працює ще до того, як DNS почне вказувати на новий сервер. Перевірку HTTP-01 не можна використати на новому сервері, доки DNS не перемкнено, оскільки запит перевірки надійде на старий сервер.