docker如何处理多种挂载类型?

时间:2017-12-13 14:51:49

标签: docker docker-compose

这篇文章有点长篇大论但是我已经有一段时间了...

假设您的本地(主机)文件系统中的应用程序位于/app,并具有以下结构

app
|-- index.php
|-- foo
|   `-- file-h1
`-- bar
    `-- file-h2

现在假设我们有一个利用以下数据结构的图像(标记为myrepo/app

opt
|-- app
|   `-- foo
|       `-- file-c1

如果我们通过将主机/app挂载到容器/opt/app来运行该图像中的容器,如下所示

docker container run \
-v /app:/opt/app \
myrepo/app

容器的结果数据结构如下

opt
|-- app
|   |-- index.php
|   |-- foo       
|   |   `-- file-h1          
|   `-- bar
|       `-- file-h2 

到目前为止,非常好......

运行具有多个安装(包括绑定安装和卷)的容器

现在,假设我们要使用 一个名为data命名卷挂载在/opt/app/vendor bind-mount /app挂载到/opt/app

docker container run \
-v /app:/opt/app \
-v data:/opt/app/foo
myrepo/app

容器内的结果数据结构为:

opt
|-- app
|   |-- index.php
|   |-- foo       
|   |   `-- file-c1          
|   `-- bar
|       `-- file-h2 

正如在各个帖子(如thisthis中所述)中所述的码头工人坐骑是按照字典顺序执行的(即最短路径优先)。根据这个,我希望docker首先执行bind-mount(-v /app:/opt/app)然后执行卷(-v data:/opt/app/foo)。

因此,我希望期待主持人/app的内容会替换/隐藏容器/opt/app的内容,从而file-h1 1}}在/opt/app/foo内。最后,file-h1在新创建的data卷中为copied,并且卷将挂载在/opt/app/foo上(因此应显示file-h1而不是{{} 1}})

当我尝试理解this回答SO

时,我提出了一些问题

1 个答案:

答案 0 :(得分:8)

最后,在github用户cpuguy83的帮助下,我想出当我们尝试运行使用多个不同类型的挂载的容器时,实际上docker引擎会做什么(例如,两者都是<例如:strong> bind-mount 和

docker container run \
-v /app:/opt/app \
-v data:/opt/app/foo
myrepo/app

这里要理解的关键点是,docker按照以下顺序执行两步中的过程:

  1. 首先,它在主机文件系统(... data/)中创建一个新的存储空间(即卷),以便容器保存文件,然后(因为新创建的卷为空)它{{ 3}}容器的文件(即/opt/app/foo/*内的任何内容)到卷的存储位置(... data/

  2. 然后,它按字典顺序执行所有安装(绑定,卷,tmpfs挂载等等都被集中在一起)(先挂载/app/opt/app然后{ {1}}至... data/

  3. 因此,正因为如此,当我们在示例中运行带有挂载的容器时,docker first 会将/opt/app/foo复制到主机中的file-c1位置文件系统和第二它首先将主机... data/的内容挂载到容器的/app,然后将主机的/opt/app(包含... data/)挂载到容器的file-c1覆盖/遮盖其内容(即用/opt/app/foo覆盖file-h1)。因此,如果我们在完成安装后查看正在运行的容器内部,结果将如下:

    file-c1