Docker容器跨主机数据迁移方案:从导出到恢复的完整实操
为什么需要跨主机数据迁移
当服务器需要升级、搬迁或切换云服务商时,Docker 容器的跨主机迁移就成了常见需求。
很多人以为直接把容器打包导过去就行,但容器里的数据卷、挂载目录和配置文件往往会被忽略,导致迁移后服务跑不起来。
本文专门解决这个问题,提供一套经过验证的迁移流程,适合开发者、运维人员和刚接触 Docker 的新手参考。
迁移前的准备工作
开始操作之前,先在源主机和目标主机上确认几件事:
- Docker 版本:两台主机最好使用相同版本的 Docker(至少兼容),避免 API 差异。运行
docker version查看。 - 磁盘空间:确保目标主机有足够空间存放镜像和数据。
- 停止容器:迁移过程中容器应该处于停止状态,避免数据变更导致不一致。可以用
docker stop 容器名暂停服务(如果允许短暂停机)。 - 记录配置:如果容器是通过 docker run 启动的,记下端口映射、环境变量、挂载路径等参数;建议提前准备一份 docker-compose.yml 文件。
第一步:导出容器镜像
容器本身运行的是某个镜像的实例,先要把这个镜像导出成 tar 包,再到目标主机上导入。
如果容器是最新版本且没有额外文件变动,直接 docker save 原镜像即可:
# 查看现有镜像名和标签
docker images
# 保存镜像为 tar 文件
docker save -o myapp-image.tar myapp:latest
如果容器内安装了额外软件或修改了文件,推荐先用 docker commit 生成新镜像,再保存:
# 提交容器为新的镜像
docker commit 容器名 myapp-backup:202504
# 保存新镜像
docker save -o myapp-backup.tar myapp-backup:202504
commit 会把容器当前的文件系统层冻结成一个新快照,包括你手动安装的依赖和改动的配置。
注意:动态数据(如日志、数据库文件)如果写在容器内部,也会被打包进去,这会导致镜像体积暴增,所以数据尽量放在数据卷中。
第二步:备份容器数据
大部分重要数据应该存在数据卷(Volume)或绑定挂载目录中。
找到这些目录并迁移它们,是迁移成功的关键。
查看挂载情况:
docker inspect 容器名 | grep -A 10 Mounts
输出里会看到 Source(宿主机路径)和 Destination(容器内路径)。
对于绑定挂载,直接备份 Source 目录即可;
对于 Docker 管理的卷,需要先查询卷的路径:
docker volume inspect 卷名
然后用 tar 或 rsync 打包备份:
# 假设绑定挂载目录在 /data/app
tar -czf app-data.tar.gz /data/app
# 如果是卷,路径一般在 /var/lib/docker/volumes/卷名/_data
sudo tar -czf myvolume-data.tar.gz /var/lib/docker/volumes/myvolume/_data
如果目标主机能直接通过 SSH 访问,也可以用 rsync 同步过去,避免打包步骤。
第三步:在新主机恢复
先把镜像和数据包拷贝到目标主机(使用 scp、rsync 或优盘),然后依次操作。
导入镜像:
docker load -i myapp-backup.tar
# 确认镜像已出现
docker images
恢复数据: 在原主机上创建相同的目录结构(或者先创建空的卷/目录),再把备份解压回去:
# 假设原绑定挂载路径是 /data/app,新主机同样创建
mkdir -p /data/app
cd /data/app && tar -xzf /tmp/app-data.tar.gz
# 如果使用的是 Docker 卷,先创建同名卷,再解压
docker volume create myvolume
sudo tar -xzf myvolume-data.tar.gz -C /var/lib/docker/volumes/myvolume/_data
启动容器: 使用原来的启动命令或 docker-compose up -d 启动。
注意端口映射、环境变量要与之前一致。
如果是 docker run,可以用 docker run -d --name myapp -v /data/a/app -p 8080:80 myapp-backup:202504 类似的命令。
避坑与常见问题
- 不要直接拷贝 /var/lib/docker:虽然它包含了所有容器和镜像,但直接拷贝到另一台机器的 Docker 目录容易因版本或配置不一致导致 Docker 崩溃,不推荐初学者使用。
- 注意文件权限:解压数据卷时,目录所有者可能不对,可能导致容器内进程无权限读写。用
chown -R调整成容器内用户 uid:gid(通常为 1000:1000 或容器专用用户)。 - 网络端口冲突:新主机上可能已经运行了其他占用相同端口的服务,启动前先用
netstat -tlnp | grep 80检查。 - 环境变量丢失:docker save/load 不保留环境变量,需要自己在启动时重新指定。建议使用 docker-compose 管理所有参数,迁移时只需搬运 compose 文件和镜像、数据卷即可。
验证迁移结果
- 访问服务 URL 或 API,确认业务正常响应。
- 查看容器日志:
docker logs -f myapp。 - 检查数据是否完整:往数据库写一条测试数据,看能否持久化;或者比对文件数量。
- 如果用了
docker commit打包,确认新镜像大小不超过预期;若发现体积过大,可考虑清理容器内临时文件后再 commit。
按照以上步骤操作,你的 Docker 容器跨主机数据迁移就能顺利完成。
如果迁移过程中遇到其他报错(如权限禁止、镜像层丢失),可以先回看避坑部分,或者尝试用 docker-compose 统一管理容器参数,下次迁移会更省力。