docker如何处理多种挂载类型? [英] How docker handles multiple mount types?
问题描述
这篇文章有点长,但请耐心等待一段时间...
This post is somewhat lenglthy but bear with me for a while...
假设您有一个位于 / app
在具有以下结构的本地(主机)文件系统中
Suppose you have an app that sits in /app
in your local (host) filesystem with the following structure
app
|-- index.php
|-- foo
| `-- file-h1
`-- bar
`-- file-h2
现在假设我们有一个利用以下数据结构的图像(标记为 myrepo / app
)
Now suppose we have an image (tagged myrepo/app
) that exploits the following data structure
opt
|-- app
| `-- foo
| `-- file-c1
如果我们通过挂载主机的<$ c $从该映像运行容器c> / app 到容器的 / opt / app
If we run a container from that image by mounting host's /app
to container's /opt/app
as follows
docker container run \
-v /app:/opt/app \
myrepo/app
容器的结果数据结构如下
The resulting data structure of the container will be the following
opt
|-- app
| |-- index.php
| |-- foo
| | `-- file-h1
| `-- bar
| `-- file-h2
到目前为止,很好...
So far, so good...
现在,假设我们要同时使用 / strong>名为 data
的命名卷,将其安装在 / opt / app / vendor
和 bind-mount 来将 / app
装入 / opt / app
Now, lets say that we want to use both a named volume called data
to be mounted on /opt/app/vendor
and a bind-mount to mount /app
to /opt/app
docker container run \
-v /app:/opt/app \
-v data:/opt/app/foo
myrepo/app
容器中的结果数据结构将是:
The resulting data structure inside the container will be:
opt
|-- app
| |-- index.php
| |-- foo
| | `-- file-c1
| `-- bar
| `-- file-h2
在各种帖子中都已提到(例如此和此),按目录顺序(即最短路径优先)执行docker挂载。据此,我希望docker首先执行bind-mount( -v / app:/ opt / app
),然后执行卷( -v数据:/ opt / app / foo
)。
As it is stated in various posts (like this and this) the docker mounts are performed in lexicographic order (i.e shortest path first). According to this, I would expect docker first to execute the bind-mount (-v /app:/opt/app
) and then the volume (-v data:/opt/app/foo
).
因此,我期望主机的 / app
的内容将替换/遮盖了容器 / opt / app
的内容,因此 file-h1
放在 /之内opt / app / foo
。最后, file-h1
将是复制在新创建的 data
卷中,并且该卷将安装在 / opt / app / foo
(因此应显示 file-h1
而不是 file-c1
)
Hence, I would expect that the contents of host's /app
would replace/obscure the contents of container's /opt/app
and thus file-h1
to be inside /opt/app/foo
. Finally, file-h1
would be copied in the newly created data
volume and the volume would be mounted on /opt/app/foo
(so file-h1
should be shown instead of file-c1
)
我尝试理解此时提出的问题SO的答案
My questions raised when I tried to understand this answer on SO
推荐答案
最后,在github用户 cpuguy83 中,我弄清楚了当我们尝试运行一个使用多个不同挂载的容器时docker引擎实际上是做什么的类型(例如 bind-mount 和 volume ),例如:
Finally, and with a lot of help by github user cpuguy83, I figured out what actually docker engine does when we try to run a container that uses multiple mounts of different type (e.g both a bind-mount and a volume) as, for instance:
docker container run \
-v /app:/opt/app \
-v data:/opt/app/foo
myrepo/app
这里要理解的关键是docker在两个步骤,它们按以下顺序完成:
The key point to understand here is that docker executes the process in two steps that are done in the following order:
-
首先,它会创建一个新的存储-空间(即卷)在主机文件系统(
... data /
)中供容器保留文件,然后(由于新创建的卷为空)将其复制容器的文件(即<$ c内的任何内容$ c> / opt / app / foo / * )到卷的存储位置(... data /
)
First, it creates a new storage-space (i.e. volume) in the host filesystem (
... data/
) for the container to persist files and then (since that newly created volume is empty) it copies the container's files (i.e whatever is inside/opt/app/foo/*
) to the volume's storage location (... data/
)
然后,它按字典顺序执行所有挂载(绑定,卷,tmpfs挂载等...都集中在一起)(第一个挂载 /应用
到 / opt / app
,然后 ... data /
到 / opt / app / foo
)
Then after that, it performs all mounts (binds, volumes, tmpfs mounts, etc... are all lumped together) in lexicographic order (first mounts /app
to /opt/app
then ... data/
to /opt/app/foo
)
因此,我们在示例中使用装载器运行容器,泊坞窗 first 将 file-c1
复制到。主机文件系统中的.data /
位置,然后 second 将主机的 / app
的内容首先安装到con tainer的 / opt / app
,然后主机的 ... data /
(其中包含文件-c1
)到容器的 / opt / app / foo
覆盖/遮盖其内容(即覆盖 file-h1
和 file-c1
)。因此,如果我们在挂载完成后看一下正在运行的容器,结果将是:
So, because of that, when we run the container with the mounts in our example, the docker first will copy the file-c1
to the ... data/
location in the host filesystem and second it will mount first the contents of host's /app
to the container's /opt/app
and then the host's ... data/
(which contains file-c1
) to container's /opt/app/foo
overwriting/obscuring its contents (i.e overwriting file-h1
with file-c1
). Therefore, if we take a look inside the running container after the mounts are done, the result will be the following:
opt
|-- app
| |-- index.php
| |-- foo
| | `-- file-c1
| `-- bar
| `-- file-h2
这篇关于docker如何处理多种挂载类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!