摘要:卷安装传播由 . 这种模式相当于内核文档中描述的挂载传播。 此卷挂载的工作原理类似于挂载。 安装传播可能很危险。 所谓的传播事件是指一个已安装对象中的状态更改导致其他已安装对象中的安装和卸载行为的事件。
挂载传播
挂载传播可让您与同一 Pod 或同一节点上的其他容器共享由容器挂载的卷 您将能够做吧。 其他豆荚。
卷挂载传播由 Container.volumeMounts 的 mountPropagation 字段控制。 其值为:
None 该卷挂载将不接受对该卷或该卷子目录的后续挂载。 同样,容器创建的挂载对主机不可见。 这是默认模式。
此模式相当于 Linux 内核文档中描述的私有传播。
HostToContainer 此卷安装接收对此卷或此卷的子目录的后续安装。
换句话说,当主机在卷挂载上挂载某些内容时,容器会看到那里挂载的内容。
同样,如果具有双向挂载传播的 pod 挂载在同一卷上,则具有HostToContainer挂载传播的容器将知道 Masu.
此模式相当于 Linux 内核文档中描述的 rslave 挂载传播。
双向 此卷挂载的行为与 HostToContainer 挂载相同。 此外,容器创建的所有卷挂载都会传播到主机上的所有容器以及使用同一卷的所有 Pod。
此模式的一个常见用例是使用 Flexvolume 或 CSI 驱动程序。Pod 必须使用 hostPath 卷模式在主机上挂载内容。
此模式相当于 Linux 内核文档中描述的 rshared 安装传播。
附加说明:
双向安装传播可能很危险。 它可能会损坏主机操作系统,并且只能在特权容器中使用。 强烈建议您熟悉 Linux 内核的工作原理。 此外,当容器退出时,容器内创建的卷挂载必须由容器销毁(卸载)。
一些双向使用场景:
在不同 Pod 之间共享设备。 安装发生在 Pod 内,但在 Pod 之间共享。
从容器内连接设备。 例如,从容器内连接 iSCSI 设备。 这是因为当容器死亡时,主机没有正确刷新写入和断开设备连接所需的信息(除非使用双向挂载传播)。
示例
部署:容器:- 图片:gcr.io/google_containers/busybox:1.24 名称:Reader 卷:- 挂载:/usr/test- Pod 存储:local-vol 传播:双向 名称:local-test-reader 版本:extension/v1beta1 卷:local-vol:pvc:example-local-claim
配置
为了使挂载传播在给定部署(CoreOS、RedHat/Centos、Ubuntu)中正常工作,必须在 Docker 中正确配置挂载共享,如下所示。
编辑多克rsystemd服务文件。 设置MountFlags如下:
MountFlags=shared
或者,如果存在,则删除 MountFlags = SLAVE。 接下来,重新启动 Docker 守护进程。
$ sudo systemctl daemon-reload$ sudo systemctl restart docker
具体案例
为什么我们关心这个:实际使用k8s时这是因为发生了相关问题。
容器业务 大部分日志收集是通过 sidecar 完成的,sidecar 将日志挂载到主机上的目录中。 日志量很大,即使在每台主机上挂载1T硬盘,这个磁盘也经常会被占满。 因此我实现了 log-tracer 项目,该项目用于根据 pod 日志挂载信息等清除过期日志。 通过 daemonset 部署。
但是,如果挂载设置为私有,则不会有广播通知。 实际添加 Pod 后,有些日志挂载无法被发现,因此无法彻底清理。
走到最后
深入分析一下,这个功能并不是k8s或者docker实现的。 它基本上是挂载命名空间的一个功能。
挂载命名空间通过隔离文件系统挂载点提供对隔离文件系统的支持。 由于这是第一个 Linux 命名空间,因此它的标识位非常特殊:CLONE_NEWNS。 分离后,不同挂载命名空间的文件结构变化不会互相影响。 通过/proc/[pid]/mounts可以查看当前命名空间下挂载的所有文件系统。 还可以通过/proc/[pid]/mountstats查看挂载命名空间中的文件。设备统计信息,包括安装的文件名、文件系统类型、安装位置等。
当进程创建挂载命名空间时,当前文件结构将被复制到新的命名空间。 新命名空间中的所有挂载操作仅影响命名空间自己的文件系统,而不影响外界。 这提供了非常严格的分离,但在某些情况下可能并非如此。 例如,父节点命名空间中的进程挂载 CD-ROM。 目前该操作影响父节点,因此子节点namespace复制的目录结构无法自动挂载CD-ROM。 文件系统。
2006 年推出的挂载传播解决了这个问题。 安装传播定义了安装对象之间的关系。 系统使用这些关系来确定已安装对象的内容。 如何将挂载事件传播到其他挂载对象(来源:http://www.ibm.com/developerw...)。 所谓的传播事件是指一个已安装对象中的状态更改导致其他已安装对象中的安装和卸载行为的事件。
分享关系。 当两个挂载对象具有共享关系时,一个挂载对象的挂载事件将传播到另一个挂载对象,反之亦然。
从属关系。 当两个挂载对象形成依赖关系时,来自一个挂载对象的挂载事件将传播到另一个挂载对象,但反之则不然。 在这种关系中,依赖对象是事件的接收者。
安装状态可以是以下之一:
共享挂载(共享)
从属挂载(从属)
共享/从属挂载(共享和从属)
私有挂载(私有)
不可绑定挂载(non-bindable)
默认情况下,以下所有挂载都是私有的。 您可以使用以下命令显式标记已安装的对象:挂载共享:
mount --make-shared
例如 / 上的挂载需要共享,如果所以,然后运行以下命令:
mount --make-shared /
从共享挂载克隆的挂载对象也是共享挂载。 它们相互传播挂载事件。
您可以通过运行以下命令将共享挂载显式转换为从属挂载:
mount --make-slave
从从挂载克隆的挂载对象也是从挂载,并且也从属于原始从挂载的主挂载对象。
您可以通过运行以下命令将已安装的对象标记为私有:
mount --make-private
您可以通过运行以下命令将已挂载的对象标记为不可绑定:
mount --make-unbindable
最后,所有这些设置可以递归应用。 也就是说,它适用于目标挂载以下的所有挂载。
将 mount --make-rshared /
/ 下的所有挂载转换为共享挂载。
参考资料
官方文档
了解Docker背后的内核——命名空间资源分离
评论前必须登录!
注册