删除容器后Docker卷会发生什么?

15
假设我在我的Mysql Docker容器中有这些卷:
VOLUME ["/etc/mysql", "/var/lib/mysql"]
现在,在生产环境中运行良好。
然后我对mysql镜像进行了一些更改,并希望将其部署到生产环境中。
请纠正我,如果我错了
1.我需要从更新的mysql镜像构建新容器。 2.我需要删除旧容器,因此我将停止并删除它。 3.然后我需要创建一个同名的新mysql容器,以便使用数据库的其他Web服务器可以使用它。
现在我的问题是,Docker会不会在我删除容器时删除所有mysql数据。

根据文档“卷会一直存在,直到没有容器在使用它们”,请参见https://docs.docker.com/userguide/dockervolumes/。 - user2915097
@user2915097,卷持久存在,但新容器会使用相同的卷还是创建新的卷,因为它们是由容器ID命名空间化的? - user3214546
2个回答

14

在我们继续之前,有两个概念我认为需要解释一下。Docker 镜像和 Docker 容器。容器是由 Docker 管理的基于 Docker 镜像运行的进程。有两种创建镜像的方式:

  1. 使用 Dockerfile 指定所有依赖项并使用 docker build 构建它。然后它被保存在本地注册表中(或者您可以将其推送到中央位置)。
  2. 可以基于镜像启动容器,在该容器中进行修改,然后 commit 更改。

容器只是正在运行的进程,它们始终基于镜像。请注意,容器永远不能更改镜像(除非您 commit)。在我看来,Dockerfile 方法要优秀得多。

那么,回到最初的问题。在 Dockerfile 中,VOLUME 指令只是为容器创建一个挂载点,实际上它不会将任何东西从主机文件系统挂载到容器文件系统。为了实际从主机挂载文件夹,必须在运行容器时提供 -v 标志。

docker run -v /host/path:/container/path ...

这将在主机和容器之间创建一个共享文件夹,即使容器已停止、删除或崩溃,数据也可以存活下来。

  1. 我必须从更新的mysql镜像构建新容器。

是的,如果你在Dockerfile中更新了某些内容,你就需要构建一个新的镜像(而不是容器),并将该镜像部署到生产环境。然后,你可以基于新构建的镜像使用docker run启动容器。

  1. 我需要删除旧的容器,所以我会停止它并删除它。

是的,你需要停止旧的容器,然后删除它。之后,你可以使用相同的名称启动新容器,但这次基于一个新镜像。删除容器是必要的,因为它是一个命名容器,如果你使用相同的名称启动一个新容器(例如,容器使用了--name选项来运行docker run),你将会得到一个名称冲突。如果容器没有被命名,删除旧容器可以被跳过。

  1. 然后我需要使用相同的名称创建新的mysql容器,以便其他使用数据库的web服务器可以使用它。

是的,因为你可能正在使用容器链接来实现这一点。

资源:


感谢回复。您说“它实际上不会挂载来自主机文件系统的任何内容”,这是否意味着新容器将挂载其新卷并且不会使用旧卷? - user3214546
@KKJOJ 我建议你阅读这篇关于卷的精彩文章。它比我的胡言乱语解释得更好;) - wassgren

4
除非使用docker rm -v container_id删除父容器并且没有其他容器正在使用该卷,否则卷将永远不会被删除。如果没有给出-v标志,则卷不会被删除。这意味着您经常会在/var/lib/docker下找到未使用-v标志删除的容器存在的“孤立”卷。
映射到所选主机目录(使用-v host_dir:container_dir)的卷永远不会被删除。

如果是这样,那么人们如何在MySQL容器中使用卷呢?因为每当镜像被更新时,该卷将消失。这是否意味着每次更新镜像时,我都必须备份数据容器,然后在新的容器准备好后将其恢复到所需位置?那么数据容器有什么意义呢?难道不是主机挂载卷更好,至少当我从更新的镜像创建新的容器时,数据已经存在,我不需要担心备份和还原。如果我错了,请纠正我。 - user3214546
请去阅读一些资源,你似乎混淆了几个概念。如果你愿意,可以尝试阅读我的博客:http://container-solutions.com/2014/12/understanding-volumes-docker/ - Adrian Mouat
@KKJOJ 基本上,为什么需要更新数据容器?您可以更新mysql镜像并使用“--volumes-from data_container”加载数据。数据容器本身没有运行,它只是处于退出状态。 - Adrian Mouat
很抱歉我有些困惑。在一个教程中,那个人告诉我要创建卷,然后在数据容器中使用它们,而不是另一种方式。我明白了。你认为我应该为mysql制作单独的数据容器,为psql制作单独的数据容器,为备份等制作单独的数据容器,还是为所有这些都制作一个数据容器?当你说“不要使用像busybox或scratch这样的“最小镜像”作为数据容器。只需使用数据库镜像本身即可。您已经拥有该镜像,因此它不会占用任何额外的空间,并且还允许从镜像中填充卷。”时,是在你的博客上吗?我不理解。 - user3214546
我正在阅读你的博客,非常好,有很多技巧在其他地方都找不到。谢谢。 - user3214546
我很高兴它有所帮助。我不确定你在问什么关于数据容器的问题。你不会为备份创建一个数据容器 - 你只需运行一个临时容器将数据复制到其他地方。你会为不同类型的数据库拥有单独的数据容器。 - Adrian Mouat

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