नवीन VPS वर सर्व्हर स्थलांतर: सुरक्षित cutover मार्गदर्शक
नवीन VPS वर live server हलवताना inventory तयार करा, clone ऐवजी rebuild करा, database dump आणि दोन sync करा, DNS TTL आधी कमी करून तपासणीनंतर switch करा.
नवीन VPS वर सर्व्हरचे स्थलांतर पूर्वतयारी केलेल्या cutover प्रमाणे करा
सर्व्हरचे नवीन VPS वर स्थलांतर करताना ही प्रक्रिया केवळ कॉपी न मानता पूर्वतयारी केलेला cutover म्हणून करा. नवीन सर्व्हर सुरुवातीपासून तयार करा, डेटा दोनदा sync करा, DNS मध्ये बदल करण्यापूर्वी नवीन सर्व्हर त्याच्या स्वतःच्या IP पत्त्यावर स्वतंत्रपणे कार्यरत असल्याचे सिद्ध करा. त्यानंतर records बदला आणि खात्री होईपर्यंत जुना सर्व्हर सुरू ठेवा. bytes कॉपी करणे हा सोपा भाग आहे. प्रक्रिया कोणत्या क्रमाने करता यावर स्थलांतर सुरळीत होईल की खर्चिक ठरेल हे ठरते.
या मार्गदर्शिकेत web application, database आणि TLS (transport layer security) certificate चालवणाऱ्या एका Linux सर्व्हरचे वर्णन आहे. बहुतांश single-server सेटअपसाठी हे पुरेसे आहे. यात दोन hosts आहेत. त्यामुळे प्रत्येक उदाहरणातील comment मध्ये ते कोणत्या host वर चालवायचे आहे हे नमूद केले आहे. पत्ते documentation ranges मधून घेतले आहेत: 198.51.100.10 हा जुना सर्व्हर आहे आणि 203.0.113.20 हा नवीन सर्व्हर आहे.
सुरुवात करण्यापूर्वी संपूर्ण runbook वाचा. पहिली पायरी, DNS TTL कमी करणे, प्रत्यक्ष महत्त्वाच्या पायरीच्या अनेक दिवस आधी करावी लागते.
तुम्ही काहीही तयार करण्यापूर्वी इन्व्हेंटरी तयार करा
तुम्ही ज्याचे वर्णन केलेले नाही असा सर्व्हर पुन्हा तयार करू शकत नाही. जुन्या सर्व्हरवर नेमकी कोणती कामे होतात हे लिहून ठेवण्यासाठी एक तास द्या. कारण migration नंतर बिघडणारी गोष्ट बहुतेक वेळा अशीच असते जी कोणाच्याही लक्षात राहिलेली नसते: एखादे cron job, firewall exception किंवा application directoryच्या बाहेर ठेवलेली environment file.
जुन्या सर्व्हरवर हे commands चालवा आणि त्यांचे output नवीन सर्व्हरवरून वाचता येईल अशा ठिकाणी जतन करा.
# 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 ही यादी ठेवणे उपयुक्त आहे, कारण dependency म्हणून आलेल्या सर्व गोष्टी त्यातून समाविष्ट होतात. पाच वर्षे जुन्या सर्व्हरवर पूर्ण dpkg --get-selections चालवल्यास दोन हजार lines मिळतात आणि त्या package कशासाठी आहेत हे समजत नाही.
Scheduled काम दोन ठिकाणी असू शकते, त्यामुळे दोन्ही तपासा. महिन्यातून एकदाच चालणारे job migration नंतर सहा आठवड्यांनी सापडण्याची शक्यता असते.
# 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त्यानंतर सामान्य files नसलेल्या घटकांची तपासणी करा: firewall rules, certificates, databases आणि प्रत्यक्षात किती data हलवायचा आहे.
# 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 प्रत्येक certificateचे नाव, त्यात समाविष्ट असलेले domains, expiry date आणि diskवरील filesचे paths दाखवते. हे output तुमची TLS checklist आहे. du -x एकाच filesystemमध्ये मर्यादित राहते. त्यामुळे ते mounted backup volumeमध्ये जात नाही आणि प्रत्यक्ष आकारापेक्षा दहा पट मोठा आकडा दाखवत नाही.
दोन गोष्टी सर्व्हरच्या बाहेर असतात आणि प्रत्येक वेळी विसरल्या जातात. पहिली म्हणजे तुमच्या सर्व्हरच्या IP addressला allowlist करणारी कोणतीही third party: payment gateway, managed database, SMTP relay किंवा partner API. नवीन सर्व्हरला नवीन address मिळतो. त्यामुळे cutoverपूर्वी त्या allowlistमध्ये नवीन IP जोडा; cutoverनंतर नाही. दुसरी म्हणजे तुम्ही स्वतः तयार न केलेले DNS records, जसे MX record किंवा textमध्ये जुन्या IPचा उल्लेख करणारा SPF record.
जुनी root filesystem क्लोन करण्याऐवजी तुम्ही पुन्हा का तयार करता
संपूर्ण root filesystem नवीन VPS वर क्लोन करणे जलद वाटते आणि सुरुवातीला ते तसे असतेही. पण नंतर समस्या निर्माण होऊ शकतात. अनेक वर्षे production मध्ये असलेल्या root filesystem मध्ये दस्तऐवजीकरण न केलेली, हाताने बदललेली configuration, आता अस्तित्वात नसलेल्या repository मधील packages आणि जुन्या platform च्या virtual hardware साठी तयार केलेली boot setup असते. हे सर्व आयात केल्यावर migration करण्यामागील कारणही सोबत येते.
पहिल्या दिवशी rebuilding अधिक वेळ घेते; त्यानंतर दररोजचा खर्च कमी होतो. Current release install करा आणि base hardening लागू करा. त्यानंतर फक्त data कॉपी करा: application directory, site configs, database dump, certificates आणि user uploads. ज्याचे स्पष्टीकरण देता येत नाही ते नवीन सिस्टममध्ये आणू नका. नवीन मशीनची सुरुवात कोणत्याही मशीनप्रमाणे करा: नवीन VPS वरील पहिली दहा मिनिटे. त्यानंतर inventory मधून एकावेळी एक service जोडा. पुढची service जोडण्यापूर्वी प्रत्येक service कार्यरत असल्याची खात्री करा.
प्रतिमा किंवा snapshot restore कधी योग्य पर्याय ठरतो
सर्व्हर पुन्हा उभारणे योग्य नसण्याचा एक व्यवहार्य अपवाद आहे. जुना सर्व्हर boot होत नसेल किंवा अॅप्लिकेशनचा source पुन्हा build करता येत नसेल, तर provider image किंवा snapshot restore हा व्यवहार्य पर्याय ठरतो. मात्र त्याला वास्तविक मर्यादा आहेत. तो एका provider च्या वातावरणातच काम करतो आणि अनेकदा केवळ एका plan family मध्येच वापरता येतो, कारण restore केलेल्या disk ला त्या platform वरील virtual devices आणि network naming अपेक्षित असते.
चालू असलेल्या server च्या snapshot मध्ये live database ची file-level copy घेताना उद्भवणारीच consistency समस्या असते. Image restore कडे migration plan म्हणून नव्हे, तर recovery route म्हणून पाहा. त्यावर आधारित plan तयार करण्यापूर्वी snapshot हे backup सारखेच का नसते हे वाचा.
फाइल्स कशा हलतात: SSH वर rsync
जुन्या सर्व्हरवरून 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/Flags महत्त्वाचे आहेत. -a permissions, timestamps, symbolic links आणि ownership जतन करते. -H hard links स्वतंत्र प्रतींमध्ये विस्तारण्याऐवजी hard links म्हणूनच ठेवते. -A POSIX ACLs (access control lists) कॉपी करते आणि -X extended attributes कॉपी करते. हे शेवटचे दोन्ही flags वापरले नाहीत, तर दिसायला एकसारखी फाइल वेगळी वागू शकते. कारण SELinux labels आणि ACLs extended attributes मध्ये साठवलेले असतात आणि त्यांची नोंद इतर कोणत्याही घटकात राहत नाही.
या ठिकाणी बहुतेक failures दोन तपशीलांमुळे होतात.
शेवटचा slash डेटा कुठे जाईल हे ठरवतो. /srv/app/ म्हणजे त्या directory मधील contents. /srv/app म्हणजे ती directory स्वतः. हे चुकीचे केल्यास नवीन सर्व्हरवर /srv/app/app तयार होते. त्यानंतर application सुरू होते आणि missing files दाखवते, कारण configuration मधील paths आता एक स्तराने चुकीचे ठरतात.
sudo अंतर्गत tilde म्हणजे root ची home directory. sudo rsync मध्ये -e 'ssh -i ~/.ssh/id_ed25519' लिहिल्यास key तुमच्या स्वतःच्या home directory मध्ये नव्हे, तर /root/.ssh मध्ये शोधली जाते. Key तेथे नसल्यास SSH Permission denied (publickey) दाखवते आणि rsync rsync: connection unexpectedly closed दाखवून non-zero status सह बंद होते. Key path पूर्णपणे लिहा. Path दुरुस्त केल्यानंतरही authentication message दिसत राहिल्यास, publickey failure ची कारणे मर्यादित असतात; त्यानंतर नवीन सर्व्हरवरील directory permissions तपासा.
Ownership साठी एक निर्णय घ्यावा लागतो. root म्हणून चालवल्यावर rsync default नुसार owner आणि group यांचे mapping नावानुसार करते. त्यामुळे जुन्या सर्व्हरवर www-data च्या मालकीची फाइल नवीन सर्व्हरवर www-data च्या मालकीची होते, जरी numeric UID (user ID) वेगळा असला तरी. Rebuild साठी हेच अपेक्षित असते. ज्या filesystem मधील accounts target वर अस्तित्वात नाहीत तेथेच --numeric-ids जोडा. त्यानंतर ls -ln वापरून परिणाम तपासा. Matching account नसलेल्या UID च्या मालकीची फाइल फक्त bare number म्हणून दिसते आणि ती वाचणाऱ्या प्रत्येक service ला access नाकारला जातो.
Bulk pass काही दिवस आधी चालवा, त्या वेळी जुना सर्व्हर अजूनही traffic देत असू द्या. हे तुम्हाला हवे तितक्या वेळा पुन्हा चालवू शकता. rsync फक्त बदललेला डेटा पाठवते, त्यामुळे दुसऱ्या pass ला तासांऐवजी काही मिनिटे लागतात. Cutover window मधील अंतिम pass मध्ये --delete जोडा. त्यामुळे जुन्या सर्व्हरवर हटवलेल्या files नवीन सर्व्हरवरूनही हटवल्या जातात.
# 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 destination वरील, source मधून हटलेल्या files काढून टाकते. त्यामुळे चुकीचा source path आणि --delete यांचा एकत्र वापर केल्यास destination directory रिकामी होते. प्रत्येक वेळी प्रथम --dry-run सोबत चालवा. Laptop वरील SSH session बंद झाल्यास दीर्घ transfers देखील थांबतात. त्यामुळे ते जुन्या सर्व्हरवर tmux किंवा screen च्या आत सुरू करा. जुना सर्व्हर अजून users ना सेवा देत असताना copy मुळे link पूर्णपणे व्यापला जात असेल, तर --bwlimit=20M जोडा.
डेटाबेस कसा हलवायचा: native dump
डेटाबेस म्हणजे फाइल्सची directory नाही, जरी तो तसा दिसत असला तरी. तो फाइल्स, memory मधील state आणि write-ahead log यांचा संच असतो. डेटाबेस स्वतः निश्चित करतो त्या क्षणीच हा संच consistent असतो. त्यासाठी डेटाबेसचे स्वतःचे tool वापरा.
PostgreSQL साठी दोन dumps आवश्यक असतात, कारण roles संपूर्ण cluster साठी लागू असतात आणि 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.dumpglobals.sql वगळल्यास प्रत्येक table restore होईल; मात्र कोणताही application role ते वाचू शकणार नाही. याचे कारण GRANT statements अस्तित्वात नसलेल्या user कडे निर्देश करतात. -Fc custom archive format लिहिते. हे format फक्त pg_restore वाचते आणि नंतर निवडक tables restore करण्याची सुविधा देते. त्याच major version मध्ये किंवा त्याहून नवीन version मध्ये restore करा. उदाहरणार्थ, 17 वरून 16 कडे जाणे समर्थित नाही. pg_restore archive लिहिण्यापूर्वीच file header मधील unsupported-version error देऊन ते नाकारते.
MySQL आणि MariaDB एकाच command चा वापर करतात. त्यात default नसलेले चार options द्यावे लागतात:
# 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 writers ला block न करता consistent snapshot घेते; मात्र हे फक्त InnoDB tables साठी लागू आहे. त्याच database मधील MyISAM table अशा कोणत्याही हमीशिवाय copy केली जाते. त्यामुळे dump वर विश्वास ठेवण्यापूर्वी तुमचे storage engines तपासा. --routines, --triggers आणि --events default ने बंद असतात. त्यामुळे plain dump तुमचा data restore करतो, पण stored procedures आणि scheduled events मागे शांतपणे ठेवतो. Database users आणि त्यांचे grants mysql system database मध्ये असतात. --databases appdb dump या database ला कधीही स्पर्श करत नाही. त्यामुळे नवीन server वर CREATE USER आणि GRANT वापरून ते पुन्हा तयार करा. MariaDB 11 मध्ये हेच tool mariadb-dump म्हणून उपलब्ध आहे आणि mysqldump symbolic link म्हणून कायम ठेवले आहे. त्यामुळे August 2026 पर्यंत दोन्ही नावे चालतात.
SQLite ही single file असते. Application लिहित असताना ती copy केल्यास file torn अवस्थेत मिळते. त्यासाठी सुरक्षित पद्धत आहे:
# old server
sqlite3 /var/lib/app/app.db ".backup '/var/backups/app.db'"Engine कोणतेही असो, dump वर विश्वास ठेवण्यापूर्वी तो तपासा. Disk भरल्यामुळे मध्येच थांबलेला dump कोणतीही तक्रार न करता restore होईल; मात्र तो जिथे truncated झाला आहे तिथपर्यंतच.
# 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 शेवटच्या फाइलपर्यंत पोहोचेपर्यंत पहिली फाइल आधीच कालबाह्य झालेली असते. कॉपीमध्ये वेगवेगळ्या क्षणांतील pages असतात. डेटाबेसची अशी स्थिती कधीच अस्तित्वात नसते. परिणामी सर्व्हर सुरू होण्यास नकार देऊ शकतो. किंवा त्याहून वाईट स्थिती उद्भवू शकते: सर्व्हर सुरू होतो, आठवडाभर योग्य उत्तरे देतो आणि एखादी query खराब झालेल्या page पर्यंत पोहोचल्यावर अपयशी ठरतो. मध्ये कोणतीही चेतावणी मिळत नाही.
फाइल स्वतः हलवण्याचे दोन सुरक्षित मार्ग आहेत. डेटाबेस थांबवा, कॉपी करा आणि पुन्हा सुरू करा. हा मार्ग योग्य आणि सोपा आहे. मात्र कॉपी पूर्ण होण्यासाठी लागणाऱ्या वेळेइतका downtime सहन करावा लागतो. किंवा चालू सर्व्हरची physical copy तयार करण्यासाठी बनवलेले tool वापरा. PostgreSQL साठी हे pg_basebackup आहे. हे server सोबत समन्वय साधते, त्यामुळे कॉपी सुसंगत राहते:
# 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 attribute असलेली role आणि जुन्या server वरील जुळणारी pg_hba.conf entry आवश्यक असते. त्यामुळे dump च्या तुलनेत याची पूर्वतयारी अधिक असते. dump आणि restore तुमच्या उपलब्ध window मध्ये पूर्ण होत नसतील, तर हा मार्ग उपयुक्त ठरतो. सामान्य single-server migration साठी dump अधिक योग्य ठरतो.
कटओव्हरनंतर नव्हे, तर त्यापूर्वी प्रमाणपत्रे पुन्हा तयार करा
TLS प्रमाणपत्र domain name शी जोडलेले असते, IP address शी नाही. त्यामुळे प्रमाणपत्राची फाइल स्वतः हलवताना अडचण येत नाही. मात्र renewal सुरळीतपणे हलत नाही. Certbot चे default HTTP-01 challenge प्रमाणपत्र प्राधिकरणाला प्रमाणित केल्या जाणाऱ्या name वर port 80 द्वारे फाइल fetch करण्यास सांगते. DNS नवीन server कडे निर्देश करेपर्यंत ही fetch विनंती जुन्या server वर पोहोचते आणि नवीन server वरील renewal अयशस्वी होते.
पहिला पर्याय म्हणजे विद्यमान प्रमाणपत्रे आणि त्यांची renewal state कॉपी करणे. ती ज्या server वर ठेवली असतील, त्या server साठी त्यांच्या expiry date पर्यंत वैध राहतात.
# old server
sudo rsync -aHAX -e 'ssh -i /root/.ssh/id_ed25519' \
/etc/letsencrypt/ root@203.0.113.20:/etc/letsencrypt//etc/letsencrypt/renewal/ अंतर्गत असलेली प्रत्येक फाइल प्रमाणपत्र जारी करणाऱ्या authenticator plugin चे नाव दर्शवते. त्यामुळे नवीन server वर तोच plugin install करा (उदाहरणार्थ python3-certbot-nginx). अन्यथा unknown authenticator असा संदेश देऊन पहिले renewal अयशस्वी होईल. त्यावर अवलंबून राहण्यापूर्वी renewal कार्यरत आहे हे सिद्ध करा:
# new server, after DNS has moved
sudo certbot renew --dry-runदुसरा पर्याय म्हणजे नवीन server वर DNS-01 challenge वापरून नवीन प्रमाणपत्र जारी करणे. हा challenge TXT record द्वारे नियंत्रण सिद्ध करतो आणि port 80 ला कधीही स्पर्श करत नाही. Migration करण्यापूर्वीही हे कार्य करते, कारण त्या वेळी name अजूनही जुन्या server कडे resolve होत असते. त्यामुळे DNS provider चे automation करता येत असल्यास हा अधिक स्वच्छ पर्याय ठरतो. DNS-01 challenge वापरून प्रमाणपत्रे जारी करणे येथे plugin आणि credential setup चे वर्णन आहे.
दोन्हीपैकी कोणताही पर्याय निवडला तरी DNS बदलल्याशिवाय नवीन server प्रत्यक्षात काय सादर करतो ते तपासा:
# 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 (server name indication) पाठवते. यामुळे web server योग्य virtual host निवडतो. ते वगळल्यास त्या IP साठी default certificate मिळते आणि mismatch दिसतो. ही वास्तविक समस्या असल्यासारखी दिसते, पण ती प्रत्यक्षात समस्या नसते.
कटओव्हरच्या काही दिवस आधी DNS TTL कमी करा
काळजीपूर्वक केलेल्या migration मध्येही DNS मुळे अडचण येऊ शकते, कारण त्यामध्ये विलंब आधीपासूनच असतो आणि कटओव्हरच्या दिवशी तो कमी करता येत नाही. तुमचा A record cache केलेला resolver, त्याला दिलेल्या TTL (time to live) कालावधीपर्यंत तोच record पुरवत राहतो. दहा मिनिटांपूर्वी जुन्या मूल्यावर record cache केलेल्या resolver साठी आता TTL कमी केल्याने काहीही बदलत नाही: जुन्या TTL मधील उर्वरित कालावधीपर्यंत तो जुने मूल्य ठेवतो आणि त्यानंतरच नवीन, कमी TTL शिकतो. त्यामुळे कटओव्हरच्या किमान एका पूर्ण जुन्या TTL कालावधीपूर्वी TTL कमी करा. एक दिवस आधी करणे अधिक सुरक्षित पर्याय आहे. येथील प्रक्रिया नवीन असल्यास, records, resolvers आणि caching यांचे walkthrough ही पार्श्वभूमी माहिती वाचा.
खालील संख्या 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
}
]3600 seconds TTL सह प्रकाशित केलेला A record तुम्ही तो बदलल्यानंतर 60 minutes पर्यंत वापरकर्त्यांना जुन्या IP कडे पाठवत राहू शकतो. तो 300 seconds पर्यंत कमी केल्यास ही कमाल स्थिती 5 minutes पर्यंत कमी होते. हे आकडे हमी म्हणून नव्हे, तर किमान अपेक्षा म्हणून घ्या. काही resolvers स्वतःचा minimum TTL लागू करतात आणि त्यापेक्षा कमी मूल्य दुर्लक्षित करतात. काही application runtimes process सुरू असेपर्यंत resolved address cache करतात. त्यामुळे तुमच्या बदलापूर्वी सुरू झालेला client restart होईपर्यंत पुन्हा lookup करणारच असे नाही.
कमी केलेला TTL लागू झाला आहे का हे तपासताना स्वतःचा cache न पाहता authoritative answer वाचा:
# 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त्या answer line मधील दुसरे field seconds मधील TTL असते. त्यानंतर लोक सहसा विसरतात ते records तपासा: जुन्या server कडे IPv6 असल्यास AAAA record, स्वतंत्र A record असल्यास CNAME ऐवजी असलेले www name, स्वतः server कडे निर्देश करणारा कोणताही MX record, जुन्या IP ची नोंद असलेला SPF record आणि नवीन address वरील reverse DNS (PTR) record. Server mail पाठवत असल्यास cutover पूर्वी provider च्या control panel मधून PTR सेट करा. Receiving mail servers त्याची पडताळणी करतात आणि PTR नसल्यास इतर सर्व काही योग्य दिसल्यानंतर काही तासांनी mail reject होऊ शकतो.
नवीन सर्व्हरला DNS मध्ये बदल करण्यापूर्वी त्याच्या IP वर पडताळा
DNS अजूनही जुन्या सर्व्हरकडे निर्देश करत असताना तुम्ही नवीन सर्व्हरवर संपूर्ण अॅप्लिकेशनची चाचणी करू शकता. एका विनंतीसाठी name lookup override करा:
# 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 फक्त connection कुठे जाते ते बदलते. TLS certificate ची पडताळणी मात्र वास्तविक नावावरच केली जाते. त्यामुळे certificate आणि service दोन्ही योग्य असल्याचे यावरून सिद्ध होते. Chain ची पडताळणी झाल्यावर %{ssl_verify_result}, 0 दाखवते.
Browser मध्ये site वर क्लिक करून तपासणी करण्यासाठी, तुमच्या laptop वरील /etc/hosts मध्ये किंवा Windows वरील C:\Windows\System32\drivers\etc\hosts मध्ये एक ओळ जोडून संपूर्ण machine साठी name override करा:
203.0.113.20 example.com www.example.comत्यानंतर वापरकर्ता ज्या पद्धतीने अॅप्लिकेशन वापरेल त्याच पद्धतीने ते तपासा. Login करा. Database मधून data वाचणारे page उघडा. त्यात data लिहिणारा form submit करा. File upload करा आणि ती disk वर योग्य ठिकाणी साठवली गेली आहे याची खात्री करा. Email पाठवणारी प्रक्रिया सुरू करा आणि तो पोहोचला आहे का ते तपासा. नवीन IP वरून outbound SMTP मध्ये अनपेक्षित अडचण येणे सामान्य आहे. काम पूर्ण होताच hosts मधील ओळ काढून टाका. ती तशीच ठेवली तर इतर सर्वांना site व्यवस्थित दिसत असताना तुम्ही विनाकारण एक तास debugging करण्यात घालवू शकता.
कटओव्हर, टप्प्याटप्प्याने
- काही दिवस आधी: TTL कमी करा, मोठ्या प्रमाणावर
rsyncचालवा, नवीन सर्व्हर तयार करा आणिhostsoverride वापरून त्याची चाचणी करा. - कटओव्हरच्या दिवशी, विंडो सुरू होण्यापूर्वी: प्रत्येक third-party allowlist मध्ये नवीन IP जोडा आणि नवीन सर्व्हरचा backup job configure करून तो तुमच्या repository कडे निर्देशित केला आहे याची खात्री करा.
- विंडो सुरू करा: जुन्या सर्व्हरवरील अॅप्लिकेशन maintenance mode मध्ये ठेवा, जेणेकरून ते write स्वीकारणे थांबवेल.
- अंतिम database dump घ्या. त्यानंतर
--deleteसहrsyncची अंतिम फेरी चालवा. - नवीन सर्व्हरवर dump restore करा आणि सेवा सुरू करा.
--resolveआणिhostsoverride वापरून पुन्हा चाचणी करा. त्यात एक प्रत्यक्ष write देखील करा.- A आणि AAAA records नवीन IP वर बदला.
- दोन्ही सर्व्हर monitor करा. जुन्या सर्व्हरचा access log अजूनही तेथे येणारे clients दाखवतो. TTL संपेपर्यंत ही संख्या शून्याच्या दिशेने कमी झाली पाहिजे.
- maintenance page हटवा.
- जुना सर्व्हर किमान एक आठवडा सुरू आणि अपरिवर्तित ठेवा.
Maintenance mode चा टप्पा लोक अनेकदा वगळतात. पण तुमचे संरक्षण करणारा हाच टप्पा आहे. नवीन database ने एकदा write स्वीकारल्यानंतर rollback करण्यासाठी तो write गमवावा लागतो किंवा नवीन database चा dump घेऊन तो जुन्या database मध्ये पुन्हा load करावा लागतो. काही मिनिटांची read-only विंडो परवडणारी आहे. दोन्ही database मध्ये write झाले असतील, तर त्यांची manual reconciliation करण्यासाठी अनेक दिवस लागू शकतात.
रोलबॅक योजना
रोलबॅक ही एकच कृती आहे: DNS records परत 198.51.100.10 वर बदला. हे फक्त तुम्ही आधी केलेल्या चार गोष्टींमुळे शक्य होते.
- जुना सर्व्हर अजूनही चालू आहे, त्याच्या सेवा कार्यरत आहेत आणि त्याचा डेटा अखंड आहे. तुम्ही तेथे writes थांबवल्या; सर्व्हर decommission केला नाही.
- TTL अजूनही कमी आहे. त्यामुळे परत जाण्याचा मार्ग पुढे जाण्याइतकाच जलद आहे.
- जुना IP बदलून टाकण्याऐवजी तुम्ही नवीन IP third-party allowlists मध्ये added केला. जुना address काढल्यास payment gateway वरचा रोलबॅक मार्ग बंद होतो.
- नवीन सर्व्हरवर तुम्ही ओळखू शकत नाही अशा कोणत्याही writes झालेल्या नाहीत, कारण आतापर्यंतच्या एकमेव writes तुमच्या स्वतःच्या test transactions होत्या.
window सुरू होण्यापूर्वीच रोलबॅक कशामुळे करायचा हे ठरवा. दोन triggers पुरेसे आहेत: ठरवलेल्या मिनिटांच्या संख्येत निदान करता न आलेली कोणतीही error आणि कोणतीही data loss. हे आधीच लिहून ठेवले तर अंदाज बांधण्यात जाणारा एक तास टाळता येतो. त्यामुळे दहा मिनिटांचा outage दीर्घकाळ चालत नाही.
स्थलांतर यशस्वी झाले हे सिद्ध करा
साइट लोड झाली म्हणजे स्थलांतर पूर्ण झाले असे नाही. नंतरच अपयशी ठरणाऱ्या बाबी तपासा.
# 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 मध्ये अपेक्षित expiry dates दिसल्या पाहिजेत आणि list-timers मध्ये तुमच्या inventory मधील प्रत्येक scheduled job साठी रिक्त नसलेली वास्तविक next-run time दिसली पाहिजे.
त्यानंतर नवीन server एकदा जाणीवपूर्वक reboot करा आणि त्या वेळी त्याचे निरीक्षण करा. एखाद्याने हाताने सुरू केलेली पण enable न केलेली सेवा पहिल्या अनियोजित reboot पर्यंत, पहाटे तीन वाजेपर्यंत, व्यवस्थित चालू राहू शकते.
# new server
sudo reboot
# your laptop, once it comes back
curl -sS -o /dev/null -w '%{http_code}\n' https://example.com/अॅप्लिकेशन containers मध्ये चालत असल्यास हीच समस्या वेगळ्या स्वरूपात दिसते, कारण reboot नंतर परत सुरू होण्यासाठी compose stack मध्ये स्पष्ट restart policy आवश्यक असते.
शेवटची तपासणी पुढे ढकलणे सर्वात सोपे आणि महत्त्वाचीही आहे: backup job. backup नसलेल्या server वर स्थलांतर पूर्ण केल्यास एक धोका दुसऱ्या धोक्याने बदलला जातो. नवीन box वर backup हाताने चालवा आणि त्यातून एक file temporary directory मध्ये restore करा. प्रत्यक्ष restore करून तपासलेले restic repository आवश्यक वेळी उपयोगी पडते. जुना आणि नवीन server एक आठवडा एकाच वेळी चालवत असल्यास, प्रत्येक host पर्यंत पोहोचण्याची आणि तो configure करण्याची सुसंगत पद्धत दोन्ही live असताना त्यांच्यात configuration drift होऊ देत नाही.
कटओव्हरनंतर: जुना सर्व्हर आणि शेवटची कामे
जुना सर्व्हर एक ते दोन आठवडे ठेवून द्या. तुम्ही रद्द करणार असलेल्या प्लॅनचा एक महिन्याचा खर्च होईल; पण तुमच्याकडे उपलब्ध असलेला तोच एकमेव rollback पर्याय आहे. त्यानंतर उर्वरित कामे पूर्ण करा.
- नवीन मशीनसाठी तुमच्या
~/.ssh/configमध्ये तोच hostname पुन्हा वापरल्यास पहिल्या कनेक्शनवरWARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!दिसते, कारण त्या नावातून आता वेगळी host key मिळते. बदलाचे कारण स्पष्टपणे समजल्यानंतरssh-keygen -R example.comवापरून जुनी entry काढा. हे reflexively करू नका, कारण interception attack झाल्यासही हाच warning दिसतो. कोणत्या keys द्वारे कोणत्या सेवांपर्यंत पोहोचता येते, याचे पुनरावलोकन करण्यासाठी migration ही योग्य वेळ आहे. यासाठी लहान fleet मधील SSH key management उपयुक्त आहे. - जुन्या सर्व्हरचा एक अंतिम snapshot किंवा backup घ्या आणि तो जुन्या provider व्यतिरिक्त इतर ठिकाणी साठवा.
- monitoring checks, SPF records आणि third-party allowlists मधून जुना IP काढा. हा क्रम पाळा आणि हे काम सर्वांत शेवटी करा.
- अंतिम copy दुसऱ्या ठिकाणी वाचता येत असल्याची खात्री झाल्यानंतरच जुना plan रद्द करा.
FAQ
नवीन VPS वर सर्व्हर स्थलांतरित करण्यासाठी किती वेळ लागतो?
वापरकर्त्यांना दिसणारा सेवा-विराम सामान्यतः अंतिम database dump, अंतिम rsync pass आणि सेवा सुरू करण्यापुरता असतो. त्यामुळे लहान अॅप्लिकेशनसाठी तो साधारणपणे दहा ते तीस मिनिटांचा असतो. मात्र calendar time अधिक असतो, कारण switch करण्याच्या किमान एका जुन्या-TTL कालावधीआधी DNS TTL कमी करावा लागतो. एक दिवस आधी कमी करणे अधिक सुरक्षित असते. मोठ्या प्रमाणातील data copy ही काही दिवस आधी सुरू करण्याचे नियोजन करा. ती live server वर चालवता येते. नंतर ती पुन्हा चालवल्यास मागील pass नंतर बदललेला dataच transfer होतो.
चालू MySQL किंवा PostgreSQL database dump करण्याऐवजी rsync करता येईल का?
नाही. Database एकाच वेळी अनेक files मध्ये लिहित असताना rsync file by file copy करतो. त्यामुळे copy मध्ये वेगवेगळ्या क्षणांतील pages येतात आणि database मध्ये कधीही अस्तित्वात नसलेली state तयार होते. Database सुरू होण्यास नकार देऊ शकतो. किंवा तो सुरू होऊन query damaged page पर्यंत पोहोचल्यावर नंतर fail होऊ शकतो. pg_dump हे pg_dumpall --globals-only सह किंवा mysqldump --single-transaction वापरा. अन्यथा आधी database थांबवा आणि मग files copy करा. मोठ्या PostgreSQL cluster साठी चालू server ची consistent physical copy तयार करण्याचे काम pg_basebackup करते.
DNS बदलण्यापूर्वी नवीन VPS ची चाचणी कशी करावी?
तुमच्या स्वतःच्या machine वर name lookup override करा. एकाच request साठी curl --resolve example.com:443:203.0.113.20 https://example.com/ connection नवीन IP कडे पाठवते आणि certificate ची पडताळणी वास्तविक name विरुद्धच करते. Browser testing साठी तुमच्या laptop वरील /etc/hosts मध्ये 203.0.113.20 example.com जोडा. त्यानंतर login, database read, form write आणि file upload करून पाहा. मग ती line काढून टाका. फक्त certificate तपासण्यासाठी openssl s_client -connect 203.0.113.20:443 -servername example.com चालवा.
कोणता TTL सेट करावा आणि तो कधी कमी करावा?
A आणि AAAA records 300 seconds वर कमी करा. Cutover च्या किमान एका पूर्ण जुन्या-TTL कालावधीआधी हे करा. तुमच्या बदलापूर्वी record cache केलेला resolver जुन्या TTL च्या उर्वरित कालावधीसाठी जुनी value वापरतो. त्यामुळे जुना TTL 86400 असल्यास एक तास आधी TTL कमी करून काहीही साध्य होत नाही. Migration नंतर काही दिवसांनी, जुन्या server चा access log शांत झाल्यावर, TTL तुमच्या नेहमीच्या value वर परत वाढवा.
TLS certificate copy करावे का, की नवीन server वर नवीन certificate issue करावे?
दोन्ही पर्याय चालतात. /etc/letsencrypt/ copy केल्यास certificate त्याच्या विद्यमान expiry पर्यंत वैध राहते. मात्र नवीन server वर तोच certbot authenticator plugin install करावा लागतो. अन्यथा पहिला renewal fail होतो. त्यामुळे DNS switch केल्यानंतर खात्री करण्यासाठी certbot renew --dry-run चालवा. DNS-01 challenge वापरता येत असल्यास नवीन certificate issue करणे अधिक स्वच्छ पद्धत आहे. कारण ते TXT record द्वारे नियंत्रण सिद्ध करते आणि DNS नवीन server कडे निर्देशित होण्यापूर्वीही कार्य करते. DNS हलवलेले नसताना नवीन server वर HTTP-01 challenge वापरता येत नाही. Validation request जुन्या server कडे पोहोचेल.