restic 加密备份自动化实战:增量、去重、异地与保留策略


上一轮聊过 Docker 的卷备份,但"本地 tar 包"离真正的备份还差三件事:有没有异地一份、有没有加密、有没有历史版本可回退。这三件事正是 restic 的看家本领。restic 是一个快照式、加密、去重的备份工具:每次备份生成的快照只存下与上一次不同的数据块,配合一份保留策略,既省空间又能回滚任意历史版本。

一、快照、去重、加密:restic 的三个核心机制

restic 把要备份的目录先分块(chunk),再对每个块计算哈希,相同的块只存一次——这就是去重,也是"改动 5%,却只多存 5%"的来源。每个备份点是 snapshot,记录了那一刻的文件列表与对应数据块,恢复时按快照回放即可,所以"快照"不是整份拷贝,而是一张指向数据块的索引。

安全性上,restic 用你设置的密码做驱动,派生加解密密钥后再"锁"进远端;即使备份仓库被拖走,没有密码也读不出内容。要注意区分两种密码的使用场景:初始化仓库(init)时设置的密码用于加解锁快照;而如果你对接对象存储(S3 或兼容 API),还可能要分别配置访问密钥——两者不要混为一谈。

二、先建仓库,再做第一次备份

# 本机初始化本地仓库
restic -r /srv/backup/restic init

# 备份某个目录,--exclude 排除没必要入库的
restic -r /srv/backup/restic backup /srv/data \
  --exclude-caches \
  --exclude '*.log' \
  --exclude /srv/data/tmp

restic -r /srv/backup/restic snapshots

把 -r 换成远程路径就是异地备份:restic 原生支持 SFTP、整套 S3 兼容存储、REST server、以及 B2 / Azure 等。最稳的一种"异地"其实是放在另一台 VPS B 上的 SFTP 目录或 S3 存储桶,因为它在物理上离开了本机。第一次备份是慢的(全量),之后都是增量,所以"备份很慢"通常只发生在初始化那天。

三、保留策略:forget 与 prune 一起用

快照会越积越多,必须给它们设一个废弃策略。restic 用 forget 决定"哪些快照不能删"(按时间、保留个数、保留最后 N 个 hourly/daily/weekly/monthly/yearly),用 prune 真正回收那些不再被任何快照引用的数据块。两者必须配合:只 forget 不 prune,只是删了"索引",磁盘还是满的——这是新手最常见的误解。

restic -r $REPO forget \
  --keep-daily 7 --keep-weekly 4 --keep-monthly 6 \
  --prune

一条常见的策略是"保留最近 7 个日快照、4 个周快照、6 个月快照",即约半年左右的粒度。写入落盘后可用 restic check 校验仓库完整性、用 restic check --read-data 抽查能否通读数据。prune 是重操作,会遍历去重块,建议放在低峰时段定期跑。

四、自动化:systemd timer 而不是"交给 crontab 随手写一行"

备份要"每天自动且失败可查",成型的做法是用 systemd 的 service + timer 组合,而不是裸 crontab。写一个一元的备份单元:/etc/systemd/system/restic-backup.service 定义"备份 + 打日志",对应的 restic-backup.timer 定义触发时间(如每天 03:30)。相比 crontab,systemd 能把运行环境、依赖、失败重启、日志统一管理,还能在失败时通过 on-failure 触发通知。

# /etc/systemd/system/restic-backup.timer
[Unit]
Description=Daily restic backup
[Timer]
OnCalendar=03:30
Persistent=true
[Install]
WantedBy=timers.target

Persistent=true 是个容易忽略却重要的选项:它让漏跑的任务在下次开机后补跑,而不是系统恰好停机错过一天就没备份。备份里包含的路径、exclude 规则应集中在一个环境文件里维护,避免散落在多个 crontab 行中。

五、恢复是另一半:到底该信任哪份快照

备份越完善,越要回答一个问题:真出事时,我能在陌生机器上把服务还原到哪个时刻?restic 恢复分两步,先 snapshots 找到目标快照 id,再 restore LATEST 指定要还原到的路径:

restic -r $REPO restore latest \
  --target /opt/restored \
  --include /srv/data/db

最容易疏漏的是"文件权限与属主":restic 默认带元数据恢复,但在 docker 重启服务前,仍要确认 restored 目录的属主与你 compose 里声明的 UID 一致,否则服务起来又读出个 "Permission denied"。恢复之后建议做一次最小演练:起一个临时容器从还原目录启动关键服务,确认读得到数据再正式切换。备份的真价值在恢复那天兑现,不演练的备份方案等于没做。

六、监控与告警:把"备份失败"变成一件会通知你的事

备份失败比没备份更隐蔽——你以为有了,实际没有。得让每次备份的成功/失败变成一个可观测信号:最简单的做法是在 service 里用 OnFailure=notify-backup-failure.service,在失败时给脚本发一份通知(Telegram / 邮件);进阶做法把 restic 的指标暴露给 Prometheus(官方提供 restic 的 job 与 node-exporter 配合),把"备份新鲜度"也挂进监控看板。衡量备份是否健康的指标里,"最后一次成功备份距今多久"比"晚上跑得顺不顺利"更有意义。

结语

restic 的价值在于把"加密 + 去重 + 异地 + 严格保留策略"这几件之前要么昂贵、要么相互打架的事,合并成一条命令就能表达的管线。它的运行模型(快照索引数据块)和资源开销都很透明,配合 systemd timer 做自动化、Prometheus 做可观测,一次搭好后的维护成本几乎为零。备份这件事真正要从"做过"进步到"敢依赖",靠的正是这套可验证、可回滚、可告警的闭环,而不是堆在高容硬盘上的一堆 tar 包。


手机扫码阅读

微信或手机浏览器扫一扫,随时随地随心阅读与分享

Gitea + Gitea Actions 自托管 CI/CD:代码托管与自动发布一把抓

WireGuard 自建异地组网实战:一台 VPS 把家里、公司、手机连成内网

评 论
更换验证码