如何在不同主机之间移动Docker容器?


98

我找不到将Docker运行容器从一台主机移动到另一台主机的方法。

有什么办法可以像将图像一样将容器推到存储库中吗?当前,我没有使用数据卷来存储与在容器内运行的应用程序关联的数据。因此,一些数据驻留在容器内,我想在重新设计设置之前将其保留。



请注意,您可能希望使用保存/加载而不是导出/导入,因为保存会保存元数据和历史记录。
Burstaholic 2015年

这应该是对@aholt答案的评论吗?
马丁·汤普森

docker save用于保存图像,而不是容器。docs.docker.com/engine/reference/commandline/save
stmllr

Answers:


57

您无法将正在运行的Docker容器从一台主机移动到另一台主机。

您可以使用将容器中的更改提交到图像docker commit,将图像移动到新主机上,然后使用来启动新容器docker run。这将保留您的应用程序在容器内创建的所有数据。

Nb:它不保留存储在卷内的数据;您需要将数据卷手动移动到新主机。


@larsks第一步不是停止容器,然后提交吗?
2016年

@valentt都可以提交运行和停止的容器
crollywood

1
这个答案并没有真正解释正是你需要使用的命令,这使得它很难像我这样的小白
保罗克鲁格

如果docker-checkpoint都支持CRIU,则可以让它们在主机之间移动“运行中”的容器。
dGRAMOP

2
1.停止容器docker stop x;2.进行更改docker commit -p x x;3.将容器保存到映像中docker save -o x x;4.将x文件移动到新主机,并在新主机中加载新映像dokcer load -i x(如果您使用-v选项启动了容器,则也必须将这些文件移动到新主机中);5.使用docker run (-v is required to mount these files if needed)
Lau Real

95

或者,如果您不想推送到存储库:

  1. 将容器导出到tarball

    docker export <CONTAINER ID> > /home/export.tar
    
  2. 将tarball移至新机器

  3. 汇回

    cat /home/export.tar | docker import - some-name:latest
    

8
也不会保留存储在卷内的数据。
stmllr

1
这应该如何工作?导入后,我得到新图像,然后呢?只是执行新的运行命令?
2016年

2
这实际上是一个非常糟糕的建议,尤其是对于运行数据库的容器。我尝试了这个建议,但没有成功。可以先停止容器吗?
2016年

2
该建议仅是真正的替代选择。它可能适合您的情况,但可能不起作用。对我而言,当时我正在设置数据库复制docker容器,而对于导出/导入,我并不关心保留数据,因为我定期将数据库数据的备份运行到另一个tarball中。为此,这很完美。
aholt 2013年

32

经过大量令人困惑的手册和令人困惑的教程之后,最终对我有用的是,因为在我撰写本文时,Docker显然是出于对虚假期望的偷看,所以:

  1. 将Docker映像保存到存档中:
    docker save image_name > image_name.tar
  2. 在另一台机器上复制
  3. 在另一台Docker机器上,按以下方式运行docker load:
    cat image_name.tar | docker load

根据另一个答案中的建议,导出和导入不会导出端口和变量,而这可能是容器运行所必需的。当您尝试将其加载到另一台计算机上时,可能会遇到诸如“未指定命令”之类的东西。

因此,保存和导出之间的区别在于,save命令使用历史记录和元数据保存整个图像,而export命令仅导出文件结构(不包含历史记录或元数据)。

不用说,如果您已经在进行导入的docker hyper-visor上已经占用了这些端口,那么其他一些docker容器将导致冲突,并且必须重新配置暴露的端口。


1
很有帮助。“未指定命令”消息使我发疯。
Rintoul '18

“未指定命令”消息也使我发疯。我使用docker commit <container-id> stackstorm-local:2.9,而docker从另一台主机拉出stackstorm-local:2.9。
张华

18

从Docker文档中:

docker export不导出与容器关联的卷的内容。如果将卷安装在容器中现有目录的顶部,docker export则将导出基础 目录的内容,而不是卷的内容。 有关在卷中导出数据的示例,请参考用户指南中的备份,还原或迁移数据卷


群集总部关闭...和BTW迁移容器,容器应在ZFS /任何受支持的存储lun上运行
asvignesh

6

使用此脚本:https : //github.com/ricardobranco777/docker-volumes.sh

确实将数据保留在卷中。

用法示例:

# Stop the container   
docker stop $CONTAINER

# Create a new image   
docker commit $CONTAINER $CONTAINER

# Save image
docker save -o $CONTAINER.tar $CONTAINER

# Save the volumes (use ".tar.gz" if you want compression)
docker-volumes.sh $CONTAINER save $CONTAINER-volumes.tar

# Copy image and volumes to another host
scp $CONTAINER.tar $CONTAINER-volumes.tar $USER@$HOST:

# On the other host:
docker load -i $CONTAINER.tar
docker create --name $CONTAINER [<PREVIOUS CONTAINER OPTIONS>] $CONTAINER

# Load the volumes
docker-volumes.sh $CONTAINER load $CONTAINER-volumes.tar

# Start container
docker start $CONTAINER

1
在AWS Linux(Centos)上对我不起作用。在Endi中,我采用了低技术含量的方法,即使用docker inspect查找卷目录,然后手动将其复制。
JasonPlutext

@JasonPlutext也许与SELinux有关?您是否启用了SELinux?
里卡多·布兰科

1

我为此尝试了许多解决方案,而这是对我有用的解决方案:

1.将容器提交/保存到新图像:

  1. ++提交容器:
    #docker stop
    #docker commit CONTAINER_NAME
    #docker save --output IMAGE_NAME.tar IMAGE_NAME:TAG


ps:“我们的容器CONTAINER_NAME的挂载卷位于'/ var / home'”(您必须检查容器以指定其卷路径:#docker inspect CONTAINER_NAME)

  1. ++节省其体积:我们将使用ubuntu映像来完成该任务。 #mkdir
    backup
    #docker run --rm --volumes- from CONTAINER_NAME -v $ {pwd} / backup:/ backup ubuntu bash -c“ cd / var / home && tar cvf /backup/volume_backup.tar”。

现在,当您查看$ {pwd} / backup时,将以tar格式找到我们的卷。
到目前为止,我们有容器的图像“ IMAGE_NAME.tar”及其卷“ volume_backup.tar”。

现在,您可以在新主机上重新创建相同的旧容器。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.