1. mount namespace

mount namespace 通过隔离文件系统挂载点对隔离文件系统提供支持。使用 unshare 构造 mount namespace 如下:

root@chunqiu:~/chunqiu/docker/mount# dd if=/dev/zero bs=1M count=32 of=./disk1.img
root@chunqiu:~/chunqiu/docker/mount# dd if=/dev/zero bs=1M count=32 of=./disk2.img
root@chunqiu:~/chunqiu/docker/mount# mkfs.ext4 ./disk1.img
root@chunqiu:~/chunqiu/docker/mount# mkfs.ext4 ./disk2.img root@chunqiu:~/chunqiu/docker/mount# ls
disk1 disk1.img disk2 disk2.img root@chunqiu:~/chunqiu/docker/mount# mount disk1.img disk1
root@chunqiu:~/chunqiu/docker/mount# df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/loop0 ext4 27M 395K 25M 2% /root/chunqiu/docker/mount/disk1 root@chunqiu:~/chunqiu/docker/mount# readlink /proc/$$/ns/mnt
mnt:[4026531840]

开启另一个 shell 窗口,并创建 mount namespace:

root@chunqiu:~# unshare --mount /bin/bash
root@chunqiu:~# readlink /proc/$$/ns/mnt
mnt:[4026532206] root@chunqiu:~# df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/loop0 ext4 27M 395K 25M 2% /root/chunqiu/docker/mount/disk1
root@chunqiu:~/chunqiu/docker/mount# mount disk2.img disk2
root@chunqiu:~/chunqiu/docker/mount# df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/loop0 ext4 27M 395K 25M 2% /root/chunqiu/docker/mount/disk1
/dev/loop1 ext4 27M 395K 25M 2% /root/chunqiu/docker/mount/disk2 root@chunqiu:~/chunqiu/docker/mount# touch disk1/demo; touch disk2/demo

回到原 mount namespace:

root@chunqiu:~/chunqiu/docker/mount# df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/loop0 ext4 27M 395K 25M 2% /root/chunqiu/docker/mount/disk1 root@chunqiu:~/chunqiu/docker/mount# ls disk1
demo
root@chunqiu:~/chunqiu/docker/mount# ls disk2

可以看到,通过 mount namespace 实现了文件系统的隔离:

  • 每个 mount namespace 都拥有一份自己的挂载点列表,创建新 mount namespace 时,新创建的 mount namespace 将拷贝一份老 mount namespace 的挂载点列表给自己。
  • 默认情况下所有挂载状态是私有的。
  • mount namespace 实现了文件系统的隔离。上例中子文件系统 disk2 不会映射到父 mount namespace,同样的文件系统下创的文件对父 mount namespace 隔离。

1.1 挂载传播

上例中介绍了默认情况下所有挂载状态是私有的。那么,如果父 mount namespace 挂载了一张硬盘,在子 mount namespace 是不可见的,需要在子 mount namespace 中重新 mount。而挂载传播(mount propagation) 解决了这个问题。它定义了挂载对象之间的关系,系统用这些关系决定了挂载对象中的挂载事件如何传播到其它挂载对象。

挂载传播的详细信息可参阅 man mount,这里以共享和私有挂载为例查看这两种挂载方式是如何影响子 mount namespace 的:

root@chunqiu:~/chunqiu/docker/mount# ls
disk1 disk1.img disk2 disk2.img root@chunqiu:~/chunqiu/docker/mount# mount --make-shared disk1.img ./disk1
root@chunqiu:~/chunqiu/docker/mount# mount --make-private disk2.img ./disk2
root@chunqiu:~/chunqiu/docker/mount# df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/loop0 ext4 27M 383K 25M 2% /root/chunqiu/docker/mount/disk1
/dev/loop1 ext4 27M 395K 25M 2% /root/chunqiu/docker/mount/disk2 root@chunqiu:~/chunqiu/docker/mount# cat /proc/self/mountinfo |grep disk| sed 's/ - .*//'
54 25 7:0 / /root/chunqiu/docker/mount/disk1 rw,relatime shared:40
55 25 7:1 / /root/chunqiu/docker/mount/disk2 rw,relatime

开启另一个 shell 窗口,并创建 mount namespace:

root@chunqiu:~# unshare --mount --propagation unchanged /bin/bash
root@chunqiu:~# df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/loop0 ext4 27M 383K 25M 2% /root/chunqiu/docker/mount/disk1
/dev/loop1 ext4 27M 395K 25M 2% /root/chunqiu/docker/mount/disk2 root@chunqiu:~# cat /proc/self/mountinfo |grep disk| sed 's/ - .*//'
/* disk1 是 shared 是因为 unshare 指明了 propagation unchanged,如果未指定,默认是私有的 */
116 63 7:0 / /root/chunqiu/docker/mount/disk1 rw,relatime shared:40
118 63 7:1 / /root/chunqiu/docker/mount/disk2 rw,relatime

在原 mount namespace 中创建“硬盘”并模仿挂载事件:

root@chunqiu:~/chunqiu/docker/mount# dd if=/dev/zero bs=1M count=32 of=./disk3.img
root@chunqiu:~/chunqiu/docker/mount# dd if=/dev/zero bs=1M count=32 of=./disk4.img
root@chunqiu:~/chunqiu/docker/mount# mkfs.ext4 ./disk3.img
root@chunqiu:~/chunqiu/docker/mount# mkfs.ext4 ./disk4.img root@chunqiu:~/chunqiu/docker/mount# mkdir disk2/disk4
root@chunqiu:~/chunqiu/docker/mount# mkdir disk1/disk3 root@chunqiu:~/chunqiu/docker/mount# mount disk3.img disk1/disk3/
root@chunqiu:~/chunqiu/docker/mount# mount disk4.img disk2/disk4/

查看子 mount namespace 的挂载信息:

root@chunqiu:~# df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/loop0 ext4 27M 384K 25M 2% /root/chunqiu/docker/mount/disk1
/dev/loop1 ext4 27M 396K 25M 2% /root/chunqiu/docker/mount/disk2
/dev/loop2 ext4 27M 395K 25M 2% /root/chunqiu/docker/mount/disk1/disk3

可以看到共享的挂载传播方式,文件系统内的挂载事件会映射到子 mount namespace 而私有的挂载传播方式则不会。

docker 原理之 mount namespace(下)的更多相关文章

  1. docker原理

    Docker原理11 Linux Namespace 11 AUFS文件系统17 重新理解Docker的各种命令18 Docker原理 Linux Namespace docker是一个容器引擎,容器 ...

  2. docker 深入理解之namespace

    namespace 名称空间 docker容器主要通过资源隔离来实现的,应该具有的6种资源隔 namespace 的六项隔离 namespace 系统调用参数 隔离的内容 UTS CLONE_NEWU ...

  3. Docker容器的原理与实践 (下)

    欢迎访问网易云社区,了解更多网易技术产品运营经验. Docker原理分析 Docker架构 镜像原理 镜像是一个只读的容器模板,含有启动docker容器所需的文件系统结构及内容Docker以镜像和在镜 ...

  4. Docker原理:Namespace

    目录 Namespace UTS Namespae PID Namespace Mount Namespace User Namespace Network Namespace 参考 Namespac ...

  5. 一篇文章带你吃透 Docker 原理

    容器的实现原理 从本质上,容器其实就是一种沙盒技术.就好像把应用隔离在一个盒子内,使其运行.因为有了盒子边界的存在,应用于应用之间不会相互干扰.并且像集装箱一样,拿来就走,随处运行.其实这就是 Paa ...

  6. Docker原理(图解+秒懂+史上最全)

    背景:下一个视频版本,从架构师视角,尼恩为大家打造高可用.高并发中间件的原理与实操. 目标:通过视频和博客的方式,为各位潜力架构师,彻底介绍清楚架构师必须掌握的高可用.高并发环境,包括但不限于: 高可 ...

  7. 一篇不一样的docker原理解析

    转自:https://zhuanlan.zhihu.com/p/22382728 https://zhuanlan.zhihu.com/p/22403015 在学习docker的过程中,我发现目前do ...

  8. Docker原理探究

    问题思考:-------------------------------------Docker浅显原理理解-------------------------------------P1. ubunt ...

  9. docker原理(转)

    转自:https://zhuanlan.zhihu.com/p/22382728 https://zhuanlan.zhihu.com/p/22403015 在学习docker的过程中,我发现目前do ...

  10. Docker 容器资源隔离 namespace(十)

    目录 一.简介 Linux Namespace的6大类型 二.Mount Namespace 三.IPC Namespace 四.Network Namespace 五.UTS Namespace 六 ...

随机推荐

  1. jextract的使用

    写这个博客的目的:新人去看jextract的官网是看不懂的,就算看懂了也不会使用,一头雾水,我会从0开始教如何使用,如何搭配java去调用c函数. 首先我们得了解jextract是什么,官网的解释是一 ...

  2. 从零玩转前后端加解密之SM2-sm2

    title: 从零玩转前后端加解密之SM2 date: 2022-08-21 19:42:00.907 updated: 2023-03-30 13:28:48.866 url: https://ww ...

  3. 【OpenCV】 OpenCV 源码编译并实现 CUDA 加速 (Windows)

    目录 1. 环境准备 1.1 软件环境 1. 2 源码下载 2. CMake编译项目 2.1 创建cmake项目 2.2 设置编译配置 2.3 解决异常 2.3.1 文件下载异常 2.3.2 解决CU ...

  4. JAVAAPI实现血缘关系Rest推送到DataHub V0.12.1版本

    DataHub 更青睐于PythonAPI对血缘与元数据操作 虽然开源源码都有Java示例和Python示例:但是这个API示例数量简直是1:100的差距!!不知为何,项目使用Java编写,示例推送偏 ...

  5. Python——第二章:元组

    元组 tuple 使用小括号组成 特点: 元组是不可变的,固定了某些数据. t = ("张无忌", "赵敏", "呵呵哒") print(t ...

  6. JavaFx之controlsfx8下载(十七)

    JavaFx之controlsfx8下载(十七) controlsfx是JavaFx功能的扩展补充,这里我使用java8,我将源码下载下来并编译好jar,在java8的环境双击运行runSamples ...

  7. dfs之迭代加深

    为什么要用迭代加深 \(dfs\) 每次会选择搜索树的一个分支,不断深入,直到达到递归边界条件:但这种搜索策略带有一定的缺陷性: 如果搜索树的某一个分支中的节点个数特别多,但是答案并不在这棵子树里面, ...

  8. STM32CubeMX教程11 RTC 实时时钟 - 入侵检测和时间戳

    使用STM32CubeMX软件配置STM32F407开发板RTC实现入侵检测和时间戳功能,具体为周期唤醒回调中使用串口输出当前RTC时间,按键WK_UP存储当前RTC时间到备份寄存器,按键KEY_2从 ...

  9. 2024-01-13:用go语言,现在有一个打怪类型的游戏,这个游戏是这样的,你有n个技能, 每一个技能会有一个伤害, 同时若怪物小于等于一定的血量,则该技能可能造成双倍伤害, 每一个技能最多只能释放

    2024-01-13:用go语言,现在有一个打怪类型的游戏,这个游戏是这样的,你有n个技能, 每一个技能会有一个伤害, 同时若怪物小于等于一定的血量,则该技能可能造成双倍伤害, 每一个技能最多只能释放 ...

  10. CodeForces 1459C 数论 GCD

    CodeForces 1459C 数论 GCD 原题链接 题意 首先给出n个数 之后给出m个数,每次问之前的n个数加上当前的这个数之后,总体的gcd是多少,也就是答案需要求出m个总体的gcd 思路 因 ...