迁移前必须明确的边界
Docker 容器迁移与备份恢复,看似简单,实则涉及多个层面:镜像、容器、数据卷、网络配置等。在动手之前,先明确边界:本文讨论的是单机 Docker 环境下的容器迁移与备份,不涉及 Kubernetes 集群或跨集群迁移。Kubernetes 的 Pod 迁移、存储抽象等概念,超出了本文范围,如需了解可参考 Kubernetes 官方文档。此外,Docker 的备份恢复通常针对容器和镜像,而数据持久化则依赖数据卷或绑定挂载,这些是独立于容器生命周期的。
备份容器:镜像导出与容器提交
备份容器有两种常见方式:导出镜像和提交容器。导出镜像是将镜像保存为 tar 文件,使用 docker save 命令。而提交容器则是将容器的当前状态(包括对文件系统的修改)保存为新的镜像,使用 docker commit。注意,docker commit 不会包含数据卷的内容,且不建议在生产环境使用,因为它会丢失元数据并产生不可复现的镜像。如果你需要备份运行中的数据,建议使用数据卷备份。
使用 docker save 导出镜像
假设你有一个名为 myapp:latest 的镜像,导出命令如下:
docker save -o myapp.tar myapp:latest
这会生成一个 tar 文件,包含镜像的所有层和元数据。在目标机器上,使用 docker load 导入即可。
使用 docker commit 备份容器状态
如果容器内安装了额外的软件或修改了配置文件,可以使用 commit 保存状态:
docker commit container_name myapp-backup:latest
但请记住,这不会包含数据卷数据,且会丢失环境变量等部分配置(部分配置会保留,但不可靠)。因此,仅适合快速保存状态,不适合作为正式备份方案。
备份数据卷:核心数据持久化
数据卷是 Docker 中持久化数据的推荐方式。备份数据卷通常使用 docker run --rm --volumes-from 挂载数据卷,然后使用 tar 打包。例如,假设容器 db 有一个名为 dbdata 的数据卷:
docker run --rm --volumes-from db -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
这会将数据卷内容打包到当前目录的 backup.tar。恢复时,先创建数据卷,再解包:
docker run --rm -v dbdata:/dbdata -v $(pwd):/backup ubuntu tar xvf /backup/backup.tar -C /dbdata
注意,备份和恢复的路径必须一致,否则数据会错位。
迁移到新主机:完整流程
迁移容器到新主机,需要同时迁移镜像和数据卷。步骤:1) 在源主机导出镜像(docker save)。2) 备份数据卷(如上述 tar 方法)。3) 将 tar 文件复制到目标主机。4) 在目标主机导入镜像(docker load)。5) 创建数据卷并恢复数据。6) 使用 docker run 重新创建容器,注意指定相同的环境变量、网络等配置。如果容器使用了自定义网络,需在目标主机重建网络,否则容器可能无法正常通信。
常见误区与失败条件
误区一:认为 docker export 和 docker save 等价。实际上,docker export 导出的是容器文件系统(不含镜像层历史),而 docker save 保存的是镜像。导出后再导入会丢失镜像的标签、历史等元数据,且无法保留所有层。误区二:忽略数据卷。许多用户只备份镜像,导致数据丢失。误区三:在容器运行期间直接复制数据卷文件,可能导致数据不一致。失败条件:目标主机 Docker 版本不兼容,可能导致镜像无法加载;数据卷路径不一致,导致恢复失败;网络配置冲突,导致容器无法启动。
备份恢复的自动化与验证
手动操作容易出错,建议编写脚本定期备份。备份后务必验证:在测试环境恢复,并检查数据完整性。例如,恢复数据库容器后,执行查询验证。另外,备份文件应存储在不同的物理位置,防止单点故障。
参考资料
延伸阅读
