SSD Nodes Learn 🎉 VPS เริ่ม $5.50/เดือน
คู่มือ Matt Connorโดย Matt Connor · อัปเดตเมื่อ 2026-08-13

ความแตกต่างระหว่าง VPS Snapshot, Backup และ Clone

สรุปความต่างของ Snapshot, Backup และ Clone บน VPS เมื่อไหร่ควรใช้แต่ละวิธี พร้อมวิธีแก้ไขปัญหาเครื่องซ้ำซ้อนหลังทำ Clone เพื่อให้เซิร์ฟเวอร์ของคุณทำงานได้อย่างปลอดภัย

ความแตกต่างระหว่าง snapshot, backup และ clone

VPS snapshot คืออิมเมจของดิสก์บนเซิร์ฟเวอร์ของคุณ ซึ่งผู้ให้บริการจัดเก็บไว้บนโครงสร้างพื้นฐานของพวกเขาภายใต้บัญชีผู้ใช้ของคุณ ส่วน backup คือสำเนาข้อมูลที่เป็นอิสระซึ่งคุณสามารถนำไปกู้คืนที่อื่นได้โดยไม่ต้องพึ่งพาผู้ให้บริการรายเดิม และ clone คืออินสแตนซ์ใหม่ที่ถูกสร้างขึ้นจาก snapshot โดยเริ่มต้นสถานะเป็นสำเนาที่เหมือนกับต้นฉบับทุกประการ รวมถึงข้อมูลระบุตัวตนของเครื่องด้วย

เครื่องมือเหล่านี้แก้ปัญหาที่แตกต่างกัน snapshot ช่วยย้อนกลับการอัปเกรดที่ผิดพลาดได้ภายในไม่กี่นาที แต่ไม่สามารถช่วยอะไรได้หากบัญชีผู้ใช้ของคุณถูกปิดไป ส่วน backup จะยังคงอยู่แม้ผู้ให้บริการจะยุติการให้บริการไปแล้ว แต่ต้องใช้เวลาในการกู้คืนนานกว่าเนื่องจากคุณต้องสร้างเครื่องขึ้นมาใหม่ก่อน ในขณะที่ clone ช่วยให้คุณได้เซิร์ฟเวอร์เครื่องที่สองที่พร้อมใช้งานได้ในขั้นตอนเดียว แต่ก็ทำให้เกิดเครื่องสองเครื่องที่มีข้อมูลระบุตัวตนเดียวกันในระบบ

เหตุใด VPS snapshot จึงไม่ใช่การสำรองข้อมูล

ปัญหาอยู่ที่ขอบเขตความล้มเหลว (failure domain) ไม่ใช่คุณภาพของอิมเมจ snapshot จะถูกเก็บไว้บนแพลตฟอร์มสตอเรจของผู้ให้บริการ ซึ่งมักอยู่ในภูมิภาคเดียวกับเซิร์ฟเวอร์ต้นทาง และอยู่ภายในบัญชีผู้ใช้เดียวกันเสมอ เหตุการณ์เดียวอาจทำให้ทั้งเซิร์ฟเวอร์และ snapshot เสียหายไปพร้อมกันได้

  • บัญชีถูกระงับ การชำระเงินล้มเหลว หรือมีผู้อื่นขโมยข้อมูลเข้าสู่ระบบ
  • บุคคลหรือสคริปต์ที่มีสิทธิ์เข้าถึง API ลบอินสแตนซ์ทิ้ง ในผู้ให้บริการหลายราย การลบอินสแตนซ์จะลบ snapshot ที่เกี่ยวข้องไปด้วย โปรดอ่านเอกสารพฤติกรรมการทำงานของผู้ให้บริการก่อนที่จะสรุปเป็นอย่างอื่น
  • ภูมิภาคที่ใช้งานเกิดปัญหา ทำให้ทุกอย่างในนั้นไม่สามารถเข้าถึงได้พร้อมกัน
  • กระบวนการที่รันด้วยสิทธิ์ root บนเซิร์ฟเวอร์ค้นพบ API token ของผู้ให้บริการที่คุณทิ้งไว้ใน /root และลบ snapshot ทิ้งก่อนที่จะแตะต้องดิสก์

การสำรองข้อมูลคือสำเนาที่รอดพ้นจากทั้ง 4 กรณีข้างต้น บททดสอบคือคำถามเดียว: หากบัญชีผู้ให้บริการของคุณหายไปในบ่ายวันนี้ คุณยังสามารถกู้คืนอะไรได้บ้าง และคุณจะกู้คืนที่ไหน สิ่งใดที่ไม่ผ่านคำถามนี้ถือเป็นเพียงเครื่องมือย้อนกลับสถานะ (rollback tool) เท่านั้น คุณควรทำ snapshot ต่อไปเพราะไม่มีวิธีใดกู้คืนได้รวดเร็วเท่านี้ จากนั้นให้เก็บสำเนาชุดที่สองไว้บนสตอเรจที่ผู้ให้บริการของคุณไม่ได้เป็นผู้ควบคุม

กฎเดิมยังคงใช้ได้เสมอ: ข้อมูล 3 ชุด บนสตอเรจ 2 ประเภท โดย 1 ชุดต้องอยู่นอกแพลตฟอร์ม การใช้ snapshot ของผู้ให้บริการร่วมกับ restic backup repository บนโครงสร้างพื้นฐานแยกต่างหาก จะช่วยให้ครอบคลุมเงื่อนไขนี้โดยใช้ส่วนประกอบเพียง 2 ส่วน

เหตุใด snapshot ของฐานข้อมูลที่กำลังทำงานอยู่จึงอาจกู้คืนไม่ได้

snapshot ของผู้ให้บริการจะคัดลอก block device ณ ขณะใดขณะหนึ่ง โดยไม่ได้สั่งให้แอปพลิเคชันหยุดทำงานก่อน และไม่สามารถมองเห็นข้อมูลที่ยังค้างอยู่ใน page cache ดังนั้นภาพที่ได้จึงเป็นเพียง crash-consistent เท่านั้น ซึ่งมีสภาพเหมือนกับดิสก์ในกรณีที่มีคนดึงปลั๊กไฟออกกะทันหัน

ซอฟต์แวร์ส่วนใหญ่จัดการเรื่องนี้ได้ ext4 และ XFS จะเล่นซ้ำ (replay) journal ของตนเองเมื่อ mount ทำให้ระบบไฟล์กลับมาใช้งานได้ PostgreSQL จะเล่นซ้ำ write-ahead log เมื่อเริ่มทำงาน และ log จะแสดงข้อความดังนี้:

LOG:  database system was not properly shut down; automatic recovery in progress

InnoDB ก็ทำเช่นเดียวกันและแสดงบรรทัดการกู้คืนจากความเสียหาย (crash recovery) ระหว่างการเริ่มต้นระบบ การกู้คืนดังกล่าวคือการทำงานตามปกติของฐานข้อมูล ดังนั้น snapshot แบบ single-volume ของ PostgreSQL หรือ MySQL ที่ไม่มีการเขียนข้อมูลหนักๆ มักจะกู้คืนได้ตามปกติ

กรณีที่ crash-consistent ไม่เพียงพอเป็นเรื่องจริงและสร้างปัญหาได้ หากข้อมูลของคุณกระจายอยู่บนสอง volume ดิสก์ root และดิสก์ข้อมูลแยกกันจะถูก snapshot ในเวลาที่ต่างกัน ทำให้ไฟล์ข้อมูลและไดเรกทอรี log ไม่ตรงกัน และการกู้คืนไม่มีข้อมูลที่ถูกต้องให้เล่นซ้ำ ไฟล์ใดก็ตามที่แอปพลิเคชันเขียนโดยไม่เรียกใช้ fsync เช่น ไฟล์อัปโหลดที่ได้รับมาครึ่งเดียวหรือไฟล์คิว อาจกลับมาในสภาพที่ถูกตัดทอน (truncated) ข้อมูลใดๆ ที่แอปพลิเคชันเก็บไว้ในหน่วยความจำและรอเขียนลงดิสก์ตามรอบเวลาจะไม่มีอยู่ในภาพ snapshot นั้น

ดังนั้น ให้เขียน dump ลงดิสก์ก่อนที่คุณจะทำ snapshot เพื่อให้ภาพที่ได้มีไฟล์หนึ่งไฟล์ที่คุณมั่นใจว่ามีความสอดคล้องภายใน (internally consistent) ไม่ว่าไฟล์ข้อมูลจริงจะมีสถานะเป็นอย่างไรก็ตาม

sudo -u postgres pg_dumpall --clean --file=/var/backups/pg-$(date +%F).sql
sudo mysqldump --single-transaction --routines --all-databases > /var/backups/mysql-$(date +%F).sql

--single-transaction จะสร้าง dump ที่สอดคล้องกันของตาราง InnoDB โดยไม่ขัดขวางการเขียนข้อมูล เนื่องจาก dump จะทำงานภายใน repeatable-read transaction เดียวกัน แต่วิธีนี้ไม่ครอบคลุมตาราง MyISAM ซึ่งจำเป็นต้องล็อกตารางหรือหยุดเซิร์ฟเวอร์ก่อน ตรวจสอบให้แน่ใจว่า dump ไม่ว่างเปล่าและไม่ถูกตัดทอนก่อนที่จะเชื่อถือข้อมูลนั้น: tail -n 1 /var/backups/mysql-$(date +%F).sql บน mysqldump ที่สมบูรณ์จะลงท้ายด้วยคอมเมนต์ Dump completed

หากคุณมี volume ข้อมูลแยกต่างหาก คุณสามารถ freeze volume นั้นไว้ในช่วงเวลาไม่กี่วินาทีที่จำเป็นสำหรับการทำ snapshot:

sudo fsfreeze -f /srv
# take the snapshot from your provider's panel or API
sudo fsfreeze -u /srv

ให้ freeze เฉพาะ volume ข้อมูลเท่านั้น ห้าม freeze / โดยเด็ดขาด เพราะระบบไฟล์ root ที่ถูก freeze จะบล็อกการเขียนทุกอย่างบนเครื่อง รวมถึง shell ที่คุณใช้พิมพ์คำสั่ง unfreeze ซึ่งจะทำให้คุณถูกล็อกออกจากระบบและต้องรอการ hard reset เท่านั้น

ส่วนของการสำรองข้อมูลนอกสถานที่: restic หรือ Borg

Snapshot เป็นส่วนที่ทำงานได้รวดเร็ว ส่วนการสำรองข้อมูลนอกสถานที่ (offsite copy) คือส่วนที่จะช่วยให้ข้อมูลของคุณรอดพ้นจากความเสียหายที่เกิดกับผู้ให้บริการหลัก restic เป็นตัวเลือกเริ่มต้นที่ดีเนื่องจากมีความสามารถในการทำ deduplication, เข้ารหัสข้อมูลที่ฝั่งไคลเอนต์ และเขียนข้อมูลลงใน object storage ที่รองรับ S3, SFTP หรือไดเรกทอรีทั่วไป การใช้ storage VPS เป็นปลายทางสำรองข้อมูลนอกสถานที่ เป็นวิธีที่ได้ผลดีในกรณีนี้ เนื่องจาก repository สำหรับสำรองข้อมูลต้องการความจุมากกว่า IOPS

sudo apt update && sudo apt install -y restic
sudo sh -c 'umask 077; head -c 24 /dev/urandom | base64 > /root/.restic-pass'
sudo chmod 600 /root/.restic-pass
sudo cat /root/.restic-pass

ให้คัดลอก passphrase นั้นไปเก็บไว้ในโปรแกรมจัดการรหัสผ่านทันที โดยต้องทำบนอุปกรณ์ที่ไม่ใช่เซิร์ฟเวอร์เครื่องนี้ repository ของ restic ไม่สามารถเปิดได้หากไม่มีรหัสผ่านและไม่มีช่องทางในการกู้คืน หากสำเนาของรหัสผ่านเพียงชุดเดียวอยู่ในเครื่องที่คุณเพิ่งสูญเสียไป ข้อมูลสำรองที่เหลืออยู่ก็จะเป็นเพียงข้อมูลที่ถูกเข้ารหัสจนอ่านไม่ออกเท่านั้น

export RESTIC_REPOSITORY="s3:https://s3.example.com/vps-backups"
export RESTIC_PASSWORD_FILE=/root/.restic-pass
export AWS_ACCESS_KEY_ID="..."
export AWS_SECRET_ACCESS_KEY="..."
sudo -E restic init
sudo -E restic backup /etc /srv /var/backups
sudo -E restic snapshots

sudo -E จะเก็บตัวแปรเหล่านั้นไว้ เนื่องจากหากไม่มีการตั้งค่านี้ root จะได้รับ environment ที่สะอาดและ restic จะแจ้งเตือนว่าไม่ได้ระบุตำแหน่งของ repository restic snapshots ควรแสดงรายการการสำรองข้อมูลที่คุณเพิ่งทำไป พร้อมทั้งระบุโฮสต์และพาธที่เกี่ยวข้อง ควรตรวจสอบ repository ตามกำหนดเวลา และลองดึงข้อมูลบางส่วนกลับมาทดสอบแทนการตรวจสอบเพียงแค่โครงสร้างของข้อมูลเท่านั้น:

sudo -E restic check --read-data-subset=5%
sudo -E restic restore latest --target /tmp/restore-check
sudo -E restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune

การสำรองข้อมูลที่ไม่ได้ผ่านการทดสอบถือเป็นการคาดเดาเท่านั้น ให้ลองกู้คืนข้อมูลไปยัง VPS เครื่องอื่นอย่างน้อยหนึ่งครั้ง จับเวลาที่ใช้ และจดบันทึกเวลานั้นไว้ เพราะตัวเลขดังกล่าวคือเป้าหมายในการกู้คืนข้อมูลจริงของคุณ Borg เป็นอีกหนึ่งตัวเลือกที่มั่นคงและจัดเก็บ repository ผ่าน SSH แทนที่จะเป็น object storage โดยสามารถดูข้อดีข้อเสียเปรียบเทียบได้ใน การเปรียบเทียบระหว่าง restic และ BorgBackup

สิ่งที่ต้องแก้ไขก่อนนำ VPS ที่โคลนมาใช้งานจริง

การโคลนคือการทำสำเนาที่เหมือนต้นฉบับทุกประการ ซึ่งเป็นทั้งจุดเด่นและปัญหาในเวลาเดียวกัน ทุกสิ่งที่ทำให้เซิร์ฟเวอร์ต้นฉบับมีเอกลักษณ์จะถูกคัดลอกมาด้วย และเมื่อมีข้อมูลซ้ำกันก็จะเกิดความขัดแย้ง

สร้าง SSH host keys ขึ้นใหม่ เซิร์ฟเวอร์ที่โคลนมาจะมีไฟล์ /etc/ssh/ssh_host_* ของต้นฉบับติดมาด้วย ทำให้เซิร์ฟเวอร์สองเครื่องแสดงตัวตนเป็นโฮสต์เดียวกัน ผู้ใดก็ตามที่ควบคุมเครื่องหนึ่งจะสามารถสวมรอยเป็นอีกเครื่องหนึ่งต่อหน้าไคลเอนต์ที่เคยยอมรับคีย์นั้นได้ โดยที่ SSH จะไม่แจ้งเตือนใดๆ เพราะคีย์นั้นตรงกับที่ไคลเอนต์คาดหวังไว้

sudo rm -f /etc/ssh/ssh_host_*
sudo ssh-keygen -A
sudo systemctl restart ssh
ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

ssh-keygen -A จะเขียนคีย์ใหม่สำหรับทุกประเภทที่ daemon ต้องการ ค่า fingerprint จากคำสั่งสุดท้ายต้องแตกต่างจากค่าของต้นฉบับ เซสชันปัจจุบันของคุณจะไม่หลุดหลังการรีสตาร์ท เพราะการรีสตาร์ท sshd ไม่ได้ปิดการเชื่อมต่อที่ค้างอยู่ ให้ดำเนินการส่วนนี้ก่อนที่จะมีใครเชื่อมต่อเข้ามายังเซิร์ฟเวอร์ที่โคลนมา หากคุณปล่อยไว้จนภายหลัง ไคลเอนต์ทุกรายที่เคยเชื่อถือคีย์เดิมจะได้รับ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! และต้องรัน ssh-keygen -R <host> ก่อน

รีเซ็ต machine ID /etc/machine-id คือตัวระบุเฉพาะที่ systemd สร้างขึ้นครั้งเดียวตอนบูตเครื่องครั้งแรก และเซิร์ฟเวอร์ที่โคลนมาจะได้รับค่านี้ติดมาด้วย

sudo truncate -s 0 /etc/machine-id
sudo rm -f /var/lib/dbus/machine-id
sudo ln -s /etc/machine-id /var/lib/dbus/machine-id
sudo reboot

การทำให้ไฟล์ /etc/machine-id ว่างเปล่าเป็นการบอกให้ systemd สร้างค่าใหม่ในการบูตครั้งถัดไป ซึ่งเป็นเหตุผลว่าทำไมคุณต้องล้างเนื้อหาในไฟล์แทนที่จะลบไฟล์ทิ้ง มีสองสิ่งที่เสียหายเมื่อค่านี้ซ้ำกัน บนอิมเมจที่รับที่อยู่ผ่าน DHCP ตัว systemd-networkd จะดึงค่า DHCP client identifier มาจาก machine ID โดยค่าเริ่มต้น ทำให้เซิร์ฟเวอร์ที่โคลนมาทั้งสองเครื่องร้องขอ IP ในฐานะไคลเอนต์เดียวกัน และเซิร์ฟเวอร์จะจ่ายที่อยู่เดียวกันให้ทั้งคู่ นอกจากนี้ journald จะประทับตราทุกรายการด้วย machine ID ทำให้ระบบรวบรวม log ส่วนกลางจัดเก็บข้อมูลของทั้งสองเซิร์ฟเวอร์ไว้ภายใต้เครื่องเดียว ให้รัน cat /etc/machine-id หลังรีบูตและตรวจสอบว่าค่ามีการเปลี่ยนแปลงแล้ว

เปลี่ยน hostname

sudo hostnamectl set-hostname web-02
grep 127.0.1.1 /etc/hosts

hostnamectl จะเขียนไฟล์ /etc/hostname และปรับใช้ชื่อใหม่ทันที แต่มันไม่ได้แก้ไขไฟล์ /etc/hosts ดังนั้นให้แก้ไขบรรทัด 127.0.1.1 ให้ตรงกัน หากข้ามขั้นตอนนี้ไป ชื่อใหม่จะไม่สามารถ resolve ได้ และทุกการเรียก sudo จะรอจนกว่าการค้นหาล้มเหลวและแสดงผล sudo: unable to resolve host web-02: Name or service not known

หมุนเวียนข้อมูลรับรอง (credential) ทุกอย่างที่ฝังอยู่ในอิมเมจ เซิร์ฟเวอร์ที่โคลนมาถือครองความลับของต้นฉบับไว้ และตอนนี้เครื่องทั้งสองสามารถทำตัวเป็นต้นฉบับได้ ให้ไล่ตรวจสอบไฟล์ authorized_keys ของ SSH, โทเค็น API ของผู้ให้บริการและ DNS, ไฟล์ .env ของแอปพลิเคชัน, รหัสผ่านฐานข้อมูล, TLS private keys, โทเค็นการลงทะเบียนระบบตรวจสอบ และรหัสผ่านของ restic repository คำสั่งนี้จะช่วยค้นหาส่วนใหญ่ได้:

sudo grep -rIlE 'PASSWORD|SECRET|TOKEN|API_KEY' /etc /srv /opt /home 2>/dev/null
sudo find / -name '.env' -not -path '/proc/*' -not -path '/sys/*' 2>/dev/null

หากเซิร์ฟเวอร์ที่โคลนมาเป็นเพียงสำเนาสำหรับทดสอบที่จะไม่ให้บริการจริง ให้เพิกถอนสิทธิ์แทนการหมุนเวียนรหัสผ่าน เครื่อง staging ที่ถือโทเค็น API ของระบบ production จริง ก็คือเครื่อง production ที่มีความเสี่ยงด้านความปลอดภัยสูงกว่า

ปิดงานที่ทำงานซ้ำซ้อน เซิร์ฟเวอร์สองเครื่องที่รัน crontab เดียวกันจะเข้าถึงระบบภายนอกเดียวกันในนาทีเดียวกัน

systemctl list-timers --all
sudo crontab -l
sudo ls -l /etc/cron.d /etc/cron.daily

กรณีของ restic ควรระบุให้ชัดเจน เพราะมันจะทำให้ข้อมูลการเก็บรักษาเสียหายแทนที่จะแค่ล้มเหลวโดยแจ้งเตือน restic จะแท็ก snapshot แต่ละรายการด้วยชื่อโฮสต์ และ restic forget --keep-daily 7 จะใช้โยบายตามโฮสต์ หากเซิร์ฟเวอร์สองเครื่องรายงานชื่อโฮสต์เดียวกัน ระบบจะมองว่าเป็นโฮสต์เดียว ทำให้ snapshot แบบ "รายวัน" ทั้ง 7 รายการอาจมาจากเครื่องที่โคลนมาทั้งหมด ในขณะที่ snapshot ของต้นฉบับถูกลบออกไป ให้แก้ไข hostname ก่อนการสำรองข้อมูลครั้งแรก หรือหยุดตัวจับเวลาบนเซิร์ฟเวอร์ที่โคลนมา กรณีของ certbot นั้นง่ายกว่า คือเซิร์ฟเวอร์สองเครื่องที่ต่ออายุชื่อเดียวกันจะติดข้อจำกัดอัตราการออกใบรับรองซ้ำของผู้ออกใบรับรอง และการทำงานที่ช้ากว่าจะล้มเหลวพร้อมข้อผิดพลาดว่ามีการออกใบรับรองสำหรับชุดชื่อนั้นมากเกินไปแล้ว เซิร์ฟเวอร์ที่โคลนมาซึ่งโดเมนยังชี้ไปที่ต้นฉบับไม่สามารถผ่านการตรวจสอบ HTTP challenge ได้อยู่แล้ว ดังนั้นให้ปิดการต่ออายุบนเครื่องนั้น

จัดการกับ monitoring agent เอเจนต์ส่วนใหญ่ระบุตัวตนด้วย hostname หรือไฟล์ ID ที่เขียนขึ้นตอนติดตั้ง ดังนั้นเอเจนต์สองตัวที่รายงานว่าเป็นโฮสต์เดียวกันจะรวมเมตริกเข้าเป็นชุดข้อมูลเดียว กราฟ CPU จะแสดงค่าที่ไม่ได้มาจากเครื่องใดเครื่องหนึ่งจริงๆ และการแจ้งเตือนจะทำงานผิดพลาด ให้หยุดและลบเอเจนต์บนเซิร์ฟเวอร์ที่โคลนมา หรือลงทะเบียนใหม่ภายใต้ hostname ใหม่ตามขั้นตอนที่ผู้ให้บริการของคุณกำหนด

ตรวจสอบการตั้งค่าเครือข่ายสำหรับที่อยู่ของต้นฉบับ หากอิมเมจมีการตั้งค่า IP แบบ static ใน netplan เซิร์ฟเวอร์ที่โคลนมาจะอ้างสิทธิ์ใน IP ที่เป็นของเครื่องอื่น

ip -br addr
sudo grep -r addresses /etc/netplan/

ล้างสถานะ cloud-init หากเซิร์ฟเวอร์ที่โคลนมานี้จะกลายเป็นเทมเพลต

sudo cloud-init clean --logs

คำสั่งนั้นจะลบสถานะของ cloud-init ภายใต้ /var/lib/cloud ทำให้การบูตครั้งถัดไปรันโมดูลสำหรับการบูตครั้งแรกอีกครั้ง ซึ่งรวมถึงการสร้าง SSH host keys หากยังไม่มี บางเวอร์ชันอาจมีแฟล็กสำหรับรีเซ็ต machine ID ให้รัน cloud-init clean --help บนอิมเมจของคุณเองเพื่อดูว่าเวอร์ชันของคุณรองรับอะไรบ้าง แทนที่จะเชื่อรายการแฟล็กจากแหล่งอื่น

เมื่อใดควรใช้วิธีใด

การย้อนกลับการอัปเกรดที่มีความเสี่ยง: ให้ทำ snapshot ให้ทำ snapshot ไว้ไม่กี่นาทีก่อนเริ่มการเปลี่ยนแปลง จากนั้นจึงดำเนินการอัปเกรด หากเกิดข้อผิดพลาดให้กู้คืนจาก image นั้น การกู้คืนจะลบข้อมูลการเขียนทั้งหมดที่เกิดขึ้นหลังจากการทำ snapshot ดังนั้นหากเป็นเซิร์ฟเวอร์ที่รับ traffic จริง ให้ dump ฐานข้อมูลออกมาก่อนและต้องทราบแน่ชัดว่าข้อมูลในช่วงเวลาใดที่จะสูญเสียไป สำหรับ do-release-upgrade บนเครื่องที่คุณสามารถออฟไลน์ได้สิบนาที การทำ snapshot ถือเป็นแผนการที่สมบูรณ์แล้ว

การย้ายไปยังแผนที่ใหญ่ขึ้น: ให้ deploy clone สร้าง clone จาก snapshot ลงบนแผนที่ใหญ่ขึ้น ทำตามรายการตรวจสอบตัวตนด้านบน จากนั้นทดสอบบน IP ของเครื่องนั้นเองก่อนที่จะย้าย traffic ใดๆ เข้าไป ให้ลดค่า DNS TTL ลงหนึ่งวันล่วงหน้าเพื่อให้การสลับเปลี่ยนรวดเร็ว และให้เครื่องเดิมทำงานต่อไปจนกว่าเครื่องใหม่จะรองรับ traffic จริงได้โดยไม่มีปัญหา ตรวจสอบให้แน่ใจก่อนว่าแผนที่ใหญ่ขึ้นนั้นเร็วกว่าสำหรับ workload ของคุณจริงๆ โดยใช้ วิธีการ benchmark เดียวกันบนเซิร์ฟเวอร์ทั้งสองเครื่อง เพราะการเพิ่ม vCPU บนฮาร์ดแวร์ที่หนาแน่นกว่าไม่ได้หมายความว่าเป็นการอัปเกรดเสมอไป

การสร้าง template: ให้ snapshot เครื่องที่ทำความสะอาดแล้ว ติดตั้งและทำ hardening เซิร์ฟเวอร์หนึ่งเครื่อง จากนั้นลบทุกอย่างที่เป็นเอกลักษณ์เฉพาะออกก่อนที่จะทำ image ไม่ควรมี host keys, machine ID ต้องว่างเปล่า, ไม่มี authorized_keys ส่วนตัว, ไม่มีข้อมูลรับรอง (credentials) และล้างค่า cloud-init ออกให้หมด แล้วจึงทำ snapshot ทุก instance ที่ deploy จาก template นี้จะสร้างตัวตนของตัวเองขึ้นมาใหม่ในการบูตครั้งแรก ดังนั้นรายการตรวจสอบด้านบนจึงไม่จำเป็นต้องทำซ้ำอีก ให้ใช้งานร่วมกับ สิบนาทีแรกตามมาตรฐานบน VPS ใหม่ เพื่อให้ template มีการตั้งค่าที่คุณต้องทำซ้ำๆ อยู่แล้วรวมอยู่ด้วย

FAQ

Snapshot ของ VPS ถือเป็นข้อมูลสำรอง (Backup) หรือไม่?

ไม่ถือเป็นข้อมูลสำรอง เพราะ snapshot มีขอบเขตความล้มเหลว (failure domain) เดียวกับเซิร์ฟเวอร์ต้นทาง โดย snapshot จะถูกเก็บไว้บนพื้นที่จัดเก็บข้อมูลของผู้ให้บริการในบัญชีของคุณ ซึ่งมักจะอยู่ในภูมิภาคเดียวกัน หากบัญชีถูกระงับ, API key ถูกขโมย หรือมีการลบ instance โดยไม่ตั้งใจ ก็อาจทำให้เซิร์ฟเวอร์และ snapshot ทั้งหมดถูกลบไปพร้อมกันได้ ในผู้ให้บริการหลายราย การลบ instance จะส่งผลให้ snapshot ถูกลบตามไปด้วยโดยการออกแบบ snapshot เป็นวิธีที่ช่วยให้ย้อนกลับ (rollback) ได้รวดเร็วที่สุด ดังนั้นควรทำ snapshot ไว้เสมอ แต่ต้องเก็บสำเนาที่เข้ารหัสไว้อีกชุดหนึ่งไว้บนโครงสร้างพื้นฐานที่ผู้ให้บริการรายนั้นไม่ได้เป็นผู้ควบคุม

จำเป็นต้องหยุดฐานข้อมูลก่อนทำ snapshot หรือไม่?

ไม่จำเป็นเสมอไป แต่คุณต้องยอมรับผลลัพธ์ที่อาจเกิดขึ้นได้ Snapshot จากผู้ให้บริการจะเป็นแบบ crash-consistent ซึ่งหมายความว่าอิมเมจที่ได้จะมีสภาพเหมือนกับดิสก์หลังจากเกิดไฟดับ PostgreSQL และ InnoDB จะกู้คืนสถานะจากจุดนั้นเมื่อเริ่มทำงานใหม่ โดย PostgreSQL จะแสดง log database system was not properly shut down; automatic recovery in progress ในระหว่างกระบวนการดังกล่าว การกู้คืนข้อมูลอาจไม่รับประกันความถูกต้องหากข้อมูลของคุณกระจายอยู่บนสองโวลุ่มที่ถูกทำ snapshot ในเวลาที่ต่างกัน หรือเมื่อแอปพลิเคชันเขียนข้อมูลโดยไม่มี fsync ดังนั้นควรเขียนข้อมูลลงดิสก์ด้วย pg_dumpall หรือ mysqldump --single-transaction ก่อน เพื่อให้มั่นใจว่าอิมเมจจะมีไฟล์ที่คุณทราบแน่ชัดว่ามีความสอดคล้องกัน

ทำไมเซิร์ฟเวอร์ที่โคลนมาสองเครื่องถึงแย่ง IP address เดียวกัน?

เพราะทั้งสองเครื่องใช้ /etc/machine-id เดียวกัน ในอิมเมจที่ใช้ DHCP นั้น systemd-networkd จะสร้าง DHCP client identifier จาก machine ID โดยอัตโนมัติ ทำให้ทั้งสองเครื่องร้องขอ lease ในฐานะ client รายเดียวกัน และ DHCP server จึงเสนอ IP address เดียวกันให้ทั้งคู่ ให้ล้างไฟล์ /etc/machine-id ให้เหลือ 0 ไบต์, ลบ /var/lib/dbus/machine-id, สร้าง symlink กลับไปยัง /etc/machine-id แล้วรีบูตเครื่องเพื่อให้ systemd สร้างค่าใหม่ สาเหตุทั่วไปอีกประการหนึ่งคือการตั้งค่า static address ไว้ใน /etc/netplan/ ซึ่งเครื่องโคลนคัดลอกมาแบบ verbatim ให้ตรวจสอบด้วย ip -br addr

วิธีที่เร็วที่สุดในการตรวจสอบว่าเซิร์ฟเวอร์ที่โคลนมาปลอดภัยสำหรับการใช้งานจริงคืออะไร?

ให้เปรียบเทียบ 4 รายการกับเซิร์ฟเวอร์ต้นฉบับ รัน ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub บนทั้งสองเครื่องและยืนยันว่า fingerprint ต้องไม่ตรงกัน รัน cat /etc/machine-id บนทั้งสองเครื่องและยืนยันว่าค่าต้องไม่ตรงกัน รัน hostnamectl status และยืนยันว่าชื่อโฮสต์เป็นชื่อใหม่และสามารถ resolve ได้ เพื่อไม่ให้ sudo แจ้งเตือน จากนั้นรัน systemctl list-timers --all และหยุด timer ทุกตัวที่เชื่อมต่อกับระบบส่วนกลาง เช่น การสำรองข้อมูล, การต่ออายุใบรับรอง หรือ monitoring agent จนกว่าคุณจะตัดสินใจได้ว่าเครื่องใดเป็นผู้รับผิดชอบงานนั้นๆ