引言
你是否曾经因为服务器磁盘损坏、误删关键数据、或云服务商宕机而损失过重要数据?在自托管和 VPS 运维中,灾难恢复不是可选功能,而是生存底线。
很多运维人员只做了本地备份,却忽略了"单点故障"的风险——备份本身也存储在同一个磁盘上,一旦磁盘故障,数据和备份同时丢失。
本文将带你从零构建一套完整的 VPS 灾难恢复体系:本地快照 + 异地备份 + 自动化恢复,全程零人工干预。
一、灾难恢复的核心原则
1.1 3-2-1 备份法则
这是数据保护的行业标准:
- 3 份数据副本:原始数据 + 2 个备份
- 2 种不同存储介质:本地磁盘 + 云存储
- 1 份异地备份:物理位置分离的远程存储
1.2 RPO 与 RTO
| 指标 | 含义 | 推荐值 |
|---|---|---|
| RPO(恢复点目标) | 最多丢失多少数据 | ≤ 1 小时 |
| RTO(恢复时间目标) | 恢复服务需要多久 | ≤ 30 分钟 |
二、本地快照策略
2.1 磁盘快照(LVM/ZFS)
如果你的 VPS 使用 LVM 或 ZFS,可以利用原生快照功能:
# 创建 LVM 快照
sudo lvcreate --size 1G --snapshot --name snap-$(date +%Y%m%d-%H%M) /dev/vg0/root
# 查看快照状态
sudo lvs -o +snap_percent
# 自动清理超过 7 天的快照
sudo lvremove -f /dev/vg0/snap-$(date -d '7 days ago' +%Y%m%d-%H%M)
2.2 使用 Timeshift 做系统快照
Timeshift 是 Linux 系统级快照工具,适合整机备份:
# 安装 Timeshift
sudo apt install timeshift
# 创建系统快照
sudo timeshift --create --comments "auto-$(date +%Y%m%d)"
# 配置自动快照(每天 2 点创建)
sudo nano /etc/cron.d/timeshift-daily
# */0 2 * * * root /usr/bin/timeshift --create --comments "daily-$(date +\%Y\%m\%d)" --skip-lvm-restore
三、异地备份:Restic + S3
3.1 为什么选择 Restic?
Restic 是新一代备份工具,相比传统工具优势明显:
- 去重压缩:相同文件只存储一次,节省 70%+ 空间
- 加密传输:端到端 AES-256 加密
- 增量备份:只传输变化的数据块
- 跨平台:Linux / macOS / Windows 通用
3.2 初始化备份仓库
# 安装 Restic
curl -L https://github.com/restic/restic/releases/latest/download/restic_0.17.0_amd64.deb -o restic.deb
sudo dpkg -i restic.deb
# 创建备份仓库(以 S3 兼容存储为例)
export RESTIC_REPOSITORY=s3:s3.amazonaws.com/your-bucket-name
export RESTIC_PASSWORD=your-strong-password
export AWS_ACCESS_KEY_ID=xxx
export AWS_SECRET_ACCESS_KEY=xxx
# 初始化仓库
restic init
3.3 备份脚本
创建 ~/scripts/backup.sh:
#!/bin/bash
set -euo pipefail
export RESTIC_REPOSITORY=s3:s3.amazonaws.com/your-bucket-name
export RESTIC_PASSWORD=your-strong-password
export AWS_ACCESS_KEY_ID=xxx
export AWS_SECRET_ACCESS_KEY=xxx
BACKUP_DIRS=("/home" "/etc" "/var/www" "/opt/app")
LOG_FILE="/var/log/restic-backup.log"
echo "[$(date)] Starting backup..." | tee -a $LOG_FILE
for dir in "${BACKUP_DIRS[@]}"; do
if [ -d "$dir" ]; then
restic backup "$dir" --tag "$(date +%Y%m%d)" >> $LOG_FILE 2>&1
echo "[$(date)] Backed up $dir" | tee -a $LOG_FILE
fi
done
# 保留最近 30 天的快照,清理过期快照
restic prune
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
echo "[$(date)] Backup completed" | tee -a $LOG_FILE
3.4 配置定时任务
# 每 6 小时备份一次
echo "0 */6 * * * /root/scripts/backup.sh" | sudo tee /etc/cron.d/restic-backup
# 设置执行权限
sudo chmod 644 /etc/cron.d/restic-backup
四、监控与告警
4.1 备份健康检查
#!/bin/bash
# ~/scripts/backup-health-check.sh
export RESTIC_REPOSITORY=s3:s3.amazonaws.com/your-bucket-name
export RESTIC_PASSWORD=your-strong-password
export AWS_ACCESS_KEY_ID=xxx
export AWS_SECRET_ACCESS_KEY=xxx
# 验证仓库可达
if ! restic snapshots | grep -q "$(date +%Y-%m-%d)"; then
echo "ALERT: No backup found for today!" | mail -s "Backup Alert" admin@yourdomain.com
exit 1
fi
# 检查备份大小异常
size=$(restic snapshots --json | jq '.[-1].stats.newBytes' 2>/dev/null || echo "0")
if [ "$size" -lt 1000 ]; then
echo "ALERT: Backup size seems异常 small: $size bytes" | mail -s "Backup Alert" admin@yourdomain.com
fi
4.2 集成 Prometheus 监控
# restic_exporter 配置
restic_exporter:
repositories:
- s3:s3.amazonaws.com/your-bucket-name
environment:
- RESTIC_PASSWORD=your-password
五、恢复演练
5.1 单文件恢复
# 列出所有快照
restic snapshots
# 恢复单个文件
restic restore latest --target /tmp/recovered --include "/home/user/docs/report.pdf"
# 恢复整个目录
restic restore latest --target /tmp/recovered --include "/home/user"
5.2 整机恢复
# 在新 VPS 上安装 Restic 和系统
# 恢复系统数据
restic restore latest --target /mnt/root
# 恢复 GRUB
grub-install /dev/vda
update-grub
# 重启系统
reboot
5.3 定期恢复测试
# 每月执行一次恢复测试
sudo crontab -e
# 0 3 1 * * restic restore latest --target /tmp/test-restore && echo "Recovery OK"
六、成本控制技巧
6.1 选择性价比高的存储
| 服务商 | 价格(每 GB/月) | 特点 |
|---|---|---|
| AWS S3 Standard | $0.023 | 标准,可靠 |
| AWS S3 Glacier | $0.00099 | 归档,99.99% 可用性 |
| Backblaze B2 | $0.005 | 最便宜的对象存储 |
| Cloudflare R2 | $0.015 | 零出站流量费 |
6.2 压缩与去重
Restic 默认启用去重和压缩,通常可将 100GB 数据压缩到 20-30GB。配合 zstd 压缩:
# 备份前压缩大文件
restic backup /data --compression=zstd
6.3 生命周期策略
# 在 S3 桶上设置生命周期规则
# 30 天后转入 Glacier,180 天后删除
aws s3api put-bucket-lifecycle-configuration \
--bucket your-bucket-name \
--lifecycle-configuration '{
"Rules": [
{
"ID": "archive-old-backups",
"Status": "Enabled",
"Transitions": [
{"Days": 30, "StorageClass": "GLACIER"}
],
"Expiration": {"Days": 180}
}
]
}'
七、完整自动化方案
7.1 自动化脚本合集
#!/bin/bash
# ~/scripts/daily-ops.sh — 每日运维自动化
set -euo pipefail
echo "=== Daily VPS Operations $(date) ==="
# 1. 执行备份
~/scripts/backup.sh
# 2. 验证备份健康
~/scripts/backup-health-check.sh
# 3. 清理旧快照
restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
# 4. 磁盘空间检查
df -h | awk 'NR==1 || $5+0 > 80 {print "WARNING: "$0}'
# 5. 发送日报
~/scripts/send-daily-report.sh
7.2 完整 crontab 配置
# 每 6 小时备份
0 */6 * * * /root/scripts/backup.sh >> /var/log/restic-backup.log 2>&1
# 每日健康检查
0 8 * * * /root/scripts/backup-health-check.sh
# 每周日完整快照验证
0 3 * * 0 /usr/bin/restic snapshots | head -5
# 每月 1 号恢复演练
0 4 1 * * /usr/bin/restic restore latest --target /tmp/monthly-test --dry-run
总结
构建 VPS 灾难恢复体系不需要复杂的基础设施,核心是:
- 本地快照 — 快速恢复,应对误操作
- 异地备份 — 防止单点故障,应对硬件损坏
- 自动化执行 — 定时任务 + 健康检查,零人工干预
- 定期演练 — 没有测试过的恢复等于没有恢复
记住:备份不是"什么时候需要",而是"什么时候会需要"。现在就花 30 分钟配置 Restic 异地备份,明天你可能会感谢今天的自己。
