资讯专栏INFORMATION COLUMN

谈谈k8s1.12新特性--Mount propagation(挂载命名空间的传播)

DTeam / 1372人阅读

摘要:一个卷的挂载传播由中的字段控制。此模式等同于内核文档中描述的挂载传播。此卷挂载的行为与挂载相同。挂载传播可能很危险。所谓传播事件,是指由一个挂载对象的状态变化导致的其它挂载对象的挂载与解除挂载动作的事件。

Mount propagation

挂载传播允许将Container挂载的卷共享到同一Pod中的其他Container,甚至可以共享到同一节点上的其他Pod。
一个卷的挂载传播由Container.volumeMounts中的mountPropagation字段控制。它的值是:

None 此卷挂载不会接收到任何后续挂载到该卷或是挂载到该卷的子目录下的挂载。以类似的方式,在主机上不会显示Container创建的装载。这是默认模式。

此模式等同于Linux内核文档中所述的 private 传播。

HostToContainer 此卷挂载将会接收到任何后续挂载到该卷或是挂载到该卷的子目录下的挂载。

换句话说,如果主机在卷挂载中挂载任何内容,则Container将看到它挂载在那里。
类似地,如果任何具有 Bidirectional 挂载传播设置的Pod挂载到同一个卷中,那么具有HostToContainer挂载传播的Container将会看到它。
此模式等同于Linux内核文档中描述的rslave挂载传播。

Bidirectional 此卷挂载的行为与HostToContainer挂载相同。此外,Container创建的所有卷挂载都将传播回主机和所有使用相同卷的Pod的所有容器。

此模式的典型用例是具有Flexvolume或CSI驱动程序的Pod需要使用hostPath 卷模式 在主机上挂载内容。
此模式等同于Linux内核文档中描述的rshared安装传播。
PS:
Bidirectional 挂载传播可能很危险。它可能会损坏主机操作系统,因此只允许在特权容器中使用它。强烈建议您熟悉Linux内核行为。此外,容器在容器中创建的任何卷装入必须在终止时由容器销毁(卸载)。

Bidirectional一些使用场景:

在不同的pod之间共享设备,其中挂载发生在pod中,但是在pod之间共享。

从容器内部附加设备。例如,从容器内部附加ISCSI设备。这时候因为如果容器死掉,主机将不能获得所需的信息(除非使用双向安装传播)来正确刷新写入和分离设备。

sample
deployment:
  containers:
  - image: gcr.io/google_containers/busybox:1.24
    name: reader
    volume:
    - mount: /usr/test-pod
      store: local-vol
      propagation: bidirectional
  name: local-test-reader
  version: extensions/v1beta1
  volumes:
    local-vol: pvc:example-local-claim
配置

在挂载传播可以在某些部署(CoreOS,RedHat / Centos,Ubuntu)上正常工作之前,必须在Docker中正确配置挂载共享,如下所示。
编辑Docker的systemdservice 文件。设置MountFlags如下:

MountFlags=shared

或者,如果存在,则删除MountFlags = slave。然后重启Docker守护进程:

$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
具体案例

之所以关注这块,是由于我们在实际使用k8s的过程中遇到了相关的问题。
我们容器业务日志的收集有很大一部分通过sidecar的方式,mount日志到主机某个目录。由于我们的日志量非常大,即使我们每个主机挂载了1T的硬盘,经常会写满这张盘。所以我们实现了一个log-tracer的项目,专门用于根据pod的日志挂载信息clear过期的日志。通过daemonset方式部署。
但是如果设置mount为private的话,缺乏广播通知。在实际新增pod后,有一部分的日志挂载是无法感测到,因而也无法彻底清理。

刨根问底

究其深层次分析,该特性并不是k8s或是docker实现的。本质上是mount namespace 的特性。

mount namespace通过隔离文件系统挂载点对隔离文件系统提供支持,它是历史上第一个Linux namespace,所以它的标识位比较特殊,就是CLONE_NEWNS。隔离后,不同mount namespace中的文件结构发生变化也互不影响。你可以通过/proc/[pid]/mounts查看到所有挂载在当前namespace中的文件系统,还可以通过/proc/[pid]/mountstats看到mount namespace中文件设备的统计信息,包括挂载文件的名字、文件系统类型、挂载位置等等。

进程在创建mount namespace时,会把当前的文件结构复制给新的namespace。新namespace中的所有mount操作都只影响自身的文件系统,而对外界不会产生任何影响。这样做非常严格地实现了隔离,但是某些情况可能并不适用。比如父节点namespace中的进程挂载了一张CD-ROM,这时子节点namespace拷贝的目录结构就无法自动挂载上这张CD-ROM,因为这种操作会影响到父节点的文件系统。

2006 年引入的挂载传播(mount propagation)解决了这个问题,挂载传播定义了挂载对象(mount object)之间的关系,系统用这些关系决定任何挂载对象中的挂载事件如何传播到其他挂载对象(参考自:http://www.ibm.com/developerw...)。所谓传播事件,是指由一个挂载对象的状态变化导致的其它挂载对象的挂载与解除挂载动作的事件。

共享关系(share relationship)。如果两个挂载对象具有共享关系,那么一个挂载对象中的挂载事件会传播到另一个挂载对象,反之亦然。

从属关系(slave relationship)。如果两个挂载对象形成从属关系,那么一个挂载对象中的挂载事件会传播到另一个挂载对象,但是反过来不行;在这种关系中,从属对象是事件的接收者。

一个挂载状态可能为如下的其中一种:

共享挂载(shared)

从属挂载(slave)

共享/从属挂载(shared and slave)

私有挂载(private)

不可绑定挂载(unbindable)

在默认情况下,所有挂载都是私有的。可以用以下命令将挂载对象显式地标为共享挂载:

mount --make-shared 

例如,如果 / 上的挂载必须是共享的,那么执行以下命令:

mount --make-shared /

从共享挂载克隆的挂载对象也是共享的挂载;它们相互传播挂载事件。

通过执行以下命令,可以显式地将一个共享挂载转换为从属挂载:

mount --make-slave 

从从属挂载克隆的挂载对象也是从属的挂载,它也从属于原来的从属挂载的主挂载对象。
通过执行以下命令,可以将挂载对象标为私有的:

mount --make-private 

通过执行以下命令,可以将挂载对象标为不可绑定的:

mount --make-unbindable 

最后,这些设置都可以递归地应用,这意味着它们将应用于目标挂载之下的所有挂载。

mount --make-rshared /

将 / 之下的所有挂载转换为共享挂载。

参考文献

官方文档

Docker背后的内核知识——Namespace资源隔离

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/33083.html

相关文章

  • 谈谈k8s1.12特性--Mount propagation(挂载命名空间传播)

    摘要:一个卷的挂载传播由中的字段控制。此模式等同于内核文档中描述的挂载传播。此卷挂载的行为与挂载相同。挂载传播可能很危险。所谓传播事件,是指由一个挂载对象的状态变化导致的其它挂载对象的挂载与解除挂载动作的事件。 Mount propagation 挂载传播允许将Container挂载的卷共享到同一Pod中的其他Container,甚至可以共享到同一节点上的其他Pod。一个卷的挂载传播由Con...

    高胜山 评论0 收藏0
  • 谈谈k8s1.12特性--Mount propagation(挂载命名空间传播)

    摘要:一个卷的挂载传播由中的字段控制。此模式等同于内核文档中描述的挂载传播。此卷挂载的行为与挂载相同。挂载传播可能很危险。所谓传播事件,是指由一个挂载对象的状态变化导致的其它挂载对象的挂载与解除挂载动作的事件。 Mount propagation 挂载传播允许将Container挂载的卷共享到同一Pod中的其他Container,甚至可以共享到同一节点上的其他Pod。一个卷的挂载传播由Con...

    xuhong 评论0 收藏0
  • Linux mount (第二部分 - Shared subtrees)

    简单点说,Shared subtrees就是一种控制子挂载点能否在其他地方被看到的技术,它只会在bind mount和mount namespace中用到,属于不怎么常用的功能。本篇将以bind mount为例对Shared subtrees做一个简单介绍, 本篇所有例子都在ubuntu-server-x86_64 16.04下执行通过 概述 回想一下上一篇中介绍的bind mount部分,如果b...

    zone 评论0 收藏0
  • Kubernetes 1.12发布!功能亮点解析

    摘要:距离上一次版本发布三个月之隔,是今年的第三个主要版本。证书轮换证书轮换功能现已进入状态。这一功能可以在当前证书到期时自动续订密钥和服务器的证书。更多包含许多修复和内部组件的改进,此次的更新明显侧重于稳定核心以及使现有的功能成熟。 Kubernetes1.12已于今日全新发布!Kubelet证书轮换、资源配额优先级、挂载命名空间、对Azure的增强支持等10大亮点功能,本文为你一一解读!...

    Developer 评论0 收藏0
  • docker/k8s/云

    摘要:执行容器内部运行的执行工作作为容器的执行驱动,负责创建容器运行命名空间,负责容器资源使用的统计与限制,负责容器内部进程的真正运行等。典型的在启动后,首先将设置为进行一系列检查然后将其切换为供用户使用。 在https://segmentfault.com/a/11... 容器,隔离,云的概述。这篇对其中用途广泛的docker,k8s做详细介绍,并给出云搭建的生态环境体系。 docker ...

    zollero 评论0 收藏0

发表评论

0条评论

DTeam

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<