Cara Migrasi Pelayan ke VPS Baharu dengan Selamat
Ketahui langkah migrasi pelayan ke VPS baharu menggunakan kaedah cutover yang dirancang. Panduan ini merangkumi proses inventori, binaan semula, pemindahan data dan DNS.
Migrasi pelayan ke VPS baharu sebagai cutover yang dirancang
Untuk memigrasikan pelayan ke VPS baharu, anggap proses pemindahan ini sebagai cutover yang dirancang dan bukannya sekadar salinan data. Bina pelayan baharu dari awal, segerakkan data sebanyak dua kali, dan pastikan pelayan baharu berfungsi dengan alamat IP sendiri sebelum anda menyentuh DNS. Kemudian, tukar rekod DNS dan biarkan pelayan lama terus berjalan sehingga anda benar-benar pasti. Menyalin bait data adalah bahagian yang mudah. Urutan operasi menentukan sama ada pemindahan tersebut berjalan lancar atau mendatangkan masalah.
Panduan ini meliputi satu pelayan Linux yang menjalankan aplikasi web, pangkalan data, dan sijil TLS (transport layer security). Ini merangkumi kebanyakan persediaan pelayan tunggal. Dua hos terlibat, jadi setiap contoh menyatakan dalam komen hos mana ia dijalankan. Alamat yang digunakan adalah daripada julat dokumentasi: 198.51.100.10 ialah pelayan lama, 203.0.113.20 ialah pelayan baharu.
Baca keseluruhan buku panduan ini sebelum anda bermula. Langkah pertama, iaitu mengurangkan TTL DNS, perlu dilakukan beberapa hari sebelum langkah yang anda sasarkan.
Buat inventori sebelum anda membina apa-apa
Anda tidak boleh membina semula pelayan yang tidak anda perincikan. Luangkan masa sejam untuk mencatat fungsi pelayan lama, kerana perkara yang rosak selepas migrasi selalunya adalah perkara yang dilupakan: cron job, pengecualian firewall, atau fail persekitaran yang terletak di luar direktori aplikasi.
Jalankan arahan ini pada pelayan lama dan simpan outputnya di tempat yang boleh anda akses daripada pelayan baharu.
# 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 ialah senarai yang berguna kerana ia membuang semua pakej yang dipasang sebagai dependency. dpkg --get-selections penuh pada pelayan berusia lima tahun akan menghasilkan dua ribu baris dan tidak memberikan maklumat tentang tujuan pemasangan tersebut.
Tugas berjadual tersembunyi di dua tempat, jadi periksa kedua-duanya. Tugas yang hanya berjalan secara bulanan adalah tugas yang akan anda temui enam minggu selepas migrasi.
# 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.hourlySeterusnya, bahagian yang bukan fail biasa: peraturan firewall, sijil, pangkalan data, dan jumlah data yang sebenarnya anda pindahkan.
# 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 mencetak setiap nama sijil, domain yang dilindunginya, tarikh luput, dan laluan fail pada cakera. Output tersebut ialah senarai semak TLS anda. du -x kekal pada satu sistem fail, jadi ia tidak akan masuk ke dalam volum sandaran yang dipasang (mounted) dan melaporkan saiz yang sepuluh kali ganda lebih besar.
Dua perkara berada di luar pelayan dan sering dilupakan setiap kali. Pertama, mana-mana pihak ketiga yang menyenaraikan putih (allowlist) alamat IP pelayan anda: get laluan pembayaran, pangkalan data terurus, relay SMTP, atau API rakan kongsi. Pelayan baharu mempunyai alamat baharu, jadi senarai putih tersebut perlu dikemas kini dengan IP baharu sebelum peralihan, bukan selepasnya. Kedua, rekod DNS yang tidak anda cipta sendiri, seperti rekod MX atau rekod SPF yang menamakan IP lama dalam teks.
Mengapa anda perlu membina semula dan bukannya mengklon sistem fail root lama
Mengklon keseluruhan sistem fail root ke VPS baharu kelihatan lebih pantas, dan memang begitu, sehingga masalah timbul. Sistem fail root yang telah digunakan dalam pengeluaran selama bertahun-tahun membawa konfigurasi yang disunting secara manual tanpa dokumentasi, pakej daripada repositori yang tidak lagi wujud, serta tetapan but yang dibina untuk perkakasan maya platform lama. Anda mengimport kesemuanya, termasuk punca mengapa anda perlu melakukan migrasi.
Membina semula memang lebih perlahan pada hari pertama tetapi lebih menjimatkan pada hari-hari seterusnya. Anda memasang release semasa, menggunakan hardening asas anda, kemudian menyalin data sahaja: direktori aplikasi, konfigurasi tapak, dump pangkalan data, sijil, dan muat naik pengguna. Apa-apa sahaja yang tidak dapat anda jelaskan tidak perlu dipindahkan. Mulakan pelayan baharu dengan cara anda memulakan mana-mana pelayan, dengan sepuluh minit pertama pada VPS baharu, kemudian tambah servis daripada inventori satu demi satu dan sahkan setiap satunya sebelum menambah yang seterusnya.
Apabila pemulihan imej atau snapshot adalah tindakan yang tepat
Terdapat satu pengecualian yang wajar bagi pembinaan semula. Jika pelayan lama tidak dapat but, atau aplikasi tersebut tidak lagi boleh dibina semula daripada kod sumber oleh sesiapa pun, pemulihan imej atau snapshot pembekal adalah jawapan yang pragmatik. Ia mempunyai had yang nyata: ia berfungsi dalam satu pembekal sahaja, dan sering kali hanya dalam satu keluarga pelan, kerana cakera yang dipulihkan menjangkakan peranti maya dan penamaan rangkaian platform tersebut.
Snapshot bagi pelayan yang sedang berjalan juga membawa masalah konsistensi yang sama seperti mana-mana salinan peringkat fail bagi pangkalan data yang aktif. Anggap pemulihan imej sebagai laluan pemulihan dan bukannya pelan migrasi, dan baca mengapa snapshot tidak sama dengan sandaran sebelum anda membina pelan berdasarkan perkara tersebut.
Cara fail dipindahkan: rsync melalui SSH
Jalankan rsync daripada pelayan lama, menolak data ke pelayan baharu. Menolak data biasanya lebih mudah, kerana pelayan lama sudah mempunyai data tersebut dan boleh membaca kesemuanya di bawah 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/Flag yang digunakan adalah penting. -a mengekalkan kebenaran (permissions), cap masa (timestamps), pautan simbolik (symbolic links) dan pemilikan. -H mengekalkan pautan keras (hard links) sebagai pautan keras dan bukannya mengembangkannya menjadi salinan berasingan. -A menyalin POSIX ACL (senarai kawalan akses) dan -X menyalin atribut lanjutan (extended attributes). Tanpa dua yang terakhir ini, fail yang kelihatan serupa boleh berkelakuan berbeza, kerana label SELinux dan ACL disimpan dalam atribut lanjutan dan tiada mekanisme lain yang merekodkannya.
Dua perincian menyebabkan kebanyakan kegagalan di sini.
Garis miring (trailing slash) menentukan lokasi data disimpan. /srv/app/ bermaksud kandungan direktori tersebut. /srv/app bermaksud direktori itu sendiri. Jika tersalah, anda akan berakhir dengan /srv/app/app pada pelayan baharu, dan aplikasi akan bermula tetapi melaporkan fail hilang, kerana laluan yang dikonfigurasikan kini berada satu tahap terlalu cetek.
Di bawah sudo, tilde adalah direktori utama root. Menulis -e 'ssh -i ~/.ssh/id_ed25519' di dalam sudo rsync akan mencari kunci dalam /root/.ssh, bukan dalam direktori utama anda sendiri. Jika kunci tiada di sana, SSH akan mencetak Permission denied (publickey), rsync mencetak rsync: connection unexpectedly closed dan keluar dengan status bukan sifar. Tulis laluan kunci secara penuh. Jika mesej pengesahan itu terus muncul selepas anda membetulkan laluan, kegagalan publickey mempunyai senarai punca yang ringkas dan kebenaran direktori pada pelayan baharu adalah perkara seterusnya yang perlu diperiksa.
Pemilikan memerlukan satu keputusan. Apabila dijalankan sebagai root, rsync memetakan pemilik dan kumpulan mengikut nama secara lalai, jadi fail yang dimiliki oleh www-data pada kotak lama akan dimiliki oleh www-data pada kotak baharu walaupun UID (ID pengguna) berangka berbeza. Itulah yang anda mahukan untuk pembinaan semula. Tambah --numeric-ids hanya apabila anda menyalin sistem fail yang akaunnya tidak wujud pada sasaran, kemudian periksa hasilnya dengan ls -ln, kerana fail yang dimiliki oleh UID tanpa akaun yang sepadan akan dipaparkan sebagai nombor sahaja dan setiap servis yang membacanya akan dinafikan akses.
Jalankan hantaran pukal beberapa hari lebih awal, sementara pelayan lama masih melayani trafik. Ulanginya sekerap yang anda mahu: rsync hanya menghantar apa yang berubah, jadi hantaran kedua hanya mengambil masa beberapa minit berbanding berjam-jam. Hantaran terakhir, di dalam tetingkap pertukaran (cutover window), tambah --delete supaya fail yang dialih keluar pada pelayan lama turut hilang pada pelayan baharu.
# 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 mengalih keluar fail pada destinasi yang sudah tiada pada sumber, jadi laluan sumber yang salah ditambah dengan --delete akan mengosongkan direktori destinasi. Jalankan ia dengan --dry-run terlebih dahulu, setiap kali. Pemindahan yang lama juga akan terhenti apabila sesi SSH komputer riba anda terputus, jadi mulakan ia di dalam tmux atau screen pada pelayan lama. Tambah --bwlimit=20M jika salinan tersebut memenuhkan pautan rangkaian sementara pelayan lama masih melayani pengguna.
Bagaimana pangkalan data dipindahkan: dump asli
Pangkalan data bukanlah direktori fail, walaupun ia kelihatan seperti satu. Ia merupakan set fail berserta keadaan dalam memori dan log tulis-dahulu (write-ahead log), yang hanya konsisten pada saat yang ditentukan oleh pangkalan data itu sendiri. Gunakan alatnya yang tersendiri.
PostgreSQL memerlukan dua dump, kerana peranan (roles) adalah merentas kluster dan pg_dump tidak menyertakannya:
# 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.dumpLangkau globals.sql dan anda akan mendapati setiap jadual dipulihkan tetapi tiada peranan aplikasi yang boleh membacanya, kerana pernyataan GRANT merujuk kepada pengguna yang tidak wujud. -Fc menulis format arkib tersuai, yang hanya boleh dibaca oleh pg_restore dan membolehkan anda memulihkan jadual terpilih kemudian. Pulihkan ke dalam versi utama yang sama atau yang lebih baharu. Pergerakan ke belakang, contohnya dari 17 ke 16, tidak disokong, dan pg_restore akan menolak arkib tersebut dengan ralat versi-tidak-disokong dalam pengepala fail sebelum ia menulis apa-apa.
MySQL dan MariaDB menggunakan satu arahan, dengan empat pilihan yang bukan tetapan lalai:
# 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 mengambil syot kilat (snapshot) yang konsisten tanpa menyekat penulis, tetapi hanya untuk jadual InnoDB. Jadual MyISAM dalam pangkalan data yang sama disalin tanpa jaminan sedemikian, jadi periksa enjin storan anda sebelum anda mempercayai dump tersebut. --routines, --triggers dan --events dimatikan secara lalai, yang bermaksud dump biasa akan memulihkan data anda tetapi secara senyap meninggalkan prosedur tersimpan dan acara berjadual anda. Pengguna pangkalan data dan pemberian hak mereka berada dalam pangkalan data sistem mysql, yang tidak pernah disentuh oleh dump --databases appdb, jadi cipta semula mereka pada pelayan baharu dengan CREATE USER dan GRANT. MariaDB 11 membekalkan alat yang sama seperti mariadb-dump dan mengekalkan mysqldump sebagai pautan simbolik, jadi kedua-dua nama berfungsi setakat Ogos 2026.
SQLite ialah fail tunggal, dan menyalinnya semasa aplikasi sedang menulis akan menghasilkan fail yang rosak (torn file). Ia mempunyai laluan selamatnya sendiri:
# old server
sqlite3 /var/lib/app/app.db ".backup '/var/backups/app.db'"Walau apa pun enjinnya, periksa dump tersebut sebelum anda mempercayainya. Dump yang terhenti awal kerana cakera penuh akan dipulihkan tanpa sebarang amaran, sehingga ke titik di mana ia terpotong.
# 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;'Mengapa anda tidak boleh menggunakan rsync pada pangkalan data yang sedang berjalan
rsync menyalin fail demi fail. Pangkalan data yang sedang berjalan menulis ke beberapa fail serentak, jadi apabila rsync sampai ke fail terakhir, fail pertama sudah pun ketinggalan zaman. Salinan tersebut mengandungi halaman daripada detik masa yang berbeza, iaitu keadaan yang tidak pernah wujud dalam pangkalan data tersebut. Hasilnya ialah pelayan yang enggan bermula, atau kes yang lebih buruk: pelayan yang berjaya bermula, memberikan jawapan yang betul selama seminggu, kemudian gagal apabila pertanyaan akhirnya sampai ke halaman yang rosak. Tiada amaran di antara tempoh tersebut.
Terdapat dua cara selamat untuk memindahkan fail tersebut. Hentikan pangkalan data, salin, kemudian mulakannya semula: cara ini betul, mudah, dan kosnya ialah tempoh masa henti sepanjang proses penyalinan. Atau gunakan alat yang dibina untuk salinan fizikal pelayan yang sedang berjalan. Bagi PostgreSQL, alat tersebut ialah pg_basebackup, yang menyelaraskan proses dengan pelayan supaya salinan tersebut konsisten:
# 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 -PCara ini memerlukan peranan dengan atribut REPLICATION dan entri pg_hba.conf yang sepadan pada pelayan lama, jadi ia memerlukan lebih banyak persediaan berbanding proses dump. Ia berbaloi apabila pangkalan data cukup besar sehingga proses dump dan restore tidak dapat diselesaikan dalam tempoh masa yang diperuntukkan. Untuk migrasi pelayan tunggal yang biasa, proses dump adalah pilihan yang lebih baik.
Bina semula sijil sebelum peralihan, bukan selepasnya
Sijil TLS terikat pada nama domain, bukan pada alamat IP, jadi fail sijil itu sendiri boleh dipindahkan tanpa masalah. Perkara yang tidak berpindah dengan lancar ialah pembaharuan. Cabaran HTTP-01 lalai Certbot meminta pihak berkuasa sijil mengambil fail melalui port 80 pada nama yang diperakui, dan selagi DNS tidak menghala ke pelayan baharu, pengambilan itu akan mendarat pada pelayan lama dan pembaharuan pelayan baharu akan gagal.
Pilihan pertama ialah menyalin sijil sedia ada dan status pembaharuannya. Sijil tersebut kekal sah sehingga tarikh luputnya, tidak kira pelayan mana yang menyimpannya.
# old server
sudo rsync -aHAX -e 'ssh -i /root/.ssh/id_ed25519' \
/etc/letsencrypt/ root@203.0.113.20:/etc/letsencrypt/Setiap fail di bawah /etc/letsencrypt/renewal/ menamakan pemalam pengesah yang mengeluarkan sijil tersebut, jadi pasang pemalam yang sama pada pelayan baharu (contohnya python3-certbot-nginx) atau pembaharuan pertama akan gagal dengan mesej mengenai pengesah yang tidak diketahui. Buktikan pembaharuan berfungsi sebelum anda bergantung padanya:
# new server, after DNS has moved
sudo certbot renew --dry-runPilihan kedua ialah mengeluarkan sijil baharu pada pelayan baharu menggunakan cabaran DNS-01, yang membuktikan kawalan melalui rekod TXT dan tidak menyentuh port 80 langsung. Ini berfungsi sebelum migrasi, semasa nama tersebut masih diselesaikan kepada pelayan lama, yang menjadikannya pilihan yang lebih bersih jika anda boleh mengautomasikan pembekal DNS anda. Mengeluarkan sijil dengan cabaran DNS-01 merangkumi persediaan pemalam dan kelayakan.
Walau apa pun caranya, semak apa yang sebenarnya dibentangkan oleh pelayan baharu, tanpa menukar 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 menghantar SNI (server name indication), iaitu perkara yang membuatkan pelayan web memilih hos maya yang betul. Jika ditinggalkan, anda akan mendapat sijil lalai untuk IP tersebut dan ketidakpadanan yang kelihatan seperti masalah sebenar sedangkan sebenarnya tidak.
Kurangkan TTL DNS beberapa hari sebelum peralihan
DNS merupakan bahagian di mana migrasi yang dirancang rapi masih boleh gagal, kerana kelewatan adalah terbina dalam dan anda tidak boleh memendekkannya pada hari kejadian. Resolver yang telah menyimpan cache rekod A anda akan terus menyajikannya sepanjang tempoh TTL (time to live) yang diberikan kepadanya. Mengurangkan TTL sekarang tidak memberi kesan kepada resolver yang telah menyimpan cache rekod tersebut sepuluh minit yang lalu pada nilai lama: ia akan memegang nilai lama tersebut sepanjang baki tempoh TTL lama, dan hanya selepas itu ia akan mempelajari nilai baharu yang lebih singkat. Oleh itu, kurangkan TTL sekurang-kurangnya satu tempoh TTL lama yang penuh sebelum peralihan. Sehari lebih awal adalah tempoh yang selesa. Jika perkara ini baharu bagi anda, panduan tentang rekod, resolver dan caching menyediakan latar belakang yang diperlukan.
Nombor di bawah adalah pengiraan aritmetik daripada TTL itu sendiri, bukan satu ukuran.
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
}
]Rekod A yang diterbitkan dengan TTL sebanyak 3600 saat boleh terus menghantar pengguna ke IP lama selama 60 minit selepas anda menukarnya. Kurangkannya kepada 300 saat dan kes terburuk itu akan jatuh kepada 5 minit. Anggap angka tersebut sebagai had minimum dan bukannya jaminan. Sesetengah resolver menggunakan TTL minimum mereka sendiri dan mengabaikan nilai yang lebih singkat, dan sesetengah runtime aplikasi menyimpan cache alamat yang telah diselesaikan sepanjang hayat proses tersebut, jadi klien yang bermula sebelum perubahan anda mungkin tidak akan menyemak semula sehingga ia dimulakan semula.
Baca jawapan autoritatif, bukan cache anda sendiri, apabila anda menyemak sama ada TTL yang lebih rendah telah aktif:
# 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 AMedan kedua pada baris jawapan tersebut ialah TTL dalam saat. Kemudian, selesaikan rekod yang sering dilupakan orang: rekod AAAA jika pelayan lama mempunyai IPv6, nama www apabila ia merupakan rekod A yang berasingan dan bukannya CNAME, sebarang rekod MX yang menghala ke pelayan itu sendiri, rekod SPF yang menyenaraikan IP lama, dan rekod DNS berbalik (PTR) pada alamat baharu. Tetapkan PTR melalui panel kawalan pembekal anda sebelum peralihan jika pelayan tersebut menghantar e-mel, kerana pelayan e-mel penerima akan menyemaknya dan PTR yang tiada akan menyebabkan e-mel ditolak beberapa jam selepas segala-galanya kelihatan baik.
Sahkan pelayan baharu pada IP-nya sebelum anda mengubah DNS
Anda boleh menguji keseluruhan aplikasi pada pelayan baharu sementara DNS masih menghala ke pelayan lama. Gantikan carian nama (name lookup) untuk satu permintaan:
# 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 hanya mengubah ke mana sambungan itu pergi. Sijil TLS masih disemak berdasarkan nama sebenar, jadi ini mengesahkan sijil serta servis tersebut. %{ssl_verify_result} akan mencetak 0 apabila rantaian tersebut disahkan.
Untuk melayari tapak tersebut melalui pelayar web, gantikan nama untuk keseluruhan mesin anda dengan menambah satu baris ke dalam /etc/hosts pada komputer riba anda, atau ke dalam C:\Windows\System32\drivers\etc\hosts pada Windows:
203.0.113.20 example.com www.example.comKemudian, gunakan aplikasi tersebut seperti yang dilakukan oleh pengguna. Log masuk. Muatkan halaman yang membaca daripada pangkalan data. Hantar borang yang menulis ke dalamnya. Muat naik fail dan sahkan ia sampai ke cakera. Cetuskan apa sahaja yang menghantar e-mel, dan semak sama ada ia sampai, kerana SMTP keluar daripada IP baharu sering kali menimbulkan masalah yang tidak dijangka. Buang baris hosts tersebut sebaik sahaja anda selesai. Membiarkannya di situ adalah punca anda menghabiskan masa selama sejam untuk menyahpepijat tapak yang boleh dilihat dengan sempurna oleh orang lain.
Langkah demi langkah peralihan
- Beberapa hari sebelumnya: rendahkan nilai TTL, jalankan rsync pukal, bina pelayan baharu dan ujinya di sebalik penggantian fail hosts.
- Pada hari kejadian, sebelum tetingkap penyelenggaraan: tambahkan IP baharu ke dalam setiap senarai putih pihak ketiga, dan sahkan tugasan sandaran pelayan baharu telah dikonfigurasikan serta dihalakan ke repositori anda.
- Buka tetingkap penyelenggaraan: letakkan aplikasi dalam mod penyelenggaraan pada pelayan lama supaya ia berhenti menerima penulisan data.
- Ambil dump pangkalan data terakhir, kemudian jalankan pas rsync terakhir dengan
--delete. - Pulihkan dump tersebut pada pelayan baharu dan mulakan servis.
- Uji sekali lagi melalui
--resolvedan penggantian fail hosts, termasuk satu penulisan data sebenar. - Tukar rekod A dan AAAA kepada IP baharu.
- Pantau kedua-dua pelayan. Log capaian pelayan lama menunjukkan siapa yang masih tiba di sana, dan jumlahnya sepatutnya menurun menghampiri sifar sepanjang tempoh TTL.
- Matikan halaman penyelenggaraan.
- Biarkan pelayan lama berjalan dan tidak disentuh selama sekurang-kurangnya seminggu.
Langkah mod penyelenggaraan adalah langkah yang sering dilangkau oleh orang ramai, sedangkan langkah inilah yang melindungi anda. Sebaik sahaja pangkalan data baharu telah menerima penulisan, proses rollback bermakna anda sama ada kehilangan penulisan tersebut atau perlu melakukan dump pangkalan data baharu dan memuatkannya semula ke dalam pangkalan data lama. Tetingkap baca-sahaja selama beberapa minit adalah kos yang rendah. Dua pangkalan data yang kedua-duanya telah menerima penulisan akan mengambil masa berhari-hari untuk diselaraskan secara manual.
Pelan rollback
Rollback ialah satu tindakan: tukar semula rekod DNS kepada 198.51.100.10. Ia hanya berfungsi disebabkan empat perkara yang anda lakukan sebelum ini.
- Pelayan lama masih berjalan dengan servisnya aktif dan data tidak terjejas. Anda hanya menghentikan penulisan di sana, anda tidak menyahaktifkannya.
- Nilai TTL masih rendah, jadi proses kembali semula adalah sepantas proses peralihan awal.
- Anda menambah IP baharu ke dalam senarai kebenaran (allowlist) pihak ketiga dan bukannya menggantikan IP lama. Jika anda membuang alamat lama, laluan rollback anda akan gagal di pintu masuk pembayaran (payment gateway).
- Pelayan baharu tidak menerima sebarang penulisan yang tidak dapat anda kenal pasti, kerana satu-satunya penulisan setakat ini hanyalah transaksi ujian anda sendiri.
Tentukan perkara yang mencetuskan rollback sebelum tetingkap masa bermula. Dua pencetus sudah memadai: sebarang ralat yang tidak dapat anda diagnosis dalam tempoh masa yang ditetapkan, dan sebarang kehilangan data. Menulisnya lebih awal adalah langkah yang menghalang tempoh sejam meneka yang boleh menukarkan gangguan sepuluh minit kepada gangguan yang berpanjangan.
Membuktikan migrasi telah berjaya
Migrasi tidak selesai hanya apabila laman web berjaya dimuatkan. Periksa perkara yang hanya akan gagal kemudian hari.
# new server
systemctl --failed
journalctl -p err -b --no-pager | tail -n 40
sudo certbot certificates
sudo systemctl list-timers --all --no-pagersystemctl --failed yang melaporkan 0 loaded units listed adalah hasil yang anda mahukan. certbot certificates sepatutnya menunjukkan tarikh luput yang anda jangkakan, dan list-timers sepatutnya menunjukkan setiap tugasan berjadual daripada inventori anda dengan masa larian seterusnya yang sebenar, bukannya kosong.
Kemudian, but semula pelayan baharu tersebut sekali, secara sengaja, semasa anda sedang memantau. Servis yang dimulakan secara manual oleh seseorang dan tidak pernah diaktifkan akan berfungsi dengan sempurna sehingga but semula yang tidak dirancang berlaku pada pukul tiga pagi.
# new server
sudo reboot
# your laptop, once it comes back
curl -sS -o /dev/null -w '%{http_code}\n' https://example.com/Jika aplikasi berjalan di dalam kontena, perangkap yang sama mempunyai bentuk yang berbeza, kerana stak compose memerlukan polisi mulakan semula yang eksplisit untuk kembali berfungsi selepas but semula.
Semakan terakhir adalah yang paling mudah untuk ditangguhkan namun paling penting: tugasan sandaran. Migrasi yang berakhir dengan pelayan tanpa sandaran hanya menukar satu risiko dengan risiko yang lain. Jalankan sandaran pada mesin baharu secara manual, kemudian pulihkan satu fail daripadanya ke dalam direktori sementara. Repositori restic dengan pemulihan yang telah anda uji secara sebenar adalah versi yang membantu apabila anda memerlukannya. Jika anda menjalankan pelayan lama dan baharu secara serentak selama seminggu, cara yang konsisten untuk mencapai dan mengkonfigurasi setiap hos akan menghalang kedua-duanya daripada menjadi tidak selari semasa kedua-duanya masih aktif.
Selepas peralihan: pelayan lama dan perkara terakhir
Kekalkan pelayan lama selama satu hingga dua minggu. Kosnya hanyalah satu bulan pelan yang anda bakal batalkan, dan ia merupakan satu-satunya cara untuk membuat rollback. Kemudian, selesaikan perkara yang selebihnya.
- Menggunakan semula hostname yang sama dalam
~/.ssh/configanda untuk mesin baharu akan memberikanWARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!pada sambungan pertama, kerana nama tersebut kini menjawab dengan host key yang berbeza. Kosongkan entri lama denganssh-keygen -R example.comsebaik sahaja anda pasti sebab ia berubah, dan jangan lakukannya secara refleks, kerana amaran yang sama adalah rupa serangan pintasan (interception attack). Migrasi juga merupakan masa yang sesuai untuk menyemak kunci mana yang boleh mencapai apa, iaitu tujuan bagi pengurusan kunci SSH pada kumpulan pelayan kecil. - Ambil satu snapshot atau sandaran terakhir pelayan lama, dan simpan ia di tempat yang bukan penyedia lama anda.
- Alih keluar IP lama daripada semakan pemantauan, daripada rekod SPF, dan daripada senarai kebenaran pihak ketiga, mengikut urutan tersebut dan sebagai langkah terakhir.
- Batalkan pelan lama hanya selepas salinan terakhir itu disahkan boleh dibaca di tempat lain.
FAQ
Berapa lamakah masa yang diambil untuk memindahkan pelayan ke VPS baharu?
Gangguan yang dapat dilihat oleh pengguna biasanya hanyalah semasa dump pangkalan data terakhir, proses rsync terakhir, dan permulaan servis, iaitu sekitar sepuluh hingga tiga puluh minit untuk aplikasi kecil. Masa kalendar adalah lebih lama kerana TTL DNS perlu diturunkan sekurang-kurangnya satu tempoh TTL lama sebelum pertukaran, dan sehari lebih awal adalah lebih selamat. Rancang penyalinan data pukal beberapa hari lebih awal juga. Ia dijalankan terhadap pelayan yang sedang aktif, dan mengulanginya kemudian hanya memindahkan data yang berubah sejak proses terakhir.
Bolehkah saya melakukan rsync pada pangkalan data MySQL atau PostgreSQL yang sedang berjalan dan bukannya melakukan dump?
Tidak. rsync menyalin fail demi fail manakala pangkalan data menulis ke beberapa fail serentak, jadi salinan tersebut mengandungi halaman daripada detik yang berbeza dan mewakili keadaan yang tidak pernah wujud dalam pangkalan data. Ia mungkin enggan bermula, atau bermula dan gagal kemudian apabila pertanyaan mencapai halaman yang rosak. Gunakan pg_dump dengan pg_dumpall --globals-only, atau mysqldump --single-transaction, atau hentikan pangkalan data terlebih dahulu sebelum menyalin fail. Untuk kluster PostgreSQL yang besar, pg_basebackup membuat salinan fizikal yang konsisten bagi pelayan yang sedang berjalan.
Bagaimanakah cara saya menguji VPS baharu sebelum menukar DNS?
Gantikan carian nama pada mesin anda sendiri. Untuk satu permintaan, curl --resolve example.com:443:203.0.113.20 https://example.com/ menghantar sambungan ke IP baharu sambil tetap menyemak sijil terhadap nama sebenar. Untuk ujian pelayar, tambahkan 203.0.113.20 example.com ke /etc/hosts pada komputer riba anda, lakukan log masuk, bacaan pangkalan data, penulisan borang, dan muat naik fail, kemudian alih keluar baris tersebut. Untuk memeriksa sijil sahaja, jalankan openssl s_client -connect 203.0.113.20:443 -servername example.com.
Berapakah nilai TTL yang perlu saya tetapkan, dan bilakah saya perlu menurunkannya?
Turunkan rekod A dan AAAA kepada 300 saat, dan lakukan sekurang-kurangnya satu tempoh TTL lama yang penuh sebelum pertukaran. Resolver yang menyimpan rekod dalam cache sebelum perubahan anda akan mengekalkan nilai lama sepanjang baki TTL lama tersebut, jadi menurunkannya sejam lebih awal tidak memberi kesan jika TTL lama adalah 86400. Naikkan semula kepada nilai biasa anda beberapa hari selepas migrasi, sebaik sahaja log akses pelayan lama menjadi senyap.
Patutkah saya menyalin sijil TLS atau mengeluarkan sijil baharu pada pelayan baharu?
Kedua-duanya boleh dilakukan. Menyalin /etc/letsencrypt/ mengekalkan sijil sah sehingga tarikh luput sedia ada, tetapi anda mesti memasang pemalam pengesah certbot yang sama pada pelayan baharu atau pembaharuan pertama akan gagal, jadi jalankan certbot renew --dry-run selepas pertukaran DNS untuk mengesahkannya. Mengeluarkan sijil baharu adalah lebih bersih apabila anda boleh menggunakan cabaran DNS-01, kerana ia membuktikan kawalan melalui rekod TXT dan berfungsi sebelum DNS menghala ke pelayan baharu. Cabaran HTTP-01 tidak boleh digunakan pada pelayan baharu sehingga DNS dialihkan, kerana permintaan pengesahan akan sampai ke pelayan lama.