15.5.3 数据卷备份、恢复与迁移
在生产环境中,数据卷的备份、恢复与迁移是保障业务连续性与可迁移性的关键环节。本节围绕常见数据卷类型(volume、bind、tmpfs)给出可落地的方法与注意事项。
1. 备份策略与原则#
- 一致性优先:对数据库类服务建议在应用层进行快照或停写后备份,避免脏数据。
- 最小停机:可结合主从复制、只读切换或业务低峰期执行备份。
- 版本化与校验:备份文件带时间戳与版本号,生成校验和(md5/sha256)。
- 可恢复性验证:定期进行恢复演练,确保备份可用。
原理草图(Volume 备份链路)
2. Volume 数据卷备份#
2.1 使用临时容器备份(tar)#
适用场景:Volume 类型数据卷的离线/轻量备份。
# 查看卷
docker volume ls
# 假设数据卷名为 app_data
# 备份到宿主机 /backup 目录
mkdir -p /backup
docker run --rm \
-v app_data:/data:ro \
-v /backup:/backup \
alpine:3.19 \
sh -c "tar -czf /backup/app_data_$(date +%F).tar.gz -C /data ."
# 计算校验和
sha256sum /backup/app_data_*.tar.gz > /backup/app_data_$(date +%F).sha256
命令解释
- -v app_data:/data:ro:以只读挂载数据卷,避免备份时写入。
- -C /data .:打包数据目录内容而非包含目录本身。
2.2 使用 rsync 备份(增量)#
适用场景:数据量大、需要增量同步。
# 安装 rsync(宿主机)
# Ubuntu/Debian
sudo apt-get update && sudo apt-get install -y rsync
# 备份到本地目录 /backup/app_data/
mkdir -p /backup/app_data
docker run --rm \
-v app_data:/data:ro \
-v /backup/app_data:/backup \
alpine:3.19 \
sh -c "apk add --no-cache rsync && rsync -av --delete /data/ /backup/"
3. Volume 数据卷恢复#
3.1 恢复到同名数据卷#
# 确保目标卷存在
docker volume create app_data
# 将备份恢复到卷
docker run --rm \
-v app_data:/data \
-v /backup:/backup \
alpine:3.19 \
sh -c "tar -xzf /backup/app_data_2024-01-01.tar.gz -C /data"
# 验证卷内容
docker run --rm -v app_data:/data alpine:3.19 ls -al /data
3.2 恢复到新数据卷(迁移或回滚)#
# 创建新卷
docker volume create app_data_new
# 恢复到新卷
docker run --rm \
-v app_data_new:/data \
-v /backup:/backup \
alpine:3.19 \
sh -c "tar -xzf /backup/app_data_2024-01-01.tar.gz -C /data"
4. Bind Mount 备份与迁移#
适用场景:数据直接存在宿主机路径(如 /data/app)。
# 停止容器,保证一致性
docker stop app
# 备份 bind 目录
tar -czf /backup/app_bind_$(date +%F).tar.gz -C /data/app .
# 恢复到新主机(示例)
# 1) 将备份包传输到新主机
# 2) 解压到目标目录
mkdir -p /data/app
tar -xzf /backup/app_bind_2024-01-01.tar.gz -C /data/app
# 启动容器并重新挂载
docker run -d --name app \
-v /data/app:/app/data \
your_image:latest
命令解释
- -C /data/app .:只打包目录内容,避免多一层路径。
5. tmpfs 数据备份注意事项#
tmpfs 是内存数据,容器重启即失效。若必须备份:
# 以临时容器读取 tmpfs(仅运行时可访问)
docker run --rm \
--tmpfs /cache \
alpine:3.19 sh -c "echo 'temp' > /cache/a.txt"
# 将 tmpfs 内容复制到宿主机目录(容器运行期间)
docker run --rm \
--tmpfs /cache \
-v /backup:/backup \
alpine:3.19 sh -c "echo 'temp' > /cache/a.txt && tar -czf /backup/tmpfs_$(date +%F).tar.gz -C /cache ."
建议:重要数据不要放在 tmpfs;仅缓存类可用。
6. 跨主机迁移方案#
6.1 备份文件迁移(scp/rsync)#
# 本机生成备份
tar -czf /backup/app_data_$(date +%F).tar.gz -C /var/lib/docker/volumes/app_data/_data .
# 迁移到新主机
scp /backup/app_data_2024-01-01.tar.gz user@new-host:/backup/
# 新主机恢复
docker volume create app_data
docker run --rm \
-v app_data:/data \
-v /backup:/backup \
alpine:3.19 \
sh -c "tar -xzf /backup/app_data_2024-01-01.tar.gz -C /data"
6.2 在线迁移(rsync over ssh)#
# 在源主机执行(示例)
rsync -avz --delete \
/var/lib/docker/volumes/app_data/_data/ \
user@new-host:/var/lib/docker/volumes/app_data/_data/
7. 故障排查#
- 恢复后数据为空
- 检查 tar 解压路径是否正确:
-C /data是否指向卷挂载目录。 - 使用
docker volume inspect app_data查看真实路径。 - 权限问题
- 对应服务用户检查 UID/GID:
ls -ln /data。 - 修复:
chown -R 1000:1000 /data(按实际 UID/GID)。 - 备份文件损坏
- 校验:
sha256sum -c app_data_2024-01-01.sha256。 - 容器写入中导致数据不一致
- 建议停容器或使用应用级快照(如 MySQL
FLUSH TABLES WITH READ LOCK)。
8. 练习#
- 创建一个 Volume 并写入测试文件,然后使用临时容器备份与恢复。
- 将 Volume 备份包迁移到另一台主机并恢复,验证文件一致性。
- 使用 rsync 做一次增量备份,观察
--delete的效果。 - 模拟权限问题,尝试恢复后修复 UID/GID。