保存docker映像的当前状态并导出到其他服务器

保存docker映像的当前状态并导出到其他服务器,docker,Docker,我不熟悉码头工人和集装箱。 我按照以下步骤迁移运行在docker容器上的postgres数据库: docker save -o <path for generated tar file> <image name> scp root@192.10.1.5:/images/gpdb.tar root@192.10.2.5:/images 但是,当我登录到docker映像时,数据库不在那里。 如何将docker映像与所有数据库表和数据一起保存。启动时,容器基于映像,但启动后,

我不熟悉码头工人和集装箱。 我按照以下步骤迁移运行在docker容器上的postgres数据库:

docker save -o <path for generated tar file> <image name>
scp root@192.10.1.5:/images/gpdb.tar root@192.10.2.5:/images
但是,当我登录到docker映像时,数据库不在那里。
如何将docker映像与所有数据库表和数据一起保存。

启动时,容器基于映像,但启动后,所有更改都不会影响映像

所以,在保存之前,您的所有更改(包括在容器运行时进行的数据库更改)都需要提交以形成新的docker映像

如下所示,请参见


然后将新图像保存到tar,然后执行所需操作。

将当前状态提交到图像

docker commit currentcontainer newimage
docker load < /tmp/newimage.tar
将图像另存为tar文件

docker save newimage > /tmp/newimage.tar
从图像中加载容器

docker commit currentcontainer newimage
docker load < /tmp/newimage.tar
docker加载
没有数据库,因为
docker save
docker commit
命令不保存容器卷

这里有一个脚本可以做到这一点:

#停止容器
docker stop$CONTAINER
#创建一个新图像
docker提交$CONTAINER$CONTAINER
#保存图像并将其加载到另一台主机
docker保存$CONTAINER| ssh$USER@$主机docker加载
#保存卷(如果需要压缩,请使用“.tar.gz”)
docker-volumes.sh$CONTAINER save$CONTAINER-volumes.tar
#将映像和卷复制到另一台主机
scp$CONTAINER.tar$CONTAINER-volumes.tar$USER@$HOST:
###在另一台主机上:
#使用前一个容器使用的相同选项创建容器
docker create--名称$CONTAINER[]$CONTAINER
#加载卷
docker-volumes.sh$集装箱装载$CONTAINER-volumes.tar
#启动容器
docker start$容器

尝试这样移动容器不是最佳做法。不过,可能需要一些设置才能使容器进入正确的状态

重要的细节是,所有可能更改并需要持久化的数据都需要存储在容器外部。虽然Docker为此认可命名卷,但使用本机文件系统路径更易于维护和移动。您需要知道数据在容器中的位置(通常有很好的文档记录),然后您可以运行如下命令

docker-run-v/data/mysql:/var/lib/mysql/data。。。mysql
现在,您可以对容器执行任何操作,即使是
docker rm
it,但只要主机上的
/data/mysql
完好无损,您的数据就可以了。这也意味着您可以使用普通的
scp
将数据复制到其他主机,然后
docker在那里运行相同的容器,这是更典型的迁移路径

如果您正在构建和运行自定义图像,则需要检查以下几点:

  • 您真的应该使用某种Docker注册表,无论是Docker Hub、您的云提供商提供的、第三方的还是自托管的
    docker save
    移动图像是几乎不需要的最后手段

  • 映像本身应该从DockerFile构建,并且与应用程序的其余部分一样,应该签入源代码管理。理想情况下,您有一个自动构建系统(持续集成),为您运行
    docker build和&docker push
    。永远不要使用
    docker commit
    docker export
    :它们是在不同系统上获取不同版本软件的一种方法,而不记得您是如何实现的

  • 应用程序应尽量减少本地存储的数据量。最好的情况是将所有内容存储在一个外部数据库中,然后您可以直接指向该数据库;如果本地文件存储确实不可避免,请尝试将其全部包含在应用程序源目录树之外的单个目录中

  • 在本地,您可以自由地
    停靠码头;docker rm;docker运行相同的容器,并且不会丢失数据。在需要进行跨主机迁移之前,请先进行测试


如果您可以构造应用程序,以便其所有数据都在外部数据库中,请考虑在具有非常好备份程序的专用主机上运行数据库。如果您已经完成了到目前为止的所有工作,您可能会出现大规模的协调硬盘故障,并丢失所有Docker主机,而实际上没有丢失任何东西(因为您可以

Docker再次从源代码构建图像,并且
Docker运行容器,并且数据已脱离主机).

这不会保存容器卷。如果op的卷可能为k8s或--link?k8s或
--link
,则为真。谢谢。现在我有一个新问题,如果容器不改变图像,它如何保持其当前状态。但是,这对我来说将是一项阅读任务。
docker commit
命令将对容器所做的任何更改保存在非卷目录中。脚本保存并加载卷。
# Stop the container 
docker stop $CONTAINER
# Create a new image
docker commit $CONTAINER $CONTAINER
# Save and load image to another host
docker save $CONTAINER | ssh $USER@$HOST docker load 

# 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:

# Create container with the same options used by the previous container
docker create --name $CONTAINER [<PREVIOUS CONTAINER OPTIONS>] $CONTAINER

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

# Start container
docker start $CONTAINER