技术指南
Restic 异地备份:从首次快照到恢复演练
用 Restic 建立加密异地快照,从仓库初始化、R2 凭据隔离到完整检查与恢复演练。
Restic 能把文件加密、去重后保存为可追溯快照,但“命令返回成功”不等于数据已经可恢复。先定义允许丢失多少数据、恢复必须多快完成,再用一次本地仓库走通初始化、备份、检查和隔离恢复;确认流程后,才把同一方法接到 Cloudflare R2 等异地对象存储。
先写清恢复目标
| 对象 | 一致性方法 | 需要记录的结果 |
|---|---|---|
| 静态文件与配置 | 直接纳入快照;排除可重建缓存 | 快照 ID、文件数、校验抽查 |
| MySQL / PostgreSQL | 先用数据库官方工具生成逻辑或物理备份 | 导出退出码、版本、隔离导入结果 |
| 正在写入的应用目录 | 应用快照、维护窗口或官方备份接口 | 写入暂停点、恢复顺序、验收查询 |
| 密钥与仓库密码 | 与仓库分开保管的受控副本 | 保管人、轮换日、取回演练 |
3-2-1 可以用来检查故障域,但不是完成证明:生产数据、本机仓库和同一账号下的对象存储可能仍被一组凭据同时删除。VPScope 的判断是,恢复时间、删除权限和凭据隔离比机械地数副本更重要。
安装后先确认版本
优先使用发行版受支持的软件包。若业务需要上游新版本,应从 Restic 官方发布页下载与架构匹配的文件,并按同一发布提供的校验清单核对;不要使用未固定版本、未校验的“latest”下载链接。当前官方稳定文档为 0.19.1,实际执行仍以 `restic version` 的输出为准。
sudo apt update
sudo apt install restic
restic version先用本地仓库走通闭环
下面把测试输入、仓库位置和秘密文件分开。`/srv/backup-input` 只放已经达到应用一致性的输入,例如数据库导出和静态文件;不要把正在写入的数据库数据目录直接当成一致备份。生成密码后,先将其保存到独立的密码管理或受控密钥库,再初始化仓库。
sudo install -d -m 0750 /srv/backup-input /srv/restic-repo
sudo install -d -m 0700 /etc/restic
sudo sh -c 'umask 077; openssl rand -base64 32 > /etc/restic/repository-password'
printf '%s\n' /srv/restic-repo | sudo tee /etc/restic/repository >/dev/null
sudo chmod 0600 /etc/restic/repository /etc/restic/repository-password
sudo restic --repository-file /etc/restic/repository \
--password-file /etc/restic/repository-password initsudo restic --repository-file /etc/restic/repository \
--password-file /etc/restic/repository-password \
backup /srv/backup-input --tag manual --exclude='*.tmp'
sudo restic --repository-file /etc/restic/repository \
--password-file /etc/restic/repository-password snapshots再切换到 R2 异地仓库
Cloudflare 官方文档给出的 S3 端点是 `https://<ACCOUNT_ID>.r2.cloudflarestorage.com`。新建私有 bucket,并创建只限该 bucket 的 Object Read & Write 令牌;Secret Access Key 只显示一次。Restic 的维护和 prune 需要读写及删除对象,因此不能把令牌缩成只读。若删除权限与生产主机放在一起,异地并不等于防删除。
AWS_ACCESS_KEY_ID=REPLACE_WITH_BUCKET_SCOPED_KEY
AWS_SECRET_ACCESS_KEY=REPLACE_WITH_SECRETs3:https://ACCOUNT_ID.r2.cloudflarestorage.com/BUCKET/vps-restic在受控的 root 会话中读取 `r2.env`,再用 `--repository-file /etc/restic/repository-r2` 和同一 password file 执行一次 `init`、备份与恢复。不要把密钥直接写成 `export AWS_SECRET_ACCESS_KEY=...` 留在 shell 历史。自动化时让 systemd 通过仅 root 可读的 `EnvironmentFile` 注入这两个变量,并检查失败退出码。
把恢复演练当成发布门
每次策略变更后,先恢复到空的隔离目录。Restic 会在目标目录下重建快照中的路径;不要直接覆盖生产。核对文件、权限、应用版本和数据库导入,再记录快照 ID、耗时与验收结果。`check` 验证仓库结构,`--read-data` 会读取全部 pack,适合按容量安排周期性深度检查。
sudo install -d -m 0750 /srv/restore-drill
sudo restic --repository-file /etc/restic/repository \
--password-file /etc/restic/repository-password check --read-data
sudo restic --repository-file /etc/restic/repository \
--password-file /etc/restic/repository-password \
restore latest --target /srv/restore-drill
find /srv/restore-drill -type f -print | head -50先预演保留,再允许删除
保留周期必须覆盖误删被发现的时间,并匹配 RPO、容量和合规要求。下面只是示例。Restic 官方说明 `forget` 先移除快照,`--prune` 才回收不再引用的数据;prune 会锁定仓库且可能耗时。先用 `--dry-run` 审阅 keep/remove 清单,完成最新恢复演练,并确认没有并发备份后再执行。
sudo restic --repository-file /etc/restic/repository \
--password-file /etc/restic/repository-password \
forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --dry-run
# 审阅清单并完成恢复演练后,才在维护窗口执行:
sudo restic --repository-file /etc/restic/repository \
--password-file /etc/restic/repository-password \
forget --keep-daily 7 --keep-weekly 4 --keep-monthly 6 --prune可交付的验收记录
- 备份任务非零退出时能告警,日志不包含密码、Access Key 或 Secret。
- 最新与至少一个旧快照都能恢复到隔离目录,并通过应用级只读检查。
- 仓库密码可从独立保管位置取回;R2 令牌能轮换且只作用于指定 bucket。
- 定期执行仓库检查,容量允许时安排 `check --read-data`;失败会阻止后续 prune。
- 保留 dry run、恢复耗时、快照 ID、客户端版本和验收人,下一次演练可以复现。