当我同时使用主机卷(绑定安装)和命名卷(一种 docker 管理的卷)时会发生什么?

ChiuCheng

在问这个问题之前,我已经阅读了一些文件:

我对以下两部分感到困惑:

  1. 绑定挂载:挂载到容器上的非空目录中
  2. 命名卷:使用容器填充卷

他们的行为完全相反:

对于绑定安装:

如果您绑定挂载到容器上的非空目录中,则该目录的现有内容会被绑定挂载所掩盖。

对于命名卷和匿名卷:

如果你启动一个容器来创建一个新的卷,如上,并且容器在要挂载的目录中有文件或目录(如上面的 /app/),目录的内容被复制到卷中。然后容器安装并使用该卷,使用该卷的其他容器也可以访问预先填充的内容。

我的问题是,如果我VOLUME在 dockerfile 中使用一个命令来创建一个命名卷 匿名卷,同时使用绑定挂载将不存在的路径挂载到容器中,幕后发生了什么?

例如:

# in docker file
VOLUME /path/in/container

# when run container
docker run -v /not-exist-dir/in/host:/path/in/container  ... /< image >

我做了一些测试,结果是:

  1. 没有创建匿名卷 /var/lib/docker/volumes/
  2. not-exist-dir 是在主机上创建的,现在不是空的,我认为使用容器填充卷已生效。

所以,

  1. 为什么没有按预期创建匿名卷?
  2. 为什么目录的现有内容(在容器端)没有被绑定安装遮挡?

这个场景背后发生了什么?


让我举一个更具体的例子:

这是openfrontier/gerrit镜像的dockerfile,我们可以看到在docker文件的末尾,有一个VOLUME命令:

VOLUME $GERRIT_SITE

这实际上会在主机上创建一个匿名卷,并/var/gerrit/review_site在从该映像创建任何容器时将其挂载到容器中的(GERRIT_SITE 的值),如下所示:

docker run -dit --name gerrit  openfrontier/gerrit:2.15.3

之后,我可以看到下面的匿名卷/var/lib/docker/volumes/,我可以用它docker volume ls来查看它的名称be4538dbf3a51da463391c6eca9714fb6dd0c11379f1e2918f74c33d56633f00,也可以使用docker inspect gerrit命令,我们可以看到:

"Mounts": [
            {
                "Type": "volume",
                "Name": "be4538dbf3a51da463391c6eca9714fb6dd0c11379f1e2918f74c33d56633f00",
                "Source": "/var/lib/docker/volumes/be4538dbf3a51da463391c6eca9714fb6dd0c11379f1e2918f74c33d56633f00/_data",
                "Destination": "/var/gerrit/review_site",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],

这两个文件夹下还有一些文件,是容器运行后创建的。

到目前为止,这是使用 VOLUME 命令创建匿名卷的正常示例。

但是,如果我使用以下命令运行此容器:

docker run -dit --name gerrit -v /home/test:/var/gerrit/review_site openfrontier/gerrit:2.15.3

如果/home/test主机上不存在,则不创建匿名卷,而是/home/test创建文件夹且不为空!!!,挂载信息如下:

"Mounts": [
            {
                "Type": "bind",
                "Source": "/home/test",
                "Destination": "/var/gerrit/review_site",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

我认为绑定安装在这里生效,但我只是不明白为什么主机上的路径不为空(因为绑定安装到容器上的非空目录中,目录的现有内容被绑定安装掩盖了。)

在我docker run用来启动容器之前,我还通过在“/home/test”下放置一些文件来测试将一个非空文件夹安装到容器中,结果是保留了原始文件并添加了新文件。

我知道上面的例子不是使用 docker volume 的好习惯,但我只是想知道后面发生了什么。

米奇

Dockerfile 中的卷声明在映像上设置了一些元数据,告诉docker run在从该映像制作容器时在该位置定义匿名卷。这不是命名卷或主机挂载,但它与两者有很多共同点(默认情况下它们都是绑定挂载,匿名卷docker volume ls与命名卷一起列出)。

但是,当您指定主机挂载到同一个容器目录时,它优先(两个卷挂载到容器内的同一目录不会发生)。容器内运行的命令对该目录的任何修改都将在主机上可见,但目录本身不会被图像内容初始化。

如果要使用图像内容初始化主机目录,可以使用执行绑定安装的命名卷。与主机挂载的行为存在一些差异。主要是目录必须提前存在,在compose文件中必须使用绝对路径而不是相对路径。我在我的演示文稿中得到了它的语法:

https://sudo-bmitch.github.io/presentations/dc2018eu/tips-and-tricks-of-the-captains.html#48

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Docker绑定安装目录与命名卷性能比较

来自分类Dev

docker绑定安装托管卷

来自分类Dev

我可以控制Docker映像中绑定安装的卷的所有者吗?

来自分类Dev

主机上的docker安装卷

来自分类Dev

以管理员身份使用时会发生什么?

来自分类Dev

远程Docker和卷绑定

来自分类Dev

有没有一种方法可以使用docker compose标记或命名卷实例?

来自分类Dev

Docker MySQL主机卷

来自分类Dev

为什么Docker具有Docker卷和卷容器

来自分类Dev

Docker卷绑定:容器到主机

来自分类Dev

为什么Docker主机卷安装不正确?

来自分类Dev

Windows的Docker:访问命名的卷安装

来自分类Dev

Docker主机卷需要什么权限?

来自分类Dev

“与命名卷不同,绑定安装不会自动将容器内容复制到主机上”

来自分类Dev

当物理卷发生故障时,逻辑卷会发生什么?

来自分类Dev

使用 Docker Swarm 定义共享主机卷

来自分类Dev

我什么时候需要 Docker 卷?

来自分类Dev

孤立的Docker挂载主机卷?

来自分类Dev

从多个主机共享 docker 卷?

来自分类Dev

在/上安装分区时会发生什么?

来自分类Dev

在/上安装分区时会发生什么?

来自分类Dev

Docker命名卷未更新

来自分类Dev

Docker命名卷未更新

来自分类Dev

当我绑定到AliasProperty时会发生什么?

来自分类Dev

docker-compose配置如何在使用现有卷的同时从使用匿名卷过渡到命名卷?

来自分类Dev

Docker:已安装卷的权限

来自分类Dev

使用docker-compose创建命名的docker卷?

来自分类Dev

如何创建与主机共享的数据的命名Docker数据卷

来自分类Dev

创建、填充和使用 Docker 卷