目录

kubernetes 的挂载传播

kubernetes 的挂载传播

kubernetes 的挂载传播 mountPropagation


  • 说明

    • kubernetes 的 mountPropagation 翻译成中文就是挂载传播。挂载传播提供了共享卷挂载的能力, 它允许在同一个 Pod, 甚至同一个节点内, 在多个容器之间共享卷的挂载。 说白了就是 在 容器或 host 内的挂载目录中 再 mount 了一个别的挂载。

    • kubernetes 中 卷的挂载传播由 Container.volumeMountsmountPropagation 字段控制。它的值包含如下三种

      • None: - 这种卷挂载将不会收到任何后续由 host 创建的在这个卷上或其子目录上的挂载。同样的, 由容器创建的挂载在 host 上也是不可见的。这是默认的模式。这个其实很好理解, 就是容器内和 host 的后续挂载完全隔离。

      • HostToContainer: - 这种卷挂载将会收到之后所有的由 host 创建在该卷上或其子目录上的挂载。换句话说, 如果 host 在卷挂载内挂载的任何内容, 在容器中都是可见的。同样, 如果任何具有 Bidirectional 的 Pod 挂载传播到该卷挂载上, 具有 HostToContainer 的挂载传播都可以看见。

      • Bidirectional: - 这种挂载机制和 HostToContainer 类似。此外, 任何在容器中创建的挂载都会传播到 host, 然后传播到使用相同卷的所有 Pod 的所有容器。注意: Bidirectional 挂载传播是很危险的。可能会危害到 host 的操作系统。因此只有特权 securityContext: privileged: true 容器在允许使用它。


  • 挂载传播流程图

https://jicki.cn/img/posts/kubernetes/mount-propagation.png

测试

  1. mountPropagation: None
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
apiVersion: v1
kind: Pod
metadata:
    name: mount-none
    label:
      app: mount
spec:
    containers:
    - name: main
      image: nginx:latest
      volumeMounts:
      - name: testmount
        mountPath: /home
        mountPropagation: None
    volumes:
    - name: testmount
      hostPath:
        path: /mnt/

host 上创建挂载, 既在 /mnt 的目录下创建另一个挂载

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
mkdir /mnt/none

# 将本地的 /var 目录挂载过来
sudo mount --bind /var /mnt/none

# 查看
ls /mnt/none

backups  cache	lib  local  lock  log  mail  opt  run  spool  tmp

容器 上查看, 可以看到只有创建的 none 目录, 但是挂载内容为空.

1
2
3
4
# 容器内的挂载点为 /home

ls /home/none


  1. mountPropagation: HostToContainer
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
apiVersion: v1
kind: Pod
metadata:
    name: mount-host
    label:
      app: mount
spec:
    containers:
    - name: main
      image: nginx:latest
      volumeMounts:
      - name: testmount
        mountPath: /home
        mountPropagation: HostToContainer
    volumes:
    - name: testmount
      hostPath:
        path: /mnt/

host 上创建挂载, 既在 /mnt 的目录下创建另一个挂载

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
mkdir /mnt/hostto

# 将本地的 /var 目录挂载过来
sudo mount --bind /var /mnt/hostto

# 查看
ls /mnt/hostto

backups  cache	lib  local  lock  log  mail  opt  run  spool  tmp

容器 上查看, 可以看到只有创建的 hostto 目录, 里面是有内容的, 这里是 host 可以将挂载传递到 容器里面, 不过反过来容器是传递不到 host 里的。

1
2
3
4
5
6
# 容器内的挂载点为 /home

ls /home/hostto

backups  cache	lib  local  lock  log  mail  opt  run  spool  tmp


  1. mountPropagation: Bidirectional
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
apiVersion: v1
kind: Pod
metadata:
    name: mount-bidir-a
    labels:
      app: mount
spec:
    containers:
    - name: main
      image: nginx:latest
      # Bidirectional 需要开启特权模式才可以使用
      securityContext:
        privileged: true
      volumeMounts:
      - name: testmount
        mountPath: /home
        mountPropagation: Bidirectional
    volumes:
    - name: testmount
      hostPath:
        path: /mnt/

---
apiVersion: v1
kind: Pod
metadata:
    name: mount-bidir-b
    labels:
      app: mount
spec:
    containers:
    - name: main
      image: nginx:latest
      # Bidirectional 需要开启特权模式才可以使用
      securityContext:
        privileged: true
      volumeMounts:
      - name: testmount
        mountPath: /home
        mountPropagation: Bidirectional
    volumes:
    - name: testmount
      hostPath:
        path: /mnt/

在容器 mount-bidir-a 中创建一个挂载

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# exec 进入容器
kubectl exec -it mount-bidir-a sh

# 创建一个目录
mkdir /home/bidir


# 在容器中创建挂载
mount --bind /var /home/bidir

# 查看
ls /home/bidir

backups  cache	lib  local  lock  log  mail  opt  run  spool  tmp

host 上查看目录, 这里可以看到已经将 挂载传递到了 host

1
2
3
4
ls /mnt/bidir

backups  cache	lib  local  lock  log  mail  opt  run  spool  tmp

在容器 mount-bidir-b 上查看, 也已经将挂载传递到了 另一个容器 b 上

1
2
3
4
5
6
7
8
9
# exec 进入容器
kubectl exec -it mount-bidir-b sh


# 查看
ls /home/bidir

backups  cache	lib  local  lock  log  mail  opt  run  spool  tmp

linux mount 的几种类型

  • 上面介绍了 kubernetes 的挂载传播机制, 在 linux mount 中, 也有类似的概念。

  • mount 分为下面几种:

    • shared mount: - 相当于上面所说的 Bidirectional 的挂载传播。

    • slave mount: - 每个 slave mount 都有一个 shared master mount, 挂载传播只能从 master -> slave, 等同于上面的 HostToContainer, host 是 master,container 是 slave。

    • private mount: - 很明显, private 就是相当于 None,挂载不会向任何一方传播。

    • unbindable mount: - 其实就是 unbindable private mount, 也就是不允许使用 –bind 的挂载。