Files
story/docs/offsite-backup.md

122 lines
6.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 阿里云OSS异地备份适配与门禁
## 1. 目标
本能力把`platform-backup.service`生成并校验过的加密归档复制到阿里云OSS,上传后重新下载到受控临时目录并复算SHA-256,只有源归档、远端回读文件和远端摘要文件三者一致才记录`verified`。
本地备份已经加密,OSS仍应使用私有Bucket、最小权限RAM角色、服务端加密、版本控制、生命周期和必要的跨区域复制。仓库不保存AccessKey、STS令牌或ossutil配置正文。
## 2. 当前环境状态
目标ECS已安装并校验`ossutil 2.3.0`,客户端压缩包使用阿里云文档公布的Linux x86_64 SHA-256验证。2026-08-26通过IMDSv2实测实例地域为`cn-hangzhou`,RAM角色元数据返回404;当前实例没有绑定RAM角色,也没有配置OSS Bucket,因此:
- `OFFSITE_BACKUP_ENABLED=false`;
- 定时器已安装并保持活动,但任务只记录`disabled/not_enabled`;
- 健康监测记录`offsite_backup=healthy/not_required`;
- 不把当前状态声明为异地备份完成。
## 3. 上传与验证流程
```text
选择最新本机加密归档
→ 验证本机外层SHA-256
→ 上传归档到OSS私有路径
→ 上传SHA-256旁路文件
→ 从OSS重新下载归档与摘要
→ 重新计算下载文件SHA-256
→ 三方摘要一致
→ 原子写入platform-offsite-backup-v1状态
```
上传和下载均固定为单任务、单文件并发,避免在当前2核小规格服务器上争抢资源。大于ossutil阈值的文件使用断点续传,检查点保存在`/var/lib/data-terminal-cloud-offsite/checkpoints`。
状态文件位于`/var/lib/data-terminal-cloud-offsite/status.json`,只包含源文件名、OSS对象引用、SHA-256、大小、验证时间和稳定原因,不包含凭据。
## 4. 安装
```bash
cd /opt/data-terminal-cloud/current
chmod 0755 deploy/server/install-ossutil.sh \
deploy/server/install-offsite-backup.sh \
deploy/server/sync-backup-offsite.sh
deploy/server/install-offsite-backup.sh
systemctl list-timers platform-offsite-backup.timer --no-pager
```
安装器固定下载`ossutil 2.3.0`并校验官方SHA-256;已有同版本时不会重复下载。若服务器没有`unzip`,使用Python标准库解压。
## 5. OSS准备
业务方或云管理员需要在阿里云控制台完成:
1. 创建私有OSS Bucket,确定地域、版本控制、服务端加密和生命周期策略;
2. 优先给ECS绑定最小权限实例RAM角色,避免长期AccessKey落盘;
3. 授权该角色仅能向指定Bucket前缀上传、读取和查询备份对象;
4. 如需地域级灾备,为目标Bucket配置跨区域复制;
5. 推荐直接使用脚本的`ecs_ram_role`模式;该模式通过IMDSv2确认角色存在,再让ossutil自动取得短期STS凭据,不需要AccessKey或ossutil凭据文件。
当前脚本需要上传后回读,因此至少要具备指定前缀的写入和读取权限。Bucket创建、RAM授权和跨区域复制属于云资源变更,不能通过服务器root账号替代完成。
## 6. 启用
编辑`/etc/data-terminal-cloud/offsite-backup.env`:
```bash
OFFSITE_BACKUP_ENABLED=true
OFFSITE_BACKUP_REQUIRED=true
OFFSITE_OSS_BUCKET=your-private-backup-bucket
OFFSITE_OSS_PREFIX=data-terminal-cloud/121.41.46.238
OFFSITE_OSS_AUTH_MODE=ecs_ram_role
OFFSITE_OSS_REGION=cn-hangzhou
OFFSITE_OSS_ENDPOINT=oss-cn-hangzhou.aliyuncs.com
OFFSITE_OSS_CONFIG_FILE=/etc/data-terminal-cloud/ossutilconfig
```
`OFFSITE_OSS_CONFIG_FILE`只在`OFFSITE_OSS_AUTH_MODE=config`时读取,用于兼容受控配置文件或隔离测试;阿里云ECS正式路径使用`ecs_ram_role`。脚本强制通过IMDSv2获取元数据令牌,不回退IMDSv1。角色缺失时任务以`ecs_ram_role_missing`失败,不会继续读取本机归档或尝试匿名访问OSS。
然后执行:
```bash
systemctl start platform-offsite-backup.service
systemctl show platform-offsite-backup.service -p Result -p ExecMainStatus
python3 -m json.tool /var/lib/data-terminal-cloud-offsite/status.json
systemctl start platform-health-monitor.service
```
期望异地状态为`verified`,健康状态中的`offsite_backup`为`healthy`。启用或设为必需后,缺状态、上传失败、回读失败、摘要不一致、源归档不匹配或超过36小时都会令健康检查进入critical。
## 7. 定时与保留
本机备份默认在02:40执行并带最多45分钟随机延迟;OSS同步默认在04:10执行并带最多30分钟随机延迟。OSS侧历史保留应由Bucket生命周期和版本控制管理,脚本不会主动删除远端对象,避免错误配置扩大为批量删除。
## 8. 失败语义
| 原因 | 含义 |
|---|---|
| `ossutil_missing` | 官方客户端未安装 |
| `curl_missing` | ECS RAM角色模式缺少IMDSv2请求客户端 |
| `oss_config_missing` | 身份配置不可读 |
| `ecs_metadata_v2_unavailable` | 无法取得IMDSv2元数据令牌 |
| `ecs_ram_role_missing` | ECS未绑定实例RAM角色或角色名称无效 |
| `invalid_oss_region` / `invalid_oss_endpoint` | OSS地域或端点配置不合法 |
| `local_backup_missing` | 没有本机加密备份 |
| `local_checksum_failed` | 本机归档已损坏 |
| `archive_upload_failed` | OSS归档上传失败 |
| `checksum_upload_failed` | OSS摘要上传失败 |
| `archive_download_verification_failed` | 远端归档无法回读 |
| `checksum_download_verification_failed` | 远端摘要无法回读 |
| `remote_checksum_mismatch` | 回读内容与源归档不一致 |
失败状态会原子写入状态文件并使systemd任务失败;本机已验证备份不会被删除。
## 9. 已执行验证
- 禁用状态:任务成功记录`disabled/not_enabled`,不访问OSS;
- 隔离兼容目标:上传归档和摘要、回读并复算,状态为`verified`且远端有2个文件;
- 缺身份配置:退出4并记录`failed/oss_config_missing`;
- ECS RAM角色缺失:在目标阿里云实例通过IMDSv2实测退出4并记录`failed/ecs_ram_role_missing`;
- 兼容配置模式:隔离OSS替身完成上传、摘要上传、双回读和三方摘要一致校验;
- 健康门禁:设为必需但缺远端状态时退出1并记录`offsite_backup=critical/status_missing`。
隔离兼容目标只验证脚本控制流与摘要闭环,不是阿里云真实Bucket证据。真实门禁必须在配置RAM角色和私有Bucket后重新执行。