本文介绍如何在 CentOS 上完成目录级文件备份,并通过强大的开源工具 rclone 将备份包上传至 Google 云盘、阿里云盘等对象存储中。通过 Systemd 定时任务,实现重要文件的每日快照备份,便于在新机器或 VM 虚拟机中快速还原环境。

1. 部署 Rclone

1.1 安装与初始化

        首先安装 Rclone 工具,并进入配置向导:

# 一键安装
curl [https://rclone.org/install.sh](https://rclone.org/install.sh) | bash

# 开始配置
rclone config

1.2 配置 Google Drive

        在配置向导中,请按照以下步骤操作(以 Google Drive 为例):

  1. 新建配置:输入 n (New remote)。
  2. 命名:输入 gdrive(或者你喜欢的名字,需与脚本中保持一致)。
  3. 存储类型:输入 20 (Google Drive)。
  4. Client ID/Secret:建议使用自己的 API 凭据以获得更好的稳定性。获取方法参考官方文档 Making your own client_id。如果留空则使用 Rclone 公共凭据(高峰期易限流)。
  5. 权限范围:输入 1 (Full access to all files)。
  6. Service Account:按 Enter 跳过(默认不使用)。
  7. 高级配置:输入 n (No)。
  8. Web 验证

    • 如果是 VPS(无浏览器),输入 n
    • Rclone 会生成一段命令,请在本地有浏览器的电脑(Windows/Mac)上下载 Rclone 并执行该命令。
    • 浏览器授权后,会获得一串 config_token,复制并粘贴回 VPS 的终端。
  9. 共享云端硬盘:输入 n (不配置 Team Drive)。
  10. 保存配置:输入 y

        配置完成后,测试连接是否成功:

rclone lsd gdrive:/
# 如果列出了网盘根目录的文件夹,说明配置成功

2. 编写备份脚本

        创建备份脚本 /usr/local/bin/system-backup.sh,保存以下内容,并赋予执行权限 chmod +x /usr/local/bin/system-backup.sh

        优化说明:此版本脚本增加了 --drive-use-trash=false 参数,防止删除的旧备份进入 Google Drive 回收站导致空间爆满。

#!/bin/bash
# 取消 set -e,防止 tar 在打包 socket 文件时报 warning 导致脚本意外中断
# set -e 

# 配置项
DATE=$(date +%F)
BACKUP_DIR="/backup"
BACKUP_FILE="$BACKUP_DIR/system-backup-$DATE.tar.gz"
LOG_FILE="/var/log/backup.log"
MAX_RETRY=3

# 日志输出
mkdir -p "$(dirname "$LOG_FILE")"
exec > >(tee -a "$LOG_FILE") 2>&1

echo "[*] $(date '+%F %T') 开始备份任务"

# 创建备份目录
mkdir -p "$BACKUP_DIR"

# 使用 tar 备份根目录
# --exclude: 排除虚拟目录、挂载点和备份目录自身
# --warning=no-file-changed: 忽略文件在读取时发生变化的警告
for ((i=1; i<=MAX_RETRY; i++)); do
    echo "[*] 第 $i 次尝试打包备份..."
    if tar --exclude=/proc --exclude=/sys --exclude=/dev --exclude=/run --exclude=/mnt --exclude=/media --exclude=/lost+found --exclude="$BACKUP_DIR" --warning=no-file-changed -czpf "$BACKUP_FILE" /; then
        echo "[✓] 备份成功:$BACKUP_FILE"
        break
    else
        echo "[!] 第 $i 次备份失败,600 秒后重试..."
        sleep 600
    fi
done

# 检查是否生成了备份文件
if [ ! -f "$BACKUP_FILE" ]; then
    echo "[✗] 所有尝试均失败,未生成备份文件,终止脚本"
    exit 1
fi

# 上传到 Google Drive
echo "[*] 上传至 Google Drive..."
if rclone copy "$BACKUP_FILE" gdrive:/backup/; then
    echo "[✓] 上传成功"
else
    echo "[✗] 上传失败"
    # 上传失败是否继续清理旧备份?通常建议保留旧备份以防万一
    # exit 1 
fi

# 删除本地 7 天前的旧备份
echo "[*] 清理本地 7 天前的备份..."
find "$BACKUP_DIR" -type f -name "*.tar.gz" -mtime +7 -delete

# 删除 Google Drive 中 14 天前的旧备份
# --drive-use-trash=false: 强制永久删除,不进回收站,防止空间占满
echo "[*] 清理 Google Drive 中 14 天前的旧备份..."
rclone delete --min-age 14d gdrive:/backup/ --include "*.tar.gz" --drive-use-trash=false

echo "[✓] 任务完成:$(date '+%F %T')"

3. 配置定时任务

        为了管理方便和日志记录,我们使用 Systemd Timer 来替代 Crontab。

  1. 创建服务单元 /etc/systemd/system/backup.service

    [Unit]
    Description=System Backup Service
    
    [Service]
    Type=oneshot
    ExecStart=/usr/local/bin/system-backup.sh
  2. 创建定时器 /etc/systemd/system/backup.timer

    [Unit]
    Description=Run backup daily
    
    [Timer]
    # 每天凌晨 3 点执行
    OnCalendar=*-*-* 03:00:00
    # 任务如果错过(关机),开机后立即执行
    Persistent=true
    
    [Install]
    WantedBy=timers.target
  3. 启用并启动定时任务:

    sudo systemctl daemon-reload
    sudo systemctl enable --now backup.timer

4. 还原文件

        当需要恢复数据时,首先从网盘下载备份包到本地。

[!WARNING] 警告
        切勿在运行中的系统上直接解压覆盖根目录 (/)! 这会导致系统配置文件(如 fstab, shadow, network)被覆盖,极大概率导致系统崩溃无法启动。

        正确的还原姿势:

  1. 提取特定文件:解压到临时目录,手动提取需要恢复的配置或数据文件。

    mkdir /tmp/restore
    tar -xzp -C /tmp/restore -f system-backup-xxxx.tar.gz
    # 然后从 /tmp/restore 中拷贝你需要的文件
  2. 全量还原:请使用 Live CD (救援模式) 启动机器,挂载目标磁盘,然后解压备份包到挂载点。