สำรองข้อมูลไปยังเซิร์ฟเวอร์อื่นด้วย rsync และ Cronjob

ตั้งค่าสำรองไฟล์จาก Linux Server ไปยังเซิร์ฟเวอร์ปลายทางด้วย rsync ผ่าน SSH Key และให้ Cronjob รันสคริปต์สำรองข้อมูลอัตโนมัติทุกวัน

โดย ทีมงาน THAI DATA CLOUD อัปเดต อ่าน 10 นาที เข้าชม 3 ครั้ง

แชร์FacebookXLINELinkedIn
Cronjob — สำรองข้อมูลไปยังเซิร์ฟเวอร์อื่นด้วย rsync และ Cronjob
สำรองข้อมูลไปยังเซิร์ฟเวอร์อื่นด้วย rsync และ Cronjob

คำตอบสั้น ๆ: ตั้งค่าสำรองไฟล์จาก Linux Server ไปยังเซิร์ฟเวอร์ปลายทางด้วย rsync ผ่าน SSH Key และให้ Cronjob รันสคริปต์สำรองข้อมูลอัตโนมัติทุกวัน

คู่มือนี้อธิบาย Cronjob ทีละขั้นตอน พร้อมคำสั่งที่ใช้ได้จริงและปัญหาที่พบบ่อย

การเก็บไฟล์สำรองไว้บนเซิร์ฟเวอร์เครื่องเดียวกับข้อมูลจริงไม่ช่วยอะไรเมื่อดิสก์เสีย เครื่องถูกลบ หรือถูกโจมตี วิธีที่ง่ายและใช้กันแพร่หลายคือใช้ rsync คัดลอกไฟล์ผ่าน SSH ไปเก็บที่เซิร์ฟเวอร์อีกเครื่อง rsync ส่งเฉพาะส่วนที่เปลี่ยนแปลง จึงเร็วและประหยัด Bandwidth หลังจากรอบแรก

คู่มือนี้เรียกเครื่องที่มีข้อมูลว่า เครื่องต้นทาง และเครื่องที่เก็บสำรองว่า เครื่องปลายทาง (ตัวอย่าง IP 203.0.113.20) ใช้ได้กับ Ubuntu, AlmaLinux และ Rocky Linux

สิ่งที่ต้องเตรียม

  • สิทธิ์ sudo บนเครื่องต้นทาง และผู้ใช้สำหรับรับไฟล์บนเครื่องปลายทาง (ตัวอย่างใช้ชื่อ backup)
  • เครื่องต้นทางเชื่อมต่อ SSH ไปยังเครื่องปลายทางได้
  • พื้นที่บนเครื่องปลายทางมากกว่าขนาดข้อมูลที่จะสำรอง
  • ติดตั้ง rsync ทั้งสองเครื่อง: sudo apt install -y rsync หรือ sudo dnf install -y rsync

ตัวอย่างนี้สำรองโฟลเดอร์ /var/www หากต้องการสำรองฐานข้อมูลด้วย ให้ Dump ฐานข้อมูลเป็นไฟล์ก่อนตามคู่มือ สำรองและกู้คืนฐานข้อมูล MySQL/MariaDB ด้วย mysqldump แล้วให้ rsync ส่งโฟลเดอร์ไฟล์ Dump ไปด้วย

ขั้นตอนที่ 1: เตรียมผู้ใช้และโฟลเดอร์บนเครื่องปลายทาง

บนเครื่องปลายทาง สร้างผู้ใช้ backup และโฟลเดอร์รับไฟล์

sudo useradd -m -s /bin/bash backup
sudo mkdir -p /srv/backup/web01
sudo chown backup:backup /srv/backup/web01

บน Ubuntu อาจมีผู้ใช้ระบบชื่อ backup อยู่แล้ว หาก useradd แจ้งว่ามีผู้ใช้นี้ ให้ใช้ชื่ออื่น เช่น bkuser และเปลี่ยนชื่อในทุกคำสั่งให้ตรงกัน

ขั้นตอนที่ 2: สร้าง SSH Key สำหรับงานสำรองข้อมูล

Cronjob รันโดยไม่มีคนพิมพ์รหัสผ่าน จึงต้องใช้ SSH Key ที่ไม่มี Passphrase แยกไว้สำหรับงานนี้โดยเฉพาะ บนเครื่องต้นทาง ให้ทำในฐานะ root เพราะต้องอ่านไฟล์ได้ทุกไฟล์

sudo ssh-keygen -t ed25519 -f /root/.ssh/backup_ed25519 -N "" -C "backup web01"
sudo cat /root/.ssh/backup_ed25519.pub

คัดลอกข้อความ Public Key ที่ได้ แล้วนำไปใส่ในไฟล์ /home/backup/.ssh/authorized_keys บนเครื่องปลายทาง

sudo -u backup mkdir -p /home/backup/.ssh
sudo -u backup nano /home/backup/.ssh/authorized_keys
sudo chmod 700 /home/backup/.ssh
sudo chmod 600 /home/backup/.ssh/authorized_keys

จากนั้นทดสอบการเชื่อมต่อจากเครื่องต้นทาง ครั้งแรกต้องทำด้วยมือ เพื่อตอบ yes ยืนยัน Host Key ของเครื่องปลายทาง ไม่เช่นนั้น Cronjob จะล้มเหลว

sudo ssh -i /root/.ssh/backup_ed25519 [email protected] 'echo connected'

ถ้าได้คำว่า connected โดยไม่ถามรหัสผ่าน แสดงว่าพร้อมแล้ว หากเครื่องปลายทางเปลี่ยน SSH Port ไว้ ให้เติม -p 2222 (ใช้พอร์ตจริง) ต่อจาก ssh ดูรายละเอียดเรื่อง SSH Key เพิ่มเติมได้ที่ ตั้งค่า SSH Key และปิดการเข้าสู่ระบบด้วยรหัสผ่านบน Linux

ขั้นตอนที่ 3: ทดลองรัน rsync แบบจำลองก่อน

sudo rsync -aHz --delete --dry-run --itemize-changes \
  -e "ssh -i /root/.ssh/backup_ed25519" \
  /var/www/ [email protected]:/srv/backup/web01/www/

ความหมายของตัวเลือก

  • -a คัดลอกแบบเก็บสิทธิ์ เจ้าของ เวลา และ Symlink ครบ
  • -H รักษา Hard Link
  • -z บีบอัดข้อมูลระหว่างส่ง
  • --delete ลบไฟล์ฝั่งปลายทางที่ไม่มีแล้วในต้นทาง ให้สองฝั่งตรงกัน
  • --dry-run แสดงว่าจะทำอะไรโดยยังไม่ทำจริง

หมายเหตุ: เครื่องหมาย / ท้าย Path ต้นทางมีผล /var/www/ หมายถึงคัดลอก เนื้อหาใน โฟลเดอร์ ส่วน /var/www จะสร้างโฟลเดอร์ www ซ้อนเข้าไปอีกชั้น และเมื่อใช้ --delete ถ้าระบุ Path ปลายทางผิด ไฟล์ในโฟลเดอร์นั้นจะถูกลบ จึงต้องตรวจผลจาก --dry-run ทุกครั้งก่อนรันจริง

เมื่อตรวจรายการแล้วถูกต้อง ให้รันซ้ำโดยตัด --dry-run ออก รอบแรกจะใช้เวลานานตามขนาดข้อมูล รอบต่อไปจะเร็วขึ้นมาก

ขั้นตอนที่ 4: เขียนสคริปต์สำรองข้อมูล

sudo nano /usr/local/bin/backup-web.sh
#!/bin/bash
set -euo pipefail

DEST="[email protected]:/srv/backup/web01"
SSH="ssh -i /root/.ssh/backup_ed25519 -o BatchMode=yes"

echo "=== $(date '+%F %T') start"
rsync -aHz --delete --exclude 'cache/' -e "$SSH" /var/www/ "$DEST/www/"
rsync -aHz --delete -e "$SSH" /etc/nginx/ "$DEST/nginx/"
echo "=== $(date '+%F %T') done"
sudo chmod 700 /usr/local/bin/backup-web.sh
sudo /usr/local/bin/backup-web.sh

set -euo pipefail ทำให้สคริปต์หยุดทันทีเมื่อคำสั่งใดล้มเหลว และ BatchMode=yes ทำให้ SSH ไม่ค้างรอรหัสผ่านหากใช้ Key ไม่ได้ ปรับ --exclude และรายการโฟลเดอร์ให้ตรงกับเซิร์ฟเวอร์ของคุณ

ขั้นตอนที่ 5: ตั้ง Cronjob ให้รันอัตโนมัติ

sudo crontab -e

เพิ่มบรรทัดนี้ เพื่อรันทุกวันเวลา 02:30 ตามเวลาของเซิร์ฟเวอร์

30 2 * * * /usr/bin/flock -n /run/backup-web.lock /usr/local/bin/backup-web.sh >> /var/log/backup-web.log 2>&1

flock -n ป้องกันไม่ให้สคริปต์รอบใหม่เริ่มขณะที่รอบก่อนยังไม่เสร็จ และ Log ทั้งหมดถูกเก็บที่ /var/log/backup-web.log ตรวจว่าเวลาของเซิร์ฟเวอร์ถูกต้องได้ที่ ตั้งค่า Timezone และซิงก์เวลาอัตโนมัติบน Linux Server และอ่านพื้นฐาน Cronjob เพิ่มได้ที่ วิธีตั้ง Cronjob หรือ Crontab เพื่อให้ Script ทำงานอัตโนมัติบน Linux

เก็บหลายเวอร์ชันย้อนหลัง (ทางเลือก)

การใช้ --delete ทำให้ปลายทางเป็นสำเนาล่าสุดเพียงชุดเดียว หากไฟล์ถูกลบหรือถูกเข้ารหัสโดยมัลแวร์ก่อนรอบสำรอง ความเสียหายจะถูกคัดลอกไปด้วย หากต้องการเก็บย้อนหลังหลายวัน ให้ใช้ Snapshot บนเครื่องปลายทางหรือบริการสำรองข้อมูลของเซิร์ฟเวอร์ (ดู การ Backup Server บน Cloud ของ TDC) ร่วมด้วย หรือใช้ตัวเลือก --link-dest ของ rsync สร้างโฟลเดอร์แยกตามวันที่ ซึ่งไฟล์ที่ไม่เปลี่ยนจะเป็น Hard Link ไม่เปลืองพื้นที่เพิ่ม

ตรวจสอบผลลัพธ์

  • ดู Log หลังเวลาที่ตั้งไว้: sudo tail -n 20 /var/log/backup-web.log ต้องเห็นบรรทัด start และ done
  • บนเครื่องปลายทาง ตรวจขนาดและเวลาไฟล์: du -sh /srv/backup/web01/* และ ls -la /srv/backup/web01/www
  • ทดสอบกู้คืนจริง อย่างน้อยเป็นระยะ เช่น ดึงไฟล์กลับมาไว้ในโฟลเดอร์ชั่วคราวแล้วเปิดดู
sudo rsync -a -e "ssh -i /root/.ssh/backup_ed25519" \
  [email protected]:/srv/backup/web01/www/ /tmp/restore-test/

ปัญหาที่พบบ่อย

Host key verification failed

root บนเครื่องต้นทางยังไม่เคยยืนยัน Host Key ของเครื่องปลายทาง ให้รันคำสั่งทดสอบในขั้นตอนที่ 2 ด้วย sudo หนึ่งครั้งแล้วตอบ yes หากเครื่องปลายทางเพิ่งติดตั้งใหม่ ให้ลบ Key เก่าด้วย sudo ssh-keygen -R 203.0.113.20 ก่อน

Permission denied (publickey)

Public Key ไม่อยู่ใน authorized_keys ของผู้ใช้ที่ถูกต้อง หรือสิทธิ์ไฟล์กว้างเกินไป ตรวจว่า .ssh เป็น 700 และ authorized_keys เป็น 600 และเป็นเจ้าของโดยผู้ใช้ backup

รันด้วยมือได้ แต่ใน Cron ไม่ทำงาน

Cron มี PATH น้อยกว่า Shell ปกติ ให้ใช้ Path เต็มของโปรแกรมและสคริปต์ทุกตัว และตรวจ Log ของ Cron ด้วย grep CRON /var/log/syslog บน Ubuntu หรือ sudo journalctl -u crond บน AlmaLinux และ Rocky Linux

rsync: command not found หรือ connection unexpectedly closed

เครื่องปลายทางยังไม่ได้ติดตั้ง rsync ต้องติดตั้งทั้งสองฝั่ง

หากทำตามขั้นตอนแล้วยังติดปัญหา สามารถติดต่อทีมงาน Support ของ THAI DATA CLOUD ได้ที่ https://thaidata.cloud/contact/ โดยแจ้งชื่อเซิร์ฟเวอร์ ระบบปฏิบัติการ ขั้นตอนที่ทำไปแล้ว และข้อความ Error ที่พบ เพื่อให้ตรวจสอบได้รวดเร็วขึ้น

สรุปขั้นตอน Cronjob

ทบทวน Cronjob ทั้งหมดตามลำดับ ก่อนนำไปใช้กับระบบจริง

  1. เตรียมผู้ใช้และโฟลเดอร์บนเครื่องปลายทาง
  2. สร้าง SSH Key สำหรับงานสำรองข้อมูล
  3. ทดลองรัน rsync แบบจำลองก่อน
  4. เขียนสคริปต์สำรองข้อมูล
  5. ตั้ง Cronjob ให้รันอัตโนมัติ

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

อ่านเพิ่มเติมเกี่ยวกับ Cronjob

แชร์FacebookXLINELinkedIn

มีคำถามเรื่องบริการ? ติดต่อทีมงาน