使用bind mounts

自Docker早期以来bind mounts 一直存在。与volumes相比,绑定挂载具有有限的功能。使用bind mounts时,主机上的文件或目录将装入容器中。文件或目录由其在主机上的完整路径或相对路径引用。相反,当您使用卷时,会在主机上的Docker存储目录中创建一个新目录,Docker会管理该目录的内容。

该文件或目录不需要已存在于Docker主机上。如果它尚不存在,则按需创建。绑定挂载非常高效,但它们依赖于具有特定目录结构的主机文件系统。如果您正在开发新的Docker应用程序,请考虑使用命名卷。您无法使用Docker CLI命令直接管理bind mounts。

选择-v或--mount标志

最初,-v或者--volume标志用于独立容器,--mount标志用于群集服务。但是,从Docker 17.06开始,您还可以使用--mount独立容器。一般来说, --mount更明确和冗长。最大的区别在于-v 语法将所有选项组合在一个字段中,而--mount 语法将它们分开。以下是每个标志的语法比较。

具体的用法 和 差异请参看上一节以介绍。

使用绑定装载启动容器

考虑具有一个source目录的情况,并在构建源代码时将构建的代码保存到另一个目录source/target/中,您希望这个构建代码可用于容器/app/

并且您希望容器在每次构建源时都能访问新构建在开发主机上。使用以下命令将target/ 目录绑定到容器中/app/。从source目录中运行命令 。

$(pwd)子命令将扩展到Linux或者MacOS主机的当前工作目录。

[root@benjamincloud ~]# mkdir target
[root@benjamincloud ~]# docker run -tid --name devtest --mount type=bind,source="$(pwd)"/target,target=/app nginx:latest
bc8d4cb8bdc26bc77ddc64aa810f7868a13e1019072767a024d8f14b2e4f0a8a

使用docker inspect devtest验证绑定安装正确创建。寻找Mounts部分:

这表明mount是一个bindmount,它显示了正确的源和目标,它表明mount是读写的,并且传播设置为rprivate

停止容器删除容器:

$ docker container stop devtest

$ docker container rm devtest

挂载到容器上的非空目录中

如果将bind-mount绑定到容器上的非空目录中,则bind mounts 会隐藏目录的现有内容。这可能是有益的,例如当您想要测试新版本的应用程序而不构建新镜像时。当然,它也可能令人惊讶,并且此行为与docker  volume行为不同。

此示例设计极端,但将容器/usr/目录的内容替换为主机上的目录/tmp/。在大多数情况下,这会导致容器无法运行。

这些--mount-v示例具有相同的最终结果。

[root@benjamincloud ~]# docker run -dit --name broken-container --mount type=bind,source=/tmp,target=/usr nginx:latest
afe70a7698112b93f0d5f200611b80dfe6c4f9e05ad1e8134183975d14428866
docker: Error response from daemon: OCI runtime create failed: container_linux.go:: starting container process caused "exec: \"nginx\": executable file not found in $PATH": unknown.

容器已创建但无法启动。去掉它:

$ docker container rm broken-container

使用只读bind mounts

对于某些开发应用程序,容器需要写入绑定装入,因此更改会传播回Docker主机。在其他时候,容器只需要读访问权限。

此示例修改上面的示例,但ro通过在容器中的挂载点之后添加(默认情况下为空)选项列表,将目录挂载为只读绑定挂载。如果存在多个选项,请用逗号分隔。

[root@benjamincloud ~]# docker run  -dit --name devtest --mount type=bind,source="$(pwd)"/target,target=/app,readonly nginx:latest
c77da99626fd7c8389cc09aee405951f3bd0837a7a78de9d1eb667da2a24cf5f

使用docker inspect devtest验证绑定安装正确创建。寻找Mounts部分:

配置绑定传播

绑定传播默认rprivate为bind  mounts和volume。这里只配置 mount binds,并且仅适用于Linux主机。绑定传播是一个高级主题,许多用户永远不需要配置它。

绑定传播是指在给定的bind mounts或命名volume中创建的挂载是否可以传播到该装载的副本。考虑一个挂载点/mnt,挂载在/tmp

传播设置控制是否/tmp/a也可以使用挂载/mnt/a。每个传播设置都有一个递归对位。在递归的情况下,请考虑将/tmp/a被/foo挂载。传播设置控制/mnt/a和/或/tmp/a是否将存在。

传播设置 描述
shared 原始挂载的子挂载将暴露给副本挂载,副挂载的副挂载也会传播到原始挂载。
slave 类似于共享挂载,但只在一个方向上。如果原始挂载程序公开子挂载,则副本挂载程序可以看到它。但是,如果副本挂载公开子挂载,则原始挂载无法看到它。
private 挂载是私人的。其中的子挂载不会暴露给副本挂载,而子挂载中的副本挂载不会暴露给原始挂载。
rshared 与共享相同,但传播也扩展到嵌套在任何原始挂载点或副本中的挂载点。
rslave 与从属相同,但传播也延伸到嵌套在任何原始挂载点或副本挂载点。
rprivate 默认值。与private相同,意味着原始或副本挂载点中任何位置的挂载点都不会沿任一方向传播。

在你挂载点设置绑定传播之前,主机文件系统需要已经支持绑定传播。

有关绑定传播的更多信息,请参阅共享子树的 Linux内核文档

以下示例将target/目录挂载到容器两次,第二个挂载同时设置ro选项和rslave绑定传播选项。

这些--mount-v示例具有相同的结果。

[root@benjamincloud ~]# docker run -dit --name devtest --mount type=bind,source="$(pwd)"/target,target=/app --mount type=bind,source="$(pwd)"/target,target=/app2,readonly,bind-propagation=rslave nginx:latest

现在,如果你创建/app/foo//app2/foo/也存在

[root@benjamincloud ~]# mkdir target/foo
[root@benjamincloud ~]# docker exec devtest ls /app2/
foo
[root@benjamincloud ~]# docker exec devtest ls /app/
foo

果使用selinux,可以添加zZ选项以修改要装入容器的主机文件或目录的selinux标签。这会影响主机本身上的文件或目录,并且可能会产生Docker范围之外的后果。

  • z选项表示绑定装载内容在多个容器之间共享。
  • Z选项表示绑定装载内容是私有且非共享的。

使用极端谨慎使用这些选项。绑定安装系统目录(例如/home/usr使用该Z选项)会导致主机无法运行,您可能需要手动重新标记主机文件。

重要提示:将bind mounts与服务一起使用时,selinux标签(:Z:z)以及将:ro被忽略。

此示例设置z选项以指定多个容器可以共享绑定装载的内容:

无法使用--mount标志修改selinux标签。

[root@benjamincloud ~]# docker run -itd --name devtest -v "$(pwd)"/target:/app:z nginx:latest
ecb63dfecfdb2602ee32c6e6a34930f86501a052a58fe0da8aacad1f31ecfdeb
[root@benjamincloud ~]# docker run -itd --name devtest2 -v "$(pwd)"/target:/app:z nginx:latest
3427fa5a5ff671454a64186d2cb8fda0553e6c7e912559d43265dd8724cbc2db
[root@benjamincloud ~]# docker run -itd --name devtest3 -v "$(pwd)"/target:/app:z nginx:latest
78abe5d52173bc7cc327983cbb9dac5bdc9bc3cb164fa4fb6940215299191be5

docker从零开始 存储(三)bind mounts的更多相关文章

  1. docker从零开始 存储(二)volumes 挂载

    使用volumes 卷是保存Docker容器生成和使用的数据的首选机制.mount binds依赖于主机的目录结构,而卷完全由Docker管理.卷绑定安装有几个优点: 与绑定装入相比,卷更易于备份或迁 ...

  2. docker从零开始 存储(一)存储概述

    管理Docker中的数据 默认情况下,在容器内创建的所有文件都存储在可写容器层中.这意味着: 当该容器不再运行时,数据不会持久存在,如果另一个进程需要,则可能很难从容器中获取数据. 容器的可写层紧密耦 ...

  3. docker从零开始 存储(四)tmpfs挂载

    使用tmpfs挂载 volume和bind mounts允许您在主机和容器之间共享文件,以便即使在容器停止后也可以保留数据. 如果你在Linux上运行Docker,你有第三个选择:tmpfs moun ...

  4. docker从零开始 存储(五)存储驱动介绍

    关于存储驱动程序 要有效地使用存储驱动程序,了解Docker如何构建和存储镜像以及容器如何使用这些镜像非常重要.您可以使用此信息做出明智的选择,以确定从应用程序中保留数据的最佳方法,并避免在此过程中出 ...

  5. docker从零开始 存储(六)存储驱动如何选择

    Docker存储驱动程序 理想情况下,将非常少的数据写入容器的可写层,并使用Docker卷来写入数据.但是,某些工作负载要求您能够写入容器的可写层.这是存储驱动程序的用武之地. Docker使用可插拔 ...

  6. docker从零开始(三)服务初体验docker compose

    决条件 安装Docker 1.13或更高版本. 获取Docker Compose.在适用于Mac的Docker和适用于Windows的Docker上,它已预先安装,因此您可以随意使用.在Linux系统 ...

  7. [转帖]Docker的数据管理(volume/bind mount/tmpfs)

    Docker(十五)-Docker的数据管理(volume/bind mount/tmpfs) https://www.cnblogs.com/zhuochong/p/10069719.html do ...

  8. Docker(十五)-Docker的数据管理(volume/bind mount/tmpfs)

    Docker提供了三种不同的方式用于将宿主的数据挂载到容器中:volumes,bind mounts,tmpfs volumes.当你不知道该选择哪种方式时,记住,volumes总是正确的选择. vo ...

  9. Docker的数据管理(volume/bind mount/tmpfs)

    Docker提供了三种不同的方式用于将宿主的数据挂载到容器中:volumes,bind mounts,tmpfs volumes.当你不知道该选择哪种方式时,记住,volumes总是正确的选择. vo ...

随机推荐

  1. NHibernate3.3.3 学习笔记1

    前言 昨天在园友的介绍下,我找了一本学习NHibernate的书:<NHibernate 3 Beginner’s Guide>. 第一章我直接跳过了,因为是英文版的看起来很吃力,且第一章 ...

  2. js保留两位小数,不四舍五入

    //不进行四舍五入,保留两位小数 function getKeepTwoDecimals(val) { var newVal = (parseInt(val * 100) / 100).toFixed ...

  3. LTE中基于S1的切换

    1:源eNodeB决定进行基于S1的切换.S1切换的原因可能是源eNodeB和目标eNodeB之间不存在X2连接,或者源eNodeB根据其他情况作出的判断. 2:源eNodeB向源MME发送Hando ...

  4. windows apache启动报错

    Windows启动Apache时报错 he requested operation has failed 有可能80端口被占或者项目路径不存在等 首先找到问题原因 cmd--命令端--切换到apach ...

  5. arc068 E: Snuke Line

    首先要知道 (m/1 + m/2 + ... + m/m) 约为 mlogm 还有一个比较明显的结论,如果一个纪念品区间长度大于d,那么如果列车的停车间隔小于等于d,则这个纪念品一定能被买到 然后把区 ...

  6. [洛谷P1747]好奇怪的游戏

    题目大意:有两匹马,马可以走"日",也可以像象走"田",求它走到(1,1)的步数. 题解:bfs 卡点:边界判断成了可以走到(0,y)或(x,0) C++ Co ...

  7. GYM - 100814 C.Connecting Graph

    题意: 初始有n个点,m次操作.每次操作加一条边或者询问两个点第一次连通的时刻(若不连通输出-1). 题解: 用并查集维护每个点所在连通块的根.对于每次加边,暴力的更新新的根. 每次将2个块合并时,将 ...

  8. [Leetcode] Remove duplicates from sorted list 从已排序的链表中删除重复元素

    Given a sorted linked list, delete all duplicates such that each element appear only once. For examp ...

  9. [Leetcode] candy 糖果

    There are N children standing in a line. Each child is assigned a rating value. You are giving candi ...

  10. [Leetcode] 3sum 三数和

    Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all un ...