跳到主要内容
注册无需实名认证
安云主机 AnYun VPS

教程 · 安全加固

用 restic 做自动异地备份(顺便说清楚快照不是备份)

难度

高级

预计时长

35 分钟

步骤

8

最近修订

基准系统

Debian 12

要点

用 restic 做自动异地备份(顺便说清楚快照不是备份)

restic 提供去重、加密、增量的备份仓库,配合 systemd timer 可以每天自动备份并按策略清理旧快照。控制台快照与备份是两回事:快照通常与源机器在同一机房、同一账号之下,机房级故障或账号问题会连同快照一起失去 —— 只有落在另一台机器、另一个机房的副本才算备份。

前置条件

开始之前,先确认这些都具备

  • 一台待备份的服务器,以及一个存放备份的目标(另一台 VPS、存储型机器或对象存储)
  • 两台机器之间已配置 SSH 密钥登录
  • 想清楚要备份哪些目录 —— 这一步不想清楚,后面全是白做

操作步骤

8

  1. 步骤 01 / 08

    先列清单:什么必须备份,什么不必 #

    备份整块磁盘既慢又贵,而且恢复时你会发现真正需要的只有几个目录。典型清单是:配置(/etc)、网站文件(/var/www)、用户数据(/home)、数据库导出文件。系统本身不用备 —— 重装一遍比恢复更快。把这份清单写进文档,它比脚本更重要。

    Shell
    # 先看看各目录到底多大,再决定备份范围
    sudo du -sh /etc /home /var/www /var/lib/docker 2>/dev/null | sort -h
  2. 步骤 02 / 08

    安装 restic 并初始化仓库 #

    仓库密码一旦丢失,备份数据就永久打不开了 —— restic 是端到端加密的,没有找回机制。密码存进密码管理器,同时抄一份放在离线的地方。

    Shell
    sudo apt update && sudo apt install -y restic
    restic version
    
    sudo mkdir -p /etc/restic
    # 生成一个强随机密码(务必另存一份到密码管理器)
    sudo sh -c 'openssl rand -base64 32 > /etc/restic/password'
    sudo chmod 600 /etc/restic/password
    
    export RESTIC_REPOSITORY="sftp:[email protected]:/srv/restic/web01"
    export RESTIC_PASSWORD_FILE=/etc/restic/password
    
    restic init
  3. 步骤 03 / 08

    先跑一次手动备份 #

    自动化之前先手动跑通。第一次是全量,之后 restic 只传输变化的数据块,相同的文件在多台机器之间也只存一份。--exclude-caches 会跳过带 CACHEDIR.TAG 标记的缓存目录。

    Shell
    restic backup /etc /var/www /home \
      --exclude-caches \
      --exclude '/home/*/.cache' \
      --exclude '*.log'
    
    restic snapshots
    restic stats
  4. 步骤 04 / 08

    数据库要先导出,不能直接拷文件 #

    直接备份运行中的数据库数据目录,拿到的很可能是一份无法启动的残缺副本。正确做法是先用官方工具导出一致性快照,再让 restic 备份导出文件。

    Shell
    # PostgreSQL
    sudo -u postgres pg_dump -Fc appdb > /var/backups/appdb.dump
    
    # MySQL / MariaDB
    sudo mysqldump --single-transaction --routines --events appdb > /var/backups/appdb.sql
    
    restic backup /var/backups
  5. 步骤 05 / 08

    用 systemd timer 每天自动跑 #

    timer 比 cron 更适合这件事:失败会进 journald、Persistent=true 保证关机期间错过的任务开机后补跑、RandomizedDelaySec 避免整个机队在同一秒钟一起压向备份服务器。

    systemd 单元
    # /etc/systemd/system/restic-backup.service
    [Unit]
    Description=restic backup
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=oneshot
    Environment=RESTIC_REPOSITORY=sftp:[email protected]:/srv/restic/web01
    Environment=RESTIC_PASSWORD_FILE=/etc/restic/password
    ExecStart=/usr/bin/restic backup /etc /var/www /home /var/backups --exclude-caches
    ExecStart=/usr/bin/restic forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune
    
    # /etc/systemd/system/restic-backup.timer
    [Unit]
    Description=Daily restic backup
    
    [Timer]
    OnCalendar=*-*-* 03:30:00
    RandomizedDelaySec=900
    Persistent=true
    
    [Install]
    WantedBy=timers.target
  6. 步骤 06 / 08

    启用并确认它真的在跑 #

    「配好了」和「在跑」之间隔着一次 enable。list-timers 会告诉你下一次触发时间;几天后再回来看一眼快照数量有没有增加。

    Shell
    sudo systemctl daemon-reload
    sudo systemctl enable --now restic-backup.timer
    
    systemctl list-timers 'restic*'
    sudo systemctl start restic-backup.service
    journalctl -u restic-backup.service -n 50 --no-pager
  7. 步骤 07 / 08

    每季度做一次真实恢复演练 #

    没有验证过的备份不是备份,只是一个让人安心的错觉。恢复到临时目录,打开几个文件确认内容完整 —— 这件事花十分钟,换来的是真正的睡眠质量。

    Shell
    restic snapshots
    restic restore latest --target /tmp/restore-test --include /etc/nginx
    
    ls -R /tmp/restore-test/etc/nginx | head
    restic check --read-data-subset=5%
    
    rm -rf /tmp/restore-test
  8. 步骤 08 / 08

    快照的定位:回滚工具,不是备份 #

    控制台快照适合的场景是「升级前留一个还原点,十分钟内出问题就回滚」。它不适合当备份,因为它通常与源机器在同一机房、同一账号之下:机房级故障、账号异常、误删机器,快照会跟着一起消失。真正的备份必须落在另一台机器、另一个机房 —— 大容量存储型机器(例如 巨舱 1 / JC-1,1 TB)常被用作这种异地副本的落点。

    Shell
    # 3-2-1 原则的最小可用版本:
    #   3 份数据(生产 + 本地 + 异地)
    #   2 种位置或介质
    #   1 份在另一个机房,并且验证过能恢复

常见错误

这一步最容易踩的坑

下面每一条都对应一个真实会发生的故障。先读完再动手,比出问题之后再回来查要省时间。

  • 备份和源数据放在同一台机器上。磁盘坏了、机器被误删、账号出问题,两份一起没。
  • 从没做过恢复演练。绝大多数「备份失效」都是在真正需要恢复的那一天才被发现的。
  • 直接 rsync 或 restic 运行中的数据库数据目录。拿到的文件很可能无法启动,必须先用 pg_dump / mysqldump 导出。
  • 丢失 restic 仓库密码。restic 没有密码找回机制,密码丢了,备份就是一堆随机字节。
  • 只备份不清理。没有 forget --prune,仓库会持续膨胀直到写满目标磁盘,然后备份开始失败,而通常没人在看那个日志。
  • 把控制台快照当备份用。快照回答的是「十分钟前的状态」,不是「机房没了怎么办」。
  • 备份里含明文密钥与 .env 文件,而备份目标机器的防护远不如生产机。备份仓库本身也要按生产标准加固。

这篇教程的边界

  • 命令以 Debian 12 为准。Ubuntu 与 Rocky Linux 的差异只在正文明确标注之处,未标注的部分请以你所用发行版的官方文档为准。
  • 示例中的 IP 来自文档保留段 203.0.113.0/24,域名为 example.com,端口为示意值。复制后必须替换成自己的值, 原样执行不会有任何效果。
  • 教程不能替代备份。任何会改动数据或线上流量的步骤,执行前先确认有一份验证过能恢复的备份。
  • 本站不提供任何用于绕过网络审查的配置或说明,这篇也不例外。

发现命令过时或有误,请发邮件到 [email protected]。 指出错误的邮件比沉默的旧文档有价值得多。

联系 工单
扫码
手机访问

扫码在手机上打开