Skip to content

14.10 Disk, backup, disaster recovery

บทนี้ครอบคลุมการดูแล disk, กลยุทธ์การสำรองข้อมูล, และแผนกู้คืนจากภัยพิบัติ

สถานะปัจจุบัน

สิ่งสำคัญที่ต้องรับรู้:

  1. ไม่มี backup strategy ที่เป็นเอกสาร — ต้องสร้างขึ้นมาเอง
  2. ไม่มี disaster recovery plan — ไม่มี RTO/RPO ที่กำหนด
  3. ไม่มี off-site backup — ทุกอย่างอยู่ใน host เดียวกับ service
  4. disk usage ไม่ถูก monitor — ต้องตรวจด้วยตนเอง
  5. ไม่มี test restore — ไม่เคยทดสอบว่า backup ใช้งานได้จริง

การดูแล disk

การตรวจสอบ disk usage รายวัน

bash
# ดู disk ที่เหลือ
df -h

# ดู directory ที่ใช้ disk มากที่สุด
du -h --max-depth=2 /home/dev/ | sort -hr | head -20

# ดูไฟล์ใหญ่กว่า 100MB
find /home/dev/ -type f -size +100M -exec ls -lh {} \; 2>/dev/null

Directory ที่โตเร็วที่สุด

Pathสาเหตุการจัดการ
/home/dev/vtrc-api/api-logs/wlog เขียนทุกวันลบเก่ากว่า 30 วัน
/home/dev/vtrc-api/nginx-log/access log ทุก requestลบเก่ากว่า 30 วัน
/home/dev/vtrc-api/api-storage/prs/PDF payslipลบเก่ากว่า 30 วัน
/home/dev/vtrc-api/api-storage/file upload ทั่วไปaudit เป็นระยะ
Docker container logstdout/stderrlogrotate หรือ prune
Docker imagesimage เก่าdocker image prune
/var/lib/docker/Docker datamonitor

สคริปต์ cleanup อัตโนมัติ

bash
cat > /etc/cron.daily/vtrc-cleanup <<'EOF'
#!/bin/bash
set -e

# ลบ log เก่า
find /home/dev/vtrc-api/api-logs/ -mtime +30 -delete
find /home/dev/vtrc-api/nginx-log/ -mtime +30 -delete
find /home/dev/cu-central-api/main-api/logs/ -mtime +30 -delete

# ลบ PDF payslip เก่า
find /home/dev/vtrc-api/api-storage/prs/ -mtime +30 -delete

# prune docker image ที่ไม่ได้ใช้
docker image prune -f

# แจ้งผล
echo "Cleanup completed at $(date)" >> /var/log/vtrc-cleanup.log
EOF
chmod +x /etc/cron.daily/vtrc-cleanup

การ monitor disk อัตโนมัติ

bash
cat > /usr/local/bin/check-disk.sh <<'EOF'
#!/bin/bash
THRESHOLD=80
ALERT_EMAIL="ops@redcross.or.th"

df -H | awk -v threshold=$THRESHOLD '
    NR>1 && $5+0 > threshold {
        print "WARNING: " $5 " usage on " $6 " at " $4
    }
' | while read line; do
    echo "$line" | mail -s "VTRC Disk Alert" $ALERT_EMAIL
done
EOF
chmod +x /usr/local/bin/check-disk.sh

# รันทุกชั่วโมง
echo "0 * * * * /usr/local/bin/check-disk.sh" | crontab -

กลยุทธ์การสำรองข้อมูล

แนวทาง 3-2-1

  • 3 สำเนาของข้อมูล
  • 2 ประเภทสื่อที่แตกต่างกัน (เช่น disk + tape หรือ disk + cloud)
  • 1 สำเนองเก็บนอกไซต์

ปัจจุบันระบบมี 1 สำเนา (บน host เดียวกับ service) — ต้องเพิ่ม

สิ่งที่ต้องสำรอง

ข้อมูลวิธี backupความถี่RPO
MariaDB vtrc schemamysqldumpทุกวัน24 ชม.
MariaDB vtrc-centralize schemamysqldumpทุกวัน24 ชม.
MSSQL HRMIBACKUP DATABASEทุกวัน24 ชม.
Redis dumpBGSAVE + copyทุกวัน24 ชม.
File storage (PDF, upload)rsyncทุกวัน24 ชม.
nginx configrsync ไป backup hostทุกสัปดาห์7 วัน
Source codegit (มีอยู่แล้วบน Bitbucket)ต่อ commitนาที
SSL cert + keyrsync ไปที่เก็บปลอดภัยต่อการเปลี่ยนตาม

สคริปต์ backup หลัก

bash
cat > /usr/local/bin/vtrc-backup.sh <<'EOF'
#!/bin/bash
set -e

BACKUP_DATE=$(date +%Y%m%d-%H%M)
BACKUP_ROOT=/backup
BACKUP_DIR=$BACKUP_ROOT/$BACKUP_DATE

mkdir -p $BACKUP_DIR

echo "=== Backup started at $(date) ==="

# 1. MariaDB
echo "Backing up MariaDB..."
mysqldump -h <db-host> -u root -p<password> vtrc | gzip > $BACKUP_DIR/vtrc.sql.gz
mysqldump -h <db-host> -u root -p<password> vtrc-centralize | gzip > $BACKUP_DIR/vtrc-centralize.sql.gz

# 2. Redis
echo "Backing up Redis..."
docker exec vtrc-redis redis-cli BGSAVE
sleep 5
cp /home/dev/vtrc-api/redis-db/data/dump.rdb $BACKUP_DIR/vtrc-redis.rdb

# 3. File storage
echo "Backing up file storage..."
rsync -a /home/dev/vtrc-api/api-storage/ $BACKUP_DIR/api-storage/

# 4. Config
echo "Backing up config..."
tar -czf $BACKUP_DIR/config.tar.gz \
    /home/dev/vtrc-api/docker-compose.yml \
    /home/dev/vtrc-api/.env \
    /home/dev/vtrc-api/nginx/ \
    /home/dev/vtrc-api/cert/

# 5. ส่งไปยัง off-site (เช่น GCS)
echo "Uploading to off-site..."
gsutil -m rsync -r $BACKUP_DIR gs://vtrc-backup/$BACKUP_DATE/

# 6. ลบ backup เก่ากว่า 30 วัน (local)
find $BACKUP_ROOT -maxdepth 1 -type d -mtime +30 -exec rm -rf {} \;

# 7. ลบ backup เก่ากว่า 90 วัน (off-site)
gsutil -m rm -r $(gsutil ls gs://vtrc-backup/ | head -n -90)

echo "=== Backup completed at $(date) ==="
EOF
chmod +x /usr/local/bin/vtrc-backup.sh

# รันทุกคืน 02:00
echo "0 2 * * * /usr/local/bin/vtrc-backup.sh >> /var/log/vtrc-backup.log 2>&1" | crontab -

การทดสอบ restore

สำคัญมาก — backup ที่ไม่เคยทดสอบ restore ถือว่าไม่มีอยู่จริง

bash
# ทดสอบเดือนละครั้งใน UAT server

# 1. Restore database ไปยัง UAT
mysql -h <uat-db> -u root -p vtrc_test < /backup/vtrc-20250711-0200.sql

# 2. ตรวจสอบ
mysql -h <uat-db> -u root -p vtrc_test -e "SELECT COUNT(*) FROM Users;"

# 3. Restore file storage
rsync -a /backup/api-storage/ /uat/api-storage/

# 4. Start service ใน UAT แล้วทดสอบ

# 5. บันทึกผล
echo "Restore test $(date): ผ่าน" >> /var/log/vtrc-restore-test.log

แผนกู้คืนจากภัยพิบัติ (DR plan)

นิยาม

  • RTO (Recovery Time Objective) — เวลาสูงสุดที่ระบบสามารถ down ได้หลังเกิดเหตุ
  • RPO (Recovery Point Objective) — ปริมาณข้อมูลสูงสุดที่ยอมเสียได้ (วัดเป็นเวลา)

ค่าเป้าหมายที่ควรตั้ง:

ServiceRTORPO
vtrc-api4 ชม.24 ชม.
vtrc-web2 ชม.24 ชม. (static ไม่ค่อยเปลี่ยน)
cu-central-api4 ชม.24 ชม.
centralize-api8 ชม.24 ชม. (สำคัญน้อยกว่า)
database2 ชม.1 ชม. (critical)

สถานการณ์วิกฤตที่ต้องวางแผน

สถานการณ์ 1 — Host down

อาการ: production host ไม่สามารถเข้าถึงได้ (hardware fail, OS crash)

ขั้นตอน:

  1. ตรวจสอบว่าเป็นปัญหาถาวรหรือชั่วคราว
  2. สร้าง host ใหม่ (อาจใช้ GCP VM แทน on-prem)
  3. ติดตั้ง Docker, docker-compose
  4. ดึง image จาก GCR
  5. Restore database จาก backup ล่าสุด
  6. Restore file storage
  7. ปรับ DNS ให้ชี้ไป host ใหม่
  8. ทดสอบการทำงาน

สถานการณ์ 2 — Database corruption

อาการ: MariaDB ไม่ start หรือ data corrupt

ขั้นตอน:

  1. หยุด vtrc-api ทุก replica
  2. สำรอง data ที่เหลืออยู่ (ถ้าเป็นไปได้)
  3. Drop schema ที่ corrupt
  4. Restore จาก backup ล่าสุด
  5. Apply binlog ถ้ามี (เพื่อกู้ข้อมูลหลัง backup)
  6. Restart vtrc-api

สถานการณ์ 3 — Ransomware / data breach

อาการ: ผู้ไม่ประสงค์ดีเข้าถึงระบบ, encrypt data

ขั้นตอน:

  1. ตัด network — ปิด external access ทันที
  2. เก็บ evidence — snapshot disk, log, memory
  3. แจ้งทีม security และผู้บริหาร
  4. หยุด service ทั้งหมด
  5. สำรองข้อมูลที่เหลือ (ถ้ายังไม่ถูก encrypt)
  6. Wipe host และ rebuild จาก image ใหม่
  7. Restore data จาก backup off-site
  8. เปลี่ยน password ทั้งหมด — database, JWT secret, device key, LDAP
  9. Audit ว่ามีข้อมูลรั่วไหลอะไรบ้าง
  10. แจ้งผู้ใช้ ถ้ามีข้อมูลส่วนบุคคลรั่วไหล (PDPA obligation)

สถานการณ์ 4 — Data center failure

อาการ: on-prem data center ทั้งหมดไม่ใช้งานได้ (ไฟดับ, อัคคีภัย, อุทกภัย)

ขั้นตอน:

  1. เปิดใช้งาน DR site (วางแผนไว้ล่วงหน้า)
  2. Restore service ที่ DR site จาก off-site backup
  3. ปรับ DNS ให้ชี้ไป DR
  4. แจ้งผู้ใช้

หมายเหตุ: VTRC ยังไม่มี DR site อย่างเป็นทางการ — ต้องวางแผน

ลำดับการ restore

เมื่อเกิดเหตุและต้อง restore ทั้งระบบ ให้ทำตามลำดับนี้:

  1. database — MariaDB, MSSQL
  2. Redis — session, cache
  3. File storage — PDF, upload
  4. Backend service — vtrc-api, cu-central-api, centralize-api
  5. Frontend — vtrc-web, vtrc-rc-backoffice
  6. External integration — LDAP, KBank, FCM

การสื่อสารตอนเกิดเหตุ

  • แจ้งผู้บริหารทันทีเมื่อระบบ down เกิน 15 นาที
  • อัปเดตสถานะทุก 30 นาที จนกว่าจะกลับมาปกติ
  • หลังเหตุสงบ ทำ postmortem ภายใน 48 ชม.

Postmortem template

หลังเกิดเหตุ ทำ postmortem เพื่อเรียนรู้:

markdown
# Postmortem: <ชื่อเหตุการณ์>

## วันเวลาที่เกิด
- เริ่ม: YYYY-MM-DD HH:MM
- กลับปกติ: YYYY-MM-DD HH:MM
- ระยะเวลา down: X ชม. Y น.

## ผลกระทบ
- ผู้ใช้ที่ได้รับผล: X คน
- Feature ที่ไม่ใช้งานได้: ...

## สาเหตุ
(อธิบาย root cause)

## Timeline
- HH:MM — ตรวจพบ
- HH:MM — เริ่มแก้ไข
- HH:MM — กลับมาปกติ

## สิ่งที่ทำได้ดี
- ...

## สิ่งที่ต้องปรับปรุง
- ...

## Action items
- [ ] ใคร: ทำอะไร ภายในเมื่อใด

แนะนำ

  1. เก็บ backup off-site เสมอ — GCS, S3, หรือ host อื่น
  2. ทดสอบ restore เดือนละครั้ง — backup ที่ไม่เคย restore test ไม่มีคุณค่า
  3. เขียน DR runbook ให้ครบ — ทุกคนในทีมต้องทำตามได้
  4. เก็บ runbook นอก server — ถ้า server down, ต้องยังเข้าถึง runbook ได้
  5. ทำ chaos engineering — ทดสอบว่าระบบทนต่อ failure ได้แค่ไหน
  6. กำหนด on-call rotation — ใครรับผิดชอบตอนเกิดเหตุนอกเวลางาน