xiaohanliang
Docker
Docker
  • hi
  • STORAGE DRIVER
    • 1. 什么叫联合挂载
    • 2. 镜像ID是从哪来的
    • 3. 如何组装出一个镜像
    • 4. 为什么有这么多fs@aufs
    • 5. 为什么有这么多fs@overlay
    • 6. 为什么有这么多fs@dm
    • 7. 正确安装devicemapper
  • EXEC DRIVER
    • 1. 资源限制-cgroup
    • 2. 制造小型监狱
    • 3. 切换根目录是什么概念
    • 4. 标准极简容器runC
    • 5. 尝试安装runc工具
  • KUBERNETES NETWORK
    • 0. [WIP]我想串联容器网络的故事
    • 1. 容器网络是什么样的网络
    • 2. cnm认为应该怎样让容器组网
    • 3. 为什么会有一大堆cni插件
    • 4. 为什么要设计出pod
    • 5. 怎样形成一个服务
    • 6. Service就是iptables规则
    • 7. IPVS也能实现Service
    • 8. 从集群外访问服务-nodeport
    • 9. 从集群外访问服务-ingress
    • 10. 想要把域名变成IP
    • 11. DNS是怎么实现的
    • 12. 最常见的方案@flannel
    • 13. 使用tun设备封包@flannel
    • 14. 使用vxlan设备封包@flannel
    • 15. 可不可以不封包@flannel
Powered by GitBook
On this page
  • introduction
  • 什么是rootfs
  • 那什么是切换rootfs
  • 涉足无人之地
  • 再次进入无人之地
  • 尾巴

Was this helpful?

  1. EXEC DRIVER

3. 切换根目录是什么概念

introduction

容器的表现, 我们已经说了如何限制资源, 不同于小型监狱, 这一节我们说说"pivot-root"是如何防止你在宿主机上 "到处乱窜"的. "pivot-root 用于切换rootfs". 想要知道怎么切换的rootfs, 就要先知道rootfs是啥

什么是rootfs

TLDR: 就是/. 在Linux中所有的文件系统都会有一个挂载位, rootfs 作为一种文件系统, 就挂载在"/". 所以我们说 rootfs 挂在哪儿, 哪儿就是"/". 有了 rootfs 以后, 其他文件系统就有了根路径, 他们挂载的位置就是相对于 rootfs 的路径, 我举个最简单的例子:

$ mount
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
tmpfs on /run type tmpfs (rw,nosuid,noexec,relatime)
...
  • 有一个名称 sysfs , 类型为 sysfs 的文件系统, 挂载在 "/sys"目录下

  • 有一个名称 proc , 类型为 proc 的文件系统, 挂载在 "/proc"目录下

  • 有一个名称 tmpfs , 类型为 tmpfs 的文件系统, 挂载在 "/run"目录下

那什么是切换rootfs

在上面我们已经说了, rootfs(/, 根路径)下挂载了很多, 各种类型的文件系统, 现在我们切换 rootfs 到 A去, 是不是他们就全都挂载到A上去了? 那么上面的那些挂载是不是, 都变成了 A/sys , A/proc, A/run了, 多说无益, 直接开整

涉足无人之地

# 创建了一个路径
$ mkdir pivot 
# 并在这个路径下挂载了大小为1G, 类型为 tmpfs 的临时文件系统.
$ mount -n -t tmpfs -o size=1G none pivot

# 进入这个临时文件系统, 并制造一个地方用于挂载之前的rootfs
$ cd pivot && mkdir old-rootfs
# 开始切换rootfs, 现在令pivot成为新的rootfs, 并将之前的挂载都挂到old下
$ unshare -m && pivot_root . old-rootfs

# 看看我们现在在哪儿
$ pwd
/root/pivot
# 你再仔细看看我们在哪儿????
$ cd . && pwd
/
# 什么鬼? 放我出去!!!
$ ls && mount && ps
-bash: ls:    command not found
-bash: mount: command not found
-bash: ps:    command not found

哈哈, 爽了吧? 翻车了, 你现在已经进入无人之地了, 这就是你进入一个完全空白镜像以后, 你能看到的东西, 毛都没, 是真的连根毛都没. 你之所以看到这些吓人的 "Command Not Found" 是因为文件系统现在全挂到 old-rootfs下了, 那么至于你现在在的位置, 就是新的 "/" 根路径, 这个路径下除了 old-rootfs 什么都没有.

正是因为没有 /bin/{ls, mount, ps}这些装备, 才会让你感觉好像直接遁入了虚空一样, 你现在可以通过 logout / exit / control+D 的方式退出无人之地, 然后我们准备一些装备, 再进去好了~

再次进入无人之地

这次我们要准备一些装备, 第一次, 我们先准备个ls工具, 当成手电筒, 查看查看情况 :

# 准备bin文件夹, 我们到时候需要用这个文件夹里的ls工具
$ cd pivot && mkdir bin
$ cp /bin/ls ./bin

# ls工具依赖一些库, 然后我们也搞来这些库
$ ldd /bin/ls
        linux-vdso.so.1 =>  (0x00007ffe79396000)
        libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f4382997000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f43825cd000)
        libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f438235d000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f4382158000)
        /lib64/ld-linux-x86-64.so.2 (0x00005644db278000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f4381f3b000)
$ mkdir lib lib64
$ cp /lib/x86_64-linux-gnu/<xxx> ./lib
$ cp /lib64/ld-linux-x86-64.so.2 ./lib64

# 好! 再来一次! 结界! 启用!
$ unshare -m && 
  pivot_root . old-rootfs/ && 
  cd . && pwd
/
# 可以了这一回! 
$ ls
bin  lib  lib64  old-rootfs

终于, 我们打开了手电筒(ls), 看到了我们处在新的结界(根目录)中, 手电筒照亮了脚下, 看到了我们带进结界的工具, 有bin, lib, lib64, 还看到废墟: old-rootfs, 此时所有之前的文件系统全都挂载在old-rootfs, 但是我们现在用 "/"当成根目录, 因此废墟里面满满的工具, 库, 都跟我们没关系, 你都用不了, 你只有一个手电筒.

尾巴

这次我们从零开始想象, 如果是空白镜像我们会看到什么, 如何带一些工具进镜像, 我们会看到什么, 这个过程基本解答了:

  • pivot-root: 如何创造一个完全空白的结界, 这是我们囚禁容器内进程的方法, 将它困在结界里

  • bin/lib/lib64: 如何让你的空白结界里带有一些工具, 让容器内进程可以开始做一些事, 这些工具, 由底层存储驱动 aufs / dm / overlay 联合多层镜像最后一起提供

跟chroot的区别? 他俩都能达到囚禁的效果, 但是pivot-root直接将当前进程所在namespace下的所有文件系统全部转移了. 而chroot还要依赖之前的文件系统, 你看在我们的例子中, 我们重建了一套 tmpfs , 结界里的内容都会存在这里, 到时候umount一下废墟, 再删除废墟路径, 就真的完全什么都没有了.

写完这些可能已经11:40了, 但当时, 在我第二次进入结界的时候, 我真的一点没感觉累, 我觉得很兴奋, 我有一种我反复穿梭表世界 / 里世界的感觉, 我感觉我好像在玩 Undertale 一样, 我进入了地底世界, 我只带了一个手电筒照着路慢慢往前走, 前面就是怪物王国的废墟, 就会有 Flowey 羊妈 Sans Papyrus 在等着我, 这种感觉真的很让人兴奋

Previous2. 制造小型监狱Next4. 标准极简容器runC

Last updated 4 years ago

Was this helpful?