在Docker容器中持久化数据文件

4
这应该不难,但我想不出来。我有一个正在运行的容器,并在docker run命令中使用了-v /tester。然后我执行docker exec ti containername /bin/bash。然后我使用vi /tester/stayhere.txt创建了一个名为/tester/stayhere.txt的文件。然后保存文件并验证它是否存在。然后我进行docker commit,启动新镜像,但stayhere.txt却不见了。我错在哪里了?
2个回答

1
当你使用-v在docker容器内挂载卷时,它并不被视为容器本身的一部分。这就是为什么在提交更改时会缺少它的原因。
根据Docker文档:
数据卷是一个或多个容器中的特定目录,可以绕过联合文件系统。
还有:
卷在创建容器时初始化。如果容器的基础映像在指定的挂载点包含数据,则在卷初始化时将该现有数据复制到新卷中。
这意味着,数据卷存在于联合文件系统之外,即使您删除了该容器,数据卷仍然存在:
数据卷旨在持久保存数据,独立于容器的生命周期。因此,当您删除容器时,Docker永远不会自动删除卷,也不会“垃圾回收”不再由容器引用的卷。
因此,它们不是您的docker提交命令的一部分。
为了实现您想要的效果,您需要在镜像中的相同路径中复制文件,同时它未被挂载为docker卷。您可以使用Dockerfile或直接启动容器并更改文件系统,然后提交。
下一次启动带有卷的容器时,您应该能够看到这些文件。

0

我无法确定你正在运行哪些命令,所以不能给出确切的答案。但是我猜测你可能没有正确启动“新”镜像。我认为这是因为你使用了 docker exec(在运行的容器中启动)而不是 docker run

总的来说,我建议不要在更改后提交代码。你应该在构建时完成所有构建相关的操作(使用 Dockerfile)。

任何持久状态都应该挂载到容器中,可以通过卷挂载或存储容器实现。

创建这些内容非常简单:

docker create -v /path/to/data --name my_storage_container base-image-name /bin/true

然后从一个干净的构建镜像启动您的容器:

docker run -it --volumes-from my_storage_container image /bin/bash

你保存的文件应该是持久的,无论你如何操作图像。


谢谢Sobrique。我不认为我完全明白你的意思,但我已经简化了问题以尝试得到答案。基本上我的情况是这样的:我在AWS和IBM云中运行docker。我希望将在AWS中运行的容器导出并在IBM云中运行,但无论我做什么,文件都无法保留。你会如何建议我将容器和文件转移到IBM云? - Casey Johnson
我已经尝试过docker save、export、commit,但我认为你告诉我的是也许我应该使用docker cp将文件从容器中取出,然后将它们挂载到新的容器中...这似乎很奇怪,因为那样我就必须移动一个docker镜像和一组数据。这违反了我对容器的理解...为什么不把所有东西都放在一个容器中并进行移动呢? - Casey Johnson
如果你能发布一个完整的命令历史记录,我可能可以提供更多的扩展帮助。 - Sobrique
但是你根本不需要做任何事情就可以使数据在容器中持久存在。 "docker commit" 是关于更新你的容器来自的 _镜像_。我认为这是不好的实践 - 如果你需要更改 _镜像_,应该重新构建它,因为这样更新和重新部署会更容易。将容器视为可丢弃的单位,就像你处理 'bash' 进程一样。如果你想保留东西,就要 "保存" 它。 - Sobrique
1
感谢Sobrique,我认为你的答案帮助我引导了正确思考这个问题的方式...这让我找到了这个链接,真正地帮我解决问题 [http://container42.com/2013/12/16/persistent-volumes-with-docker-container-as-volume-pattern/] (http://container42.com/2013/12/16/persistent-volumes-with-docker-container-as-volume-pattern/)。 - Casey Johnson
1
这也是一个非常好的资源...但愿我在第一次提出问题时就找到了它.. http://blog.giantswarm.io/moving-docker-container-images-around/ - Casey Johnson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接