วิธีย้ายเซิร์ฟเวอร์ไปยัง VPS ใหม่ให้ปลอดภัยและราบรื่น
เรียนรู้วิธีการย้ายเซิร์ฟเวอร์ไปยัง VPS ใหม่ด้วยเทคนิค Rehearsed Cutover ลดค่า DNS TTL ล่วงหน้า สร้างเซิร์ฟเวอร์ใหม่แทนการโคลน และตรวจสอบความพร้อมก่อนสลับ IP เพื่อลดความเสี่ยงของระบบ
การย้ายเซิร์ฟเวอร์ไปยัง VPS ใหม่ด้วยวิธี rehearsed cutover
ในการย้ายเซิร์ฟเวอร์ไปยัง VPS ใหม่ ให้ปฏิบัติเสมือนเป็นการทำ cutover ที่ผ่านการซ้อมมาแล้ว แทนการคัดลอกข้อมูลเพียงอย่างเดียว ให้สร้างเซิร์ฟเวอร์ใหม่ตั้งแต่ต้น ซิงค์ข้อมูลสองรอบ และตรวจสอบให้แน่ใจว่าเซิร์ฟเวอร์ใหม่ทำงานได้บน IP address ของตัวเองก่อนที่จะไปยุ่งกับ DNS จากนั้นจึงค่อยสลับระเบียน DNS และปล่อยให้เซิร์ฟเวอร์เก่าทำงานต่อไปจนกว่าคุณจะมั่นใจ การคัดลอกข้อมูลเป็นเพียงส่วนที่ง่าย ลำดับขั้นตอนการทำงานจะเป็นตัวกำหนดว่าการย้ายครั้งนี้จะราบรื่นหรือสร้างความเสียหาย
คู่มือนี้ครอบคลุมการย้ายเซิร์ฟเวอร์ Linux หนึ่งเครื่องที่รันเว็บแอปพลิเคชัน ฐานข้อมูล และใบรับรอง TLS (transport layer security) ซึ่งครอบคลุมการตั้งค่าเซิร์ฟเวอร์เดี่ยวส่วนใหญ่ ในการดำเนินการนี้จะเกี่ยวข้องกับโฮสต์สองเครื่อง ดังนั้นตัวอย่างทุกรายการจะมีหมายเหตุระบุว่าต้องรันบนโฮสต์ใด ที่อยู่ IP ที่ใช้มาจากช่วงที่กำหนดในเอกสาร: 198.51.100.10 คือเซิร์ฟเวอร์เก่า และ 203.0.113.20 คือเซิร์ฟเวอร์ใหม่
โปรดอ่านคู่มือการทำงานทั้งหมดก่อนเริ่มดำเนินการ ขั้นตอนแรกคือการลดค่า DNS TTL ซึ่งต้องทำล่วงหน้าหลายวันก่อนขั้นตอนที่คุณต้องการดำเนินการจริง
ทำรายการตรวจสอบก่อนเริ่มสร้างสิ่งใด
คุณไม่สามารถสร้างเซิร์ฟเวอร์ใหม่ได้หากไม่มีข้อมูลของเซิร์ฟเวอร์เดิม ให้ใช้เวลาหนึ่งชั่วโมงในการจดบันทึกว่าเครื่องเก่าทำหน้าที่อะไรบ้าง เพราะสิ่งที่มักจะพังหลังจากการย้ายระบบคือสิ่งที่คุณลืมไปแล้วเสมอ เช่น cron job, ข้อยกเว้นของ firewall หรือไฟล์ environment ที่วางอยู่นอกไดเรกทอรีของแอปพลิเคชัน
ให้รันคำสั่งเหล่านี้บนเซิร์ฟเวอร์เครื่องเก่าและเก็บผลลัพธ์ไว้ในที่ที่คุณสามารถเข้าถึงได้จากเครื่องใหม่
# 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 แบบเต็มบนเครื่องที่มีอายุห้าปีจะให้ผลลัพธ์ยาวถึงสองพันบรรทัด ซึ่งไม่ได้บอกอะไรเกี่ยวกับจุดประสงค์การใช้งานเลย
งานที่ตั้งเวลาไว้มักซ่อนอยู่ในสองที่ ดังนั้นให้ตรวจสอบทั้งสองแห่ง งานที่รันเพียงเดือนละครั้งคือสิ่งที่คุณจะค้นพบหลังจากย้ายระบบไปแล้วหกสัปดาห์
# 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, ใบรับรอง (certificates), ฐานข้อมูล และปริมาณข้อมูลที่คุณกำลังจะย้ายจริง
# 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 จะทำงานอยู่บนระบบไฟล์เดียว ดังนั้นมันจะไม่เข้าไปนับรวมใน volume สำรองข้อมูลที่ mount ไว้ ซึ่งจะทำให้ตัวเลขที่ได้สูงเกินจริงไปสิบเท่า
มีสองสิ่งที่อยู่นอกเซิร์ฟเวอร์และมักถูกลืมเสมอ อย่างแรกคือบุคคลที่สามใดๆ ที่อนุญาตให้ IP address ของเซิร์ฟเวอร์คุณเข้าถึงได้ (allowlist) เช่น payment gateway, ฐานข้อมูลที่มีผู้ดูแลให้, SMTP relay หรือ partner API เครื่องใหม่จะมีที่อยู่ใหม่ ดังนั้นรายการ allowlist เหล่านั้นจำเป็นต้องเพิ่ม IP ใหม่เข้าไปก่อนการสลับระบบ ไม่ใช่หลังจากนั้น อย่างที่สองคือระเบียน DNS ที่คุณไม่ได้สร้างขึ้นเอง เช่น ระเบียน MX หรือระเบียน SPF ที่ระบุ IP เก่าไว้ในข้อความ (text)
เหตุผลที่ควรสร้างใหม่แทนการโคลน root filesystem เดิม
การโคลน root filesystem ทั้งหมดไปยัง VPS ใหม่ดูเหมือนจะรวดเร็วกว่า และก็เป็นเช่นนั้นจริงจนกระทั่งเกิดปัญหาขึ้น root filesystem ที่ผ่านการใช้งานจริงมานานหลายปีมักมีไฟล์คอนฟิกที่ถูกแก้ไขด้วยมือโดยไม่มีการจดบันทึก มีแพ็กเกจจาก repository ที่ไม่มีอยู่แล้ว และมีการตั้งค่าการบูตที่สร้างมาเพื่อฮาร์ดแวร์เสมือนของแพลตฟอร์มเก่า เมื่อคุณย้ายข้อมูลทั้งหมดมา คุณก็นำปัญหาที่เป็นสาเหตุให้คุณต้องย้ายระบบติดมาด้วย
การสร้างระบบใหม่ใช้เวลานานกว่าในวันแรก แต่จะประหยัดเวลาและค่าใช้จ่ายได้มากกว่าในระยะยาว คุณควรติดตั้ง release ปัจจุบัน ใช้การตั้งค่าความปลอดภัยพื้นฐาน (base hardening) แล้วจึงคัดลอกเฉพาะข้อมูลที่จำเป็นเท่านั้น ได้แก่ ไดเรกทอรีแอปพลิเคชัน, ไฟล์คอนฟิกของเว็บไซต์, ไฟล์ดัมพ์ฐานข้อมูล, ใบรับรอง (certificates) และไฟล์ที่ผู้ใช้อัปโหลด สิ่งใดที่คุณอธิบายไม่ได้ว่าคืออะไร ไม่ควรถูกนำมาด้วย ให้เริ่มต้นเซิร์ฟเวอร์ใหม่ด้วยวิธีเดียวกับที่คุณเริ่มต้นเซิร์ฟเวอร์ทุกเครื่อง โดยดูที่ สิบนาทีแรกบน VPS ใหม่ จากนั้นจึงเพิ่มบริการต่างๆ จากรายการที่คุณมีทีละรายการ และตรวจสอบความถูกต้องของแต่ละบริการก่อนที่จะเพิ่มบริการถัดไป
เมื่อการกู้คืนจากอิมเมจหรือสแนปชอตเป็นทางเลือกที่เหมาะสม
มีข้อยกเว้นเพียงประการเดียวที่การกู้คืนจากอิมเมจหรือสแนปชอตเป็นทางเลือกที่สมเหตุสมผล นั่นคือกรณีที่เซิร์ฟเวอร์เดิมไม่สามารถบูตได้ หรือแอปพลิเคชันนั้นไม่มีใครสามารถสร้างขึ้นใหม่จากซอร์สโค้ดได้อีกต่อไป อย่างไรก็ตาม วิธีนี้มีข้อจำกัดที่ชัดเจน คือสามารถใช้งานได้ภายในผู้ให้บริการรายเดียวกัน และมักจำกัดอยู่ภายในตระกูลของแผนบริการเดียวกันเท่านั้น เนื่องจากดิสก์ที่กู้คืนมาจะคาดหวังการทำงานร่วมกับอุปกรณ์เสมือนและชื่อเครือข่ายของแพลตฟอร์มนั้นๆ
การทำสแนปชอตของเซิร์ฟเวอร์ที่กำลังทำงานอยู่ยังคงประสบปัญหาเรื่องความสอดคล้องของข้อมูลเช่นเดียวกับการคัดลอกไฟล์ของฐานข้อมูลที่กำลังเปิดใช้งานอยู่ทั่วไป ควรพิจารณาการกู้คืนจากอิมเมจเป็นเพียงเส้นทางสำหรับการกู้คืนระบบเท่านั้น ไม่ใช่แผนสำหรับการย้ายระบบ และโปรดอ่าน เหตุใดสแนปชอตจึงไม่ใช่สิ่งเดียวกับการสำรองข้อมูล ก่อนที่คุณจะวางแผนงานโดยอ้างอิงจากสแนปชอต
การย้ายไฟล์: rsync ผ่าน SSH
รัน rsync จากเซิร์ฟเวอร์เครื่องเก่าเพื่อส่งข้อมูลไปยังเครื่องใหม่ การส่งข้อมูล (push) มักทำได้ง่ายกว่า เพราะเซิร์ฟเวอร์เครื่องเก่ามีข้อมูลอยู่แล้วและสามารถอ่านข้อมูลทั้งหมดได้ภายใต้สิทธิ์ 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 มีความสำคัญ -a จะรักษา permission, timestamp, symbolic link และความเป็นเจ้าของไฟล์ไว้ -H จะคงสถานะ hard link ไว้ตามเดิมแทนที่จะคัดลอกเป็นไฟล์แยกกัน -A จะคัดลอก POSIX ACL (access control lists) และ -X จะคัดลอก extended attributes หากขาดสองอย่างหลังนี้ ไฟล์ที่ดูเหมือนกันอาจทำงานต่างกันได้ เนื่องจาก SELinux label และ ACL ถูกเก็บไว้ใน extended attributes ซึ่งไม่มีกลไกอื่นบันทึกไว้
รายละเอียดสองประการมักเป็นสาเหตุของความล้มเหลวส่วนใหญ่
เครื่องหมาย slash ปิดท้ายเป็นตัวกำหนดตำแหน่งปลายทางของข้อมูล /srv/app/ หมายถึงเนื้อหาภายในไดเรกทอรีนั้น ส่วน /srv/app หมายถึงตัวไดเรกทอรีเอง หากระบุผิด คุณอาจได้ /srv/app/app บนเซิร์ฟเวอร์เครื่องใหม่ ส่งผลให้แอปพลิเคชันเริ่มทำงานแล้วแจ้งเตือนว่าหาไฟล์ไม่พบ เนื่องจาก path ที่ตั้งค่าไว้ตื้นกว่าความเป็นจริงหนึ่งระดับ
ภายใต้ sudo เครื่องหมาย tilde คือโฮมไดเรกทอรีของ root การเขียน -e 'ssh -i ~/.ssh/id_ed25519' ภายใน sudo rsync จะทำให้ระบบมองหาคีย์ใน /root/.ssh ไม่ใช่ในโฮมไดเรกทอรีของคุณ หากไม่มีคีย์อยู่ที่นั่น SSH จะแสดง Permission denied (publickey) และ rsync จะแสดง rsync: connection unexpectedly closed ก่อนจะจบการทำงานด้วยสถานะ non-zero ให้ระบุ path ของคีย์แบบเต็มเสมอ หากข้อความยืนยันตัวตนยังคงปรากฏหลังจากแก้ไข path แล้ว สาเหตุของความล้มเหลวในการใช้ publickey มีรายการที่ต้องตรวจสอบสั้นๆ และสิ่งถัดไปที่ต้องตรวจคือ permission ของไดเรกทอรีบนเซิร์ฟเวอร์เครื่องใหม่
เรื่องความเป็นเจ้าของไฟล์ต้องมีการตัดสินใจ ในการรันด้วยสิทธิ์ root โดยปกติ rsync จะจับคู่เจ้าของและกลุ่มตาม ชื่อ ดังนั้นไฟล์ที่เจ้าของเป็น www-data บนเครื่องเก่าจะกลายเป็นของ www-data บนเครื่องใหม่ แม้ว่าค่า UID (user ID) แบบตัวเลขจะต่างกันก็ตาม ซึ่งเป็นสิ่งที่คุณต้องการสำหรับการสร้างระบบใหม่ ให้เพิ่ม --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 จะลบไฟล์บนปลายทางที่ไม่มีอยู่บนต้นทาง ดังนั้นการระบุ path ต้นทางผิดร่วมกับ --delete จะทำให้ไดเรกทอรีปลายทางว่างเปล่า ให้รันด้วย --dry-run ก่อนทุกครั้ง การโอนย้ายไฟล์ขนาดใหญ่อาจหยุดชะงักเมื่อเซสชัน SSH บนแล็ปท็อปของคุณหลุด ดังนั้นควรเริ่มการทำงานภายใน tmux หรือ screen บนเซิร์ฟเวอร์เครื่องเก่า และเพิ่ม --bwlimit=20M หากการคัดลอกใช้แบนด์วิดท์จนเต็มในขณะที่เซิร์ฟเวอร์เครื่องเก่ายังคงให้บริการผู้ใช้งานอยู่
วิธีการย้ายฐานข้อมูล: การทำ dump แบบเนทีฟ
ฐานข้อมูลไม่ใช่แค่ไดเรกทอรีของไฟล์ แม้ว่ามันจะดูเหมือนเป็นเช่นนั้นก็ตาม มันคือชุดของไฟล์รวมกับสถานะในหน่วยความจำและ write-ahead log ซึ่งจะมีความสอดคล้องกันเฉพาะในช่วงเวลาที่ฐานข้อมูลกำหนดไว้เท่านั้น ดังนั้นควรใช้เครื่องมือของตัวฐานข้อมูลเอง
PostgreSQL ต้องการการทำ dump สองส่วน เพราะ role เป็นระดับคลัสเตอร์และ 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 ไป คุณจะกู้คืนตารางได้ครบทุกตาราง แต่ไม่มี role ของแอปพลิเคชันใดที่สามารถอ่านข้อมูลได้ เพราะคำสั่ง GRANT อ้างอิงถึงผู้ใช้ที่ไม่มีอยู่จริง -Fc จะเขียนไฟล์ในรูปแบบ custom archive ซึ่งมีเพียง pg_restore เท่านั้นที่อ่านได้ และช่วยให้คุณเลือกกู้คืนเฉพาะบางตารางในภายหลังได้ การกู้คืนต้องทำในเวอร์ชันหลักเดียวกันหรือเวอร์ชันที่ใหม่กว่า การย้อนกลับเวอร์ชัน เช่น จาก 17 ไป 16 ไม่ได้รับการรองรับ และ pg_restore จะปฏิเสธไฟล์ archive นั้นด้วยข้อผิดพลาด unsupported-version ในส่วน header ของไฟล์ก่อนที่จะเริ่มเขียนข้อมูลใดๆ
MySQL และ MariaDB ใช้คำสั่งเดียวพร้อมตัวเลือก 4 รายการที่ไม่ได้เปิดใช้งานเป็นค่าเริ่มต้น:
# 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 จะทำการ snapshot ข้อมูลอย่างสอดคล้องกันโดยไม่บล็อกการเขียน แต่ใช้ได้เฉพาะกับตารางที่เป็น InnoDB เท่านั้น ตารางที่เป็น MyISAM ในฐานข้อมูลเดียวกันจะถูกคัดลอกโดยไม่มีการรับประกันความสอดคล้อง ดังนั้นควรตรวจสอบ storage engine ของคุณก่อนที่จะเชื่อถือไฟล์ dump นั้น --routines, --triggers และ --events ไม่ได้ถูกเปิดใช้งานเป็นค่าเริ่มต้น ซึ่งหมายความว่าการ dump แบบปกติจะกู้คืนข้อมูลของคุณ แต่จะละเลย stored procedures และ scheduled events ไปโดยไม่แจ้งเตือน ผู้ใช้ฐานข้อมูลและสิทธิ์การเข้าถึงจะอยู่ในฐานข้อมูลระบบ mysql ซึ่งการทำ --databases appdb dump จะไม่เข้าไปยุ่งเกี่ยว ดังนั้นคุณต้องสร้างผู้ใช้และสิทธิ์เหล่านั้นใหม่บนเซิร์ฟเวอร์ปลายทางด้วย CREATE USER และ GRANT สำหรับ MariaDB 11 จะใช้เครื่องมือเดียวกับ mariadb-dump และยังคง mysqldump ไว้เป็น symbolic link ดังนั้นไม่ว่าจะใช้ชื่อไหนก็ใช้งานได้เหมือนกัน ณ เดือนสิงหาคม 2026
SQLite เป็นไฟล์เดียว การคัดลอกไฟล์ในขณะที่แอปพลิเคชันกำลังเขียนข้อมูลจะทำให้ไฟล์เสียหาย (torn file) มันมีวิธีการที่ปลอดภัยเฉพาะตัวดังนี้:
# old server
sqlite3 /var/lib/app/app.db ".backup '/var/backups/app.db'"ไม่ว่าจะเป็น engine ใด ให้ตรวจสอบไฟล์ dump ก่อนที่จะเชื่อถือมัน ไฟล์ dump ที่หยุดทำงานกลางคันเนื่องจากดิสก์เต็มจะถูกกู้คืนโดยไม่มีข้อความแจ้งเตือนใดๆ จนกระทั่งถึงจุดที่ไฟล์ถูกตัดทอนข้อมูลออกไป
# 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 คัดลอกไปถึงไฟล์สุดท้าย ข้อมูลในไฟล์แรกก็จะไม่อัปเดตแล้ว การคัดลอกดังกล่าวจึงเก็บข้อมูลจากช่วงเวลาที่ต่างกัน ซึ่งเป็นสถานะที่ฐานข้อมูลไม่เคยเกิดขึ้นจริง ผลลัพธ์ที่ได้คือเซิร์ฟเวอร์อาจปฏิเสธที่จะเริ่มทำงาน หรือในกรณีที่เลวร้ายกว่านั้นคือ เซิร์ฟเวอร์เริ่มทำงานได้ ให้คำตอบที่ถูกต้องเป็นเวลาหนึ่งสัปดาห์ แล้วจึงล้มเหลวเมื่อมีการเรียกใช้คำสั่ง query ไปถึงหน้าข้อมูลที่เสียหาย โดยไม่มีการแจ้งเตือนใดๆ ในระหว่างนั้น
มีวิธีที่ปลอดภัยสองวิธีในการย้ายไฟล์ฐานข้อมูล วิธีแรกคือหยุดการทำงานของฐานข้อมูล คัดลอกไฟล์ แล้วจึงเริ่มการทำงานใหม่ วิธีนี้ถูกต้อง เรียบง่าย และทำให้เกิด downtime ตามระยะเวลาที่ใช้ในการคัดลอก หรือวิธีที่สองคือการใช้เครื่องมือที่สร้างมาเพื่อคัดลอกข้อมูลทางกายภาพ (physical copy) จากเซิร์ฟเวอร์ที่กำลังทำงานอยู่ สำหรับ 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วิธีนี้จำเป็นต้องมี role ที่มีสิทธิ์ REPLICATION และต้องมีการตั้งค่า pg_hba.conf ที่ตรงกันบนเซิร์ฟเวอร์เครื่องเก่า จึงต้องมีการตั้งค่ามากกว่าการทำ dump ข้อมูล วิธีนี้คุ้มค่าเมื่อฐานข้อมูลมีขนาดใหญ่จนการทำ dump และ restore ไม่สามารถทำได้ภายในช่วงเวลาที่กำหนด สำหรับการย้ายเซิร์ฟเวอร์เดี่ยวทั่วไป การทำ dump ยังคงเป็นวิธีที่ดีกว่า
สร้างใบรับรองใหม่ก่อนการย้ายระบบ ไม่ใช่หลังจากนั้น
TLS certificate ผูกกับชื่อโดเมน ไม่ใช่ที่อยู่ IP ดังนั้นไฟล์ใบรับรองจึงสามารถย้ายไปมาได้โดยไม่มีปัญหา สิ่งที่ย้ายไม่ราบรื่นคือการต่ออายุ (renewal) การตรวจสอบแบบ HTTP-01 challenge ตามค่าเริ่มต้นของ Certbot จะร้องขอให้ผู้ออกใบรับรอง (Certificate Authority) ดึงไฟล์ผ่านพอร์ต 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/ จะระบุชื่อ authenticator plugin ที่ออกใบรับรองนั้น ดังนั้นต้องติดตั้ง plugin ตัวเดียวกันบนเซิร์ฟเวอร์ใหม่ (เช่น python3-certbot-nginx) มิฉะนั้นการต่ออายุครั้งแรกจะล้มเหลวพร้อมข้อความแจ้งเตือนเกี่ยวกับ authenticator ที่ไม่รู้จัก ให้ทดสอบว่าการต่ออายุทำงานได้จริงก่อนที่จะใช้งานจริง:
# new server, after DNS has moved
sudo certbot renew --dry-runทางเลือกที่สองคือการออกใบรับรองใหม่บนเซิร์ฟเวอร์ใหม่โดยใช้ DNS-01 challenge ซึ่งเป็นการพิสูจน์สิทธิ์ผ่าน TXT record โดยไม่ต้องผ่านพอร์ต 80 เลย วิธีนี้สามารถทำได้ก่อนการย้ายระบบ ในขณะที่ชื่อโดเมนยังคงชี้ไปที่เซิร์ฟเวอร์เก่าอยู่ จึงเป็นทางเลือกที่สะอาดกว่าหากคุณสามารถทำระบบอัตโนมัติกับผู้ให้บริการ DNS ของคุณได้ การออกใบรับรองด้วย DNS-01 challenge ครอบคลุมถึงการตั้งค่า plugin และ credential
ไม่ว่าจะเลือกวิธีใด ให้ตรวจสอบสิ่งที่เซิร์ฟเวอร์ใหม่แสดงผลจริง โดยไม่ต้องเปลี่ยนค่า 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 (server name indication) ซึ่งเป็นสิ่งที่ทำให้เว็บเซิร์ฟเวอร์เลือก virtual host ได้ถูกต้อง หากไม่ใส่ค่านี้ คุณจะได้รับใบรับรองเริ่มต้นสำหรับ IP นั้น ซึ่งอาจดูเหมือนเป็นปัญหาจริงทั้งที่ความจริงแล้วไม่ใช่
ลดค่า DNS TTL ล่วงหน้าหลายวันก่อนการย้ายระบบ
DNS เป็นจุดที่การย้ายระบบที่วางแผนมาอย่างดีมักจะเกิดข้อผิดพลาด เนื่องจากมีความหน่วงแฝงอยู่ภายในระบบซึ่งคุณไม่สามารถลดเวลาลงได้ในวันที่ย้ายจริง Resolver ที่แคช A record ของคุณไว้จะยังคงส่งค่าเดิมต่อไปจนกว่าจะครบระยะเวลา TTL (time to live) ที่ได้รับมา การลดค่า TTL ในตอนนี้ไม่มีผลกับ Resolver ที่แคชเรคคอร์ดไว้เมื่อสิบนาทีก่อนด้วยค่าเดิม มันจะยังคงเก็บค่าเก่าไว้จนกว่าจะครบ TTL เดิม แล้วจึงจะเรียนรู้ค่าใหม่ที่สั้นลง ดังนั้นควรลดค่า TTL ล่วงหน้าอย่างน้อยหนึ่งรอบระยะเวลาของ TTL เดิมก่อนการย้ายระบบ การทำล่วงหน้าหนึ่งวันเป็นระยะเวลาที่ปลอดภัย หากคุณยังไม่คุ้นเคยกับกลไกเหล่านี้ คำอธิบายเกี่ยวกับเรคคอร์ด, Resolver และการแคช จะช่วยให้คุณเข้าใจพื้นฐานได้
ตัวเลขด้านล่างนี้เป็นการคำนวณทางคณิตศาสตร์จากค่า 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
}
]A record ที่ประกาศด้วยค่า TTL 3600 วินาที อาจส่งผู้ใช้งานไปยัง IP เดิมต่อไปได้นานถึง 60 นาทีหลังจากที่คุณเปลี่ยนแปลงค่า หากลดลงเหลือ 300 วินาที กรณีที่เลวร้ายที่สุดจะลดลงเหลือ 5 นาที ให้ถือว่าตัวเลขเหล่านี้เป็นค่าต่ำสุดที่เป็นไปได้ไม่ใช่การรับประกัน Resolver บางตัวอาจกำหนดค่า TTL ขั้นต่ำของตนเองและเพิกเฉยต่อค่าที่สั้นกว่านั้น นอกจากนี้ Runtime ของแอปพลิเคชันบางตัวยังแคชที่อยู่ IP ไว้ตลอดอายุการทำงานของ Process ดังนั้นไคลเอนต์ที่เริ่มทำงานก่อนการเปลี่ยนแปลงของคุณอาจไม่ตรวจสอบค่าใหม่อีกเลยจนกว่าจะรีสตาร์ท
ให้ตรวจสอบคำตอบจาก Authoritative Name Server โดยตรงแทนการดูจากแคชของคุณเอง เพื่อยืนยันว่าค่า TTL ที่ลดลงมีผลใช้งานแล้ว:
# 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 record หากเซิร์ฟเวอร์เดิมมี IPv6, ชื่อ www เมื่อเป็น A record แยกต่างหากแทนที่จะเป็น CNAME, MX record ใดๆ ที่ชี้มายังเซิร์ฟเวอร์นั้นโดยตรง, SPF record ที่ระบุ IP เดิม และ reverse DNS (PTR) record บนที่อยู่ใหม่ ให้ตั้งค่า PTR ผ่านแผงควบคุมของผู้ให้บริการของคุณก่อนการย้ายระบบหากเซิร์ฟเวอร์มีการส่งอีเมล เนื่องจากเซิร์ฟเวอร์ปลายทางจะตรวจสอบค่านี้ และการไม่มี PTR จะทำให้อีเมลถูกปฏิเสธหลังจากทุกอย่างดูเหมือนจะเรียบร้อยดีไปแล้วหลายชั่วโมง
ตรวจสอบเซิร์ฟเวอร์ใหม่ผ่าน IP ก่อนเริ่มตั้งค่า DNS
คุณสามารถทดสอบแอปพลิเคชันทั้งหมดบนเซิร์ฟเวอร์ใหม่ได้ในขณะที่ DNS ยังคงชี้ไปยังเซิร์ฟเวอร์เดิม โดยการระบุการค้นหาชื่อโดเมน (name lookup) ใหม่สำหรับคำขอเดียว:
# 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 เมื่อตรวจสอบสายโซ่ใบรับรอง (chain) สำเร็จ
สำหรับการคลิกใช้งานเว็บไซต์ผ่านเบราว์เซอร์ ให้ระบุชื่อโดเมนใหม่สำหรับเครื่องของคุณทั้งเครื่อง โดยเพิ่มหนึ่งบรรทัดลงใน /etc/hosts บนแล็ปท็อปของคุณ หรือใน C:\Windows\System32\drivers\etc\hosts บน Windows:
203.0.113.20 example.com www.example.comจากนั้นให้ทดสอบแอปพลิเคชันในลักษณะเดียวกับที่ผู้ใช้ทั่วไปใช้งานจริง เช่น เข้าสู่ระบบ, โหลดหน้าเว็บที่อ่านข้อมูลจากฐานข้อมูล, ส่งฟอร์มที่เขียนข้อมูลลงฐานข้อมูล, อัปโหลดไฟล์และตรวจสอบว่าไฟล์ถูกบันทึกลงดิสก์เรียบร้อย, ทดสอบการทำงานของระบบส่งอีเมลและตรวจสอบว่าอีเมลได้รับจริง เนื่องจากปัญหาการส่งอีเมลขาออก (outbound SMTP) จาก IP ใหม่เป็นสิ่งที่มักพบเจอได้บ่อย อย่าลืมลบรายการในไฟล์ hosts ออกทันทีที่ทดสอบเสร็จสิ้น การทิ้งรายการดังกล่าวไว้จะทำให้คุณต้องเสียเวลาหลายชั่วโมงในการแก้ปัญหาเว็บไซต์ที่คนอื่นสามารถเข้าใช้งานได้ตามปกติ
ขั้นตอนการย้ายระบบ (Cutover)
- ล่วงหน้าหลายวัน: ลดค่า TTL, รัน rsync ข้อมูลจำนวนมาก, สร้างเซิร์ฟเวอร์ใหม่ และทดสอบผ่านการแก้ไขไฟล์ hosts
- วันที่ดำเนินการ ก่อนเริ่มช่วงเวลาบำรุงรักษา: เพิ่ม IP ใหม่ลงใน allowlist ของบริการภายนอกทุกรายการ และยืนยันว่างานสำรองข้อมูลของเซิร์ฟเวอร์ใหม่ถูกตั้งค่าและชี้ไปยัง repository ของคุณเรียบร้อยแล้ว
- เริ่มช่วงเวลาบำรุงรักษา: ตั้งค่าแอปพลิเคชันบนเซิร์ฟเวอร์เก่าให้อยู่ในโหมด maintenance เพื่อหยุดการรับข้อมูลใหม่
- ทำการ dump ฐานข้อมูลครั้งสุดท้าย จากนั้นรัน rsync รอบสุดท้ายด้วย
--delete - กู้คืนข้อมูล dump บนเซิร์ฟเวอร์ใหม่และเริ่มการทำงานของ service ต่างๆ
- ทดสอบอีกครั้งผ่าน
--resolveและการแก้ไขไฟล์ hosts รวมถึงทดสอบการเขียนข้อมูลจริงหนึ่งรายการ - เปลี่ยนค่า A และ AAAA record ให้ชี้ไปยัง IP ใหม่
- เฝ้าสังเกตเซิร์ฟเวอร์ทั้งสองเครื่อง access log ของเซิร์ฟเวอร์เก่าจะแสดงให้เห็นว่ายังมีใครเข้าใช้งานอยู่ ซึ่งจำนวนควรจะลดลงจนเหลือศูนย์ตามระยะเวลา TTL
- ปิดหน้า maintenance
- ปล่อยให้เซิร์ฟเวอร์เก่าทำงานต่อไปโดยไม่แตะต้องอย่างน้อยหนึ่งสัปดาห์
ขั้นตอนการเข้าสู่โหมด maintenance คือสิ่งที่คนมักมองข้าม แต่เป็นขั้นตอนที่ช่วยปกป้องคุณได้ดีที่สุด เมื่อฐานข้อมูลใหม่เริ่มรับข้อมูลใหม่แล้ว การย้อนกลับ (rollback) จะหมายถึงการสูญเสียข้อมูลนั้นไป หรือต้อง dump ฐานข้อมูลใหม่เพื่อนำกลับไปโหลดลงในฐานข้อมูลเก่า ช่วงเวลาที่ระบบเป็นแบบอ่านได้อย่างเดียวเพียงไม่กี่นาทีนั้นมีต้นทุนต่ำ แต่หากฐานข้อมูลทั้งสองเครื่องรับข้อมูลพร้อมกัน คุณอาจต้องเสียเวลาหลายวันในการตรวจสอบและรวมข้อมูลด้วยตนเอง
แผนการย้อนกลับ (Rollback)
การย้อนกลับคือการดำเนินการเดียว นั่นคือการเปลี่ยนระเบียน DNS กลับไปที่ 198.51.100.10 ซึ่งจะทำได้สำเร็จก็ต่อเมื่อคุณได้ทำ 4 สิ่งต่อไปนี้ไว้ก่อนหน้าแล้ว:
- เซิร์ฟเวอร์เดิมยังคงทำงานอยู่ บริการต่างๆ ยังเปิดใช้งาน และข้อมูลยังอยู่ครบถ้วน คุณเพียงแค่หยุดการเขียนข้อมูลลงไป แต่ไม่ได้ยกเลิกการใช้งานเซิร์ฟเวอร์นั้น
- ค่า TTL ยังคงต่ำอยู่ ดังนั้นเส้นทางย้อนกลับจึงรวดเร็วพอๆ กับเส้นทางขาไป
- คุณได้ เพิ่ม IP ใหม่เข้าไปในรายการอนุญาต (allowlist) ของบุคคลที่สาม แทนที่จะเข้าไปแทนที่ IP เดิม หากคุณลบที่อยู่เดิมออก เส้นทางการย้อนกลับของคุณจะล้มเหลวที่เกตเวย์การชำระเงิน
- เซิร์ฟเวอร์ใหม่ไม่มีการเขียนข้อมูลใดๆ ที่คุณระบุไม่ได้ เพราะการเขียนข้อมูลที่เกิดขึ้นจนถึงตอนนี้มีเพียงรายการธุรกรรมทดสอบของคุณเองเท่านั้น
ให้ตัดสินใจก่อนที่ช่วงเวลาดำเนินการจะเริ่มขึ้นว่าอะไรคือตัวกระตุ้นให้ต้องย้อนกลับ ตัวกระตุ้นเพียง 2 อย่างก็เพียงพอแล้ว ได้แก่ ข้อผิดพลาดใดๆ ที่คุณไม่สามารถวินิจฉัยได้ภายในจำนวนนาทีที่กำหนด และการสูญหายของข้อมูลไม่ว่าในกรณีใดก็ตาม การจดบันทึกสิ่งเหล่านี้ไว้ล่วงหน้าคือสิ่งที่ช่วยป้องกันการคาดเดาไปมานานนับชั่วโมง ซึ่งจะเปลี่ยนเหตุการณ์ระบบล่มเพียง 10 นาทีให้กลายเป็นเหตุการณ์ที่ยาวนานขึ้น
พิสูจน์ว่าการย้ายระบบสำเร็จ
การย้ายระบบยังไม่เสร็จสิ้นเพียงแค่เมื่อเว็บไซต์โหลดขึ้นมาได้ คุณต้องตรวจสอบสิ่งที่มักจะล้มเหลวในภายหลัง
# new server
systemctl --failed
journalctl -p err -b --no-pager | tail -n 40
sudo certbot certificates
sudo systemctl list-timers --all --no-pagerการรายงาน systemctl --failed คือ 0 loaded units listed คือผลลัพธ์ที่คุณต้องการ certbot certificates ควรแสดงวันหมดอายุที่คุณคาดหวัง และ list-timers ควรแสดงงานที่กำหนดเวลาไว้ทั้งหมดจากรายการของคุณพร้อมเวลาการทำงานครั้งถัดไปที่ชัดเจน ไม่ใช่ค่าว่าง
จากนั้นให้รีบูตเซิร์ฟเวอร์เครื่องใหม่หนึ่งครั้งโดยเจตนาในขณะที่คุณกำลังเฝ้าดูอยู่ บริการที่ใครบางคนเริ่มทำงานด้วยตนเองแต่ไม่ได้เปิดใช้งาน (enable) ไว้จะทำงานได้อย่างสมบูรณ์จนกระทั่งเกิดการรีบูตโดยไม่คาดคิดครั้งแรกตอนตีสาม
# new server
sudo reboot
# your laptop, once it comes back
curl -sS -o /dev/null -w '%{http_code}\n' https://example.com/หากแอปพลิเคชันทำงานในคอนเทนเนอร์ กับดักเดียวกันนี้จะมีรูปแบบที่ต่างออกไป เพราะ compose stack จำเป็นต้องมีนโยบายการรีสตาร์ทที่ชัดเจนเพื่อให้กลับมาทำงานได้หลังรีบูต
การตรวจสอบขั้นตอนสุดท้ายเป็นสิ่งที่เลื่อนออกไปได้ง่ายที่สุดแต่สำคัญที่สุด นั่นคือการสำรองข้อมูล การย้ายระบบที่จบลงด้วยเซิร์ฟเวอร์ที่ไม่มีการสำรองข้อมูลถือเป็นการเปลี่ยนความเสี่ยงหนึ่งไปเป็นอีกความเสี่ยงหนึ่ง ให้รันการสำรองข้อมูลบนเครื่องใหม่ด้วยตนเอง จากนั้นกู้คืนไฟล์เดียวจากข้อมูลสำรองนั้นลงในไดเรกทอรีชั่วคราว คลังข้อมูล restic ที่มีการทดสอบการกู้คืนจริง คือเวอร์ชันของกระบวนการนี้ที่จะช่วยคุณได้เมื่อถึงเวลาจำเป็น หากคุณกำลังรันเซิร์ฟเวอร์เครื่องเก่าและเครื่องใหม่ควบคู่กันไปเป็นเวลาหนึ่งสัปดาห์ วิธีการที่สอดคล้องกันในการเข้าถึงและกำหนดค่าแต่ละโฮสต์ จะช่วยป้องกันไม่ให้ทั้งสองเครื่องมีการตั้งค่าที่คลาดเคลื่อนจากกันในระหว่างที่ยังเปิดใช้งานอยู่ทั้งคู่
หลังการย้ายระบบ: เซิร์ฟเวอร์เก่าและรายการสุดท้าย
ให้เก็บเซิร์ฟเวอร์เก่าไว้เป็นเวลาหนึ่งถึงสองสัปดาห์ ค่าใช้จ่ายที่เกิดขึ้นเทียบเท่ากับค่าบริการหนึ่งเดือนของแผนที่คุณกำลังจะยกเลิก และนี่คือช่องทางเดียวที่คุณจะย้อนกลับไปใช้ระบบเดิมได้ จากนั้นจึงค่อยจัดการส่วนที่เหลือให้เสร็จสิ้น
- การใช้ hostname เดิมซ้ำใน
~/.ssh/configของคุณสำหรับเซิร์ฟเวอร์ใหม่ จะทำให้เกิดWARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!ในการเชื่อมต่อครั้งแรก เนื่องจากชื่อดังกล่าวตอบกลับด้วย host key ที่เปลี่ยนไป ให้ล้างรายการที่ค้างอยู่ออกด้วยssh-keygen -R example.comเมื่อคุณมั่นใจแล้วว่าเหตุใดจึงมีการเปลี่ยนแปลง ไม่ควรทำโดยสัญชาตญาณเนื่องจากคำเตือนลักษณะเดียวกันนี้คือสิ่งที่เกิดขึ้นเมื่อมีการโจมตีแบบดักฟังข้อมูล การย้ายระบบยังเป็นช่วงเวลาที่ดีในการทบทวนว่า key ใดสามารถเข้าถึงส่วนใดได้บ้าง ซึ่งเป็นเนื้อหาของ การจัดการ SSH key ในกลุ่มเซิร์ฟเวอร์ขนาดเล็ก - ทำ snapshot หรือสำรองข้อมูลครั้งสุดท้ายของเซิร์ฟเวอร์เก่า และจัดเก็บไว้ในที่ที่ไม่ใช่ผู้ให้บริการรายเดิม
- ลบ IP เก่าออกจากการตรวจสอบของระบบ monitoring, จากระเบียน SPF และจากรายการ allowlist ของบุคคลที่สาม ตามลำดับนี้และเป็นขั้นตอนสุดท้าย
- ยกเลิกแผนบริการเก่าหลังจากยืนยันแล้วว่าสำเนาข้อมูลชุดสุดท้ายสามารถอ่านได้จากที่อื่นแล้วเท่านั้น
FAQ
การย้ายเซิร์ฟเวอร์ไปยัง VPS ใหม่ใช้เวลานานเท่าใด?
ช่วงเวลาที่ผู้ใช้จะพบกับบริการหยุดชะงักมักจะเป็นช่วงการดัมพ์ฐานข้อมูลครั้งสุดท้าย การรัน rsync รอบสุดท้าย และการเริ่มบริการใหม่ ซึ่งสำหรับแอปพลิเคชันขนาดเล็กจะใช้เวลาประมาณ 10 ถึง 30 นาที แต่ระยะเวลาตามปฏิทินจะนานกว่านั้น เนื่องจากต้องลดค่า DNS TTL ลงอย่างน้อยหนึ่งรอบของค่า TTL เดิมก่อนการสลับเซิร์ฟเวอร์ และการเตรียมตัวล่วงหน้าหนึ่งวันจะปลอดภัยกว่า ควรวางแผนคัดลอกข้อมูลจำนวนมากไว้ล่วงหน้าหลายวันด้วย กระบวนการนี้สามารถรันบนเซิร์ฟเวอร์ที่กำลังทำงานอยู่ได้ และการทำซ้ำในภายหลังจะคัดลอกเฉพาะส่วนที่มีการเปลี่ยนแปลงตั้งแต่รอบล่าสุดเท่านั้น
ฉันสามารถใช้ rsync คัดลอกฐานข้อมูล MySQL หรือ PostgreSQL ที่กำลังทำงานอยู่แทนการดัมพ์ได้หรือไม่?
ไม่ได้ rsync จะคัดลอกไฟล์ทีละไฟล์ในขณะที่ฐานข้อมูลเขียนข้อมูลลงหลายไฟล์พร้อมกัน ทำให้สำเนาที่ได้ประกอบด้วยข้อมูลจากช่วงเวลาที่ต่างกันและเป็นสถานะที่ฐานข้อมูลไม่เคยมีอยู่จริง ซึ่งอาจทำให้ฐานข้อมูลปฏิเสธที่จะเริ่มทำงาน หรือเริ่มทำงานได้แต่ล้มเหลวในภายหลังเมื่อมีการคิวรีไปยังหน้าข้อมูลที่เสียหาย ให้ใช้ pg_dump ร่วมกับ pg_dumpall --globals-only หรือใช้ mysqldump --single-transaction หรือหยุดการทำงานของฐานข้อมูลก่อนแล้วจึงคัดลอกไฟล์ สำหรับ PostgreSQL คลัสเตอร์ขนาดใหญ่ pg_basebackup จะช่วยสร้างสำเนาทางกายภาพที่สอดคล้องกันของเซิร์ฟเวอร์ที่กำลังทำงานอยู่
ฉันจะทดสอบ VPS ใหม่ก่อนเปลี่ยน DNS ได้อย่างไร?
ให้ใช้วิธี override การค้นหาชื่อโดเมนบนเครื่องของคุณเอง สำหรับการร้องขอครั้งเดียว 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 เท่าใด และควรลดค่าเมื่อใด?
ให้ลดค่า A และ AAAA record ลงเหลือ 300 วินาที โดยต้องดำเนินการล่วงหน้าอย่างน้อยหนึ่งรอบของค่า TTL เดิมก่อนการย้ายจริง ตัวแก้ไข DNS (resolver) ที่แคช record ไว้ก่อนการเปลี่ยนแปลงของคุณจะยังคงใช้ค่าเดิมจนกว่าจะครบกำหนด TTL เดิม ดังนั้นการลดค่าล่วงหน้าเพียงหนึ่งชั่วโมงจะไม่มีผลหากค่า TTL เดิมคือ 86400 ให้ปรับค่ากลับเป็นค่าปกติหลังจากย้ายระบบไปแล้วสองสามวัน เมื่อ access log ของเซิร์ฟเวอร์เก่าเงียบลงแล้ว
ฉันควรคัดลอกใบรับรอง TLS หรือออกใบรับรองใหม่บนเซิร์ฟเวอร์ใหม่?
ทำได้ทั้งสองวิธี การคัดลอก /etc/letsencrypt/ จะทำให้ใบรับรองยังคงมีผลจนถึงวันหมดอายุเดิม แต่คุณต้องติดตั้ง certbot authenticator plugin ตัวเดียวกันบนเซิร์ฟเวอร์ใหม่ มิฉะนั้นการต่ออายุครั้งแรกจะล้มเหลว ดังนั้นให้รัน certbot renew --dry-run หลังจากสลับ DNS เพื่อยืนยันความถูกต้อง การออกใบรับรองใหม่จะสะอาดกว่าหากคุณสามารถใช้ DNS-01 challenge ได้ เนื่องจากเป็นการพิสูจน์สิทธิ์ผ่าน TXT record และสามารถทำได้ก่อนที่ DNS จะชี้ไปยังเซิร์ฟเวอร์ใหม่ ส่วน HTTP-01 challenge ไม่สามารถใช้บนเซิร์ฟเวอร์ใหม่ได้จนกว่า DNS จะย้ายเสร็จสิ้น เนื่องจากคำขอตรวจสอบความถูกต้องจะยังคงวิ่งไปที่เซิร์ฟเวอร์เก่าอยู่