卷如何从容器挂载到主机,反之亦然?

How does volume mount from container to host and vice versa work?

docker run -ti --rm -v DataVolume3:/var ubuntu

假设我有一个卷 DataVolume 3,它提取 ubuntu 容器中 /var 的内容 即使在杀死这个 ubuntu 容器之后,卷仍然存在,我可以使用这个卷 DataVolume3 将它挂载到其他容器。 这意味着随着容器的删除,卷安装不会被删除。
这是如何运作的 ?
该卷安装是否意味着它将 /var 的内容复制到某个本地目录中,因为这看起来不像符号 link ?
如果我有容器 运行 并且我在容器中创建了一个文件,那么相同的文件会被复制到主机路径 ?
从容器到主机以及从主机到容器的卷挂载的整个过程是如何工作的?

卷既不是容器的一部分,也不是主机的一部分。好吧,从技术上讲,一切都驻留在主机中。但是 docker 目录只能由“docker”组中的用户访问。这些目录下的文件分别由docker.

管理

“卷存储在由 Docker(/var/lib/docker/volumes/ Linux 上)管理的主机文件系统的一部分中。”

因此,卷就像 docker 容器和主机本身下的文件的结合。两端的任何添加都将添加到卷中(/var/lib/docker/volumes),而不是硬拷贝,而是类似于符号 link

由于卷可以在不同的容器之间共享,因此删除容器不会级联到与其关联的卷。

删除未使用的卷:

docker volume prune .

卷用于持​​久存储并且卷独立于容器的生命周期而持续存在。

我们可以通过一个demo来理解清楚。

首先,让我们使用命名卷方法创建一个容器:

docker run -ti --rm -v DataVolume3:/var ubuntu

这将创建一个名为 DataVolume3 的 docker 卷,可以在 docker volume ls:

的输出中查看
docker volume ls
DRIVER              VOLUME NAME
local               DataVolume3

Docker 将有关这些命名卷的信息存储在目录 /var/lib/docker/volumes/ (*):

ls /var/lib/docker/volumes/
1617af4bce3a647a0b93ed980d64d97746878564b141f30b6110d0818bf32b76  DataVolume3 

接下来,让我们从ubuntu容器写入一些数据到挂载路径var:

echo "hello" > var/file1
root@2b67a89a0050:/# cat /var/file1
hello

即使在删除容器后,我们也可以通过 cat 看到此数据:

cat /var/lib/docker/volumes/DataVolume3/_data/file1
hello

注意:虽然我们能够访问如上所示的卷,但不建议像这样访问卷数据。

现在,下次当另一个容器使用相同的卷时,该卷中的数据将装载到作为 -v 标志的一部分指定的容器目录中。

(*) 位置可能会根据 David 指出的 OS 而有所不同,可能可以通过 docker volume inspect 命令看到。

Docker 有一个 named volume. By default the storage for this lives somewhere on your host system and you can't directly access it from outside Docker (*). A named volume has its own lifecycle, it can be independently docker volume rm 的概念,如果你启动另一个容器安装相同的卷,它将具有相同的持久内容。

docker run -v 选项获取一些存储单元,命名卷或特定主机目录,并将其挂载(如 mount(8) 命令) 在容器文件系统的特定位置。这将隐藏图像中的原始内容并将其替换为卷内容。

正如您所注意到的,如果您安装的是一个空的命名卷,它将在容器初始化时从图像内容中填充。此功能有一些非常重要的注意事项:

  • 命名卷初始化发生仅当卷完全为空时
  • 指定卷的内容从不自动更新
  • 如果卷不为空,卷内容完全替换图像中的内容,即使它已更改。
  • 初始化仅在本机 Docker 上发生,例如在 Kubernetes 中不会发生。
  • 初始化发生只发生在命名卷上,而不发生在绑定挂载的主机目录上。

考虑到所有这些注意事项,我会避免依赖此功能。

如果您需要将卷装载到容器中,请假设在您的入口点或主容器命令启动时它是空的。如果您在那里需要特定的目录布局或文件结构,入口点脚本可以创建它;如果您希望它保存特定数据,请在您的图像中的其他位置保留一份副本,如果它不存在(或者,也许总是存在),则复制它。

(*) 在本机 Linux 上,您可以找到它的文件系统位置,但访问这不是最佳做法。在其他操作系统上,这将隐藏在虚拟机或其他不透明存储中。如果您需要直接访问数据(或注入配置文件,或读取日志文件),docker run -v /host/path:/container/path bind mount 是更好的选择。