CgroupNamespace 的管理下,容器其实是一个隔离和限制的 子系统,那么容器的文件系统又是如何隔离开来的呢?

Chroot 命令

chroot : 改变进程的根目录到你指定的 的位置

# 将 /bin/bash进程的根目录指定为 /leon0204/home
# 执行 ls 将显示 /leon0204/home 下的文件
$ chroot /leon0204/home /bin/bash

对于 /bin/bash 来说,它的根目录就改变了,这种修改视图的方法和namespace 是一个原理。

Rootfs

上节我们已经知道,容器启动的是一个父进程和N个 fork 出来的子进程,并且这个父进程被 chroot 修改了视图,所以容器的根目录就是一个隔离的子目录,为了让这个目录看起来更像一个系统,往往会在这个目录下增加一些 系统的文件、目录和配置 ,比如 /bin ,/etc 等。

rootfs 即是容器镜像的本身,是一个操作系统所包含的文件,配置和目录,并不包括操作系统内核,在Linux系统开机时,需要加载系统内核,那么一个镜像的rootfs没有了 内核,如何正常加载呢?

由于 docker 的内核是建立在 宿主机 上的,与宿主机共享内核,记住:docker 没有自己的内核。所以 dockerrootfs 实际上打包的不只是应用,而是整个 操作系统 ,即应用运行的所有的依赖,而不是从语言层面上的依赖。这样解决了跨机器的环境同步问题。

Layer 按层发布

A同事发布一个JAVA应用,会包含了一个操作系统的rootfs ,B同事发布一个JAVA应用同样需要制作一个 rootfs ,如何提取我们之间的 共性 ?制造出一个基础的镜像(base image)?
docker 在这方面实现上,引入了 layer(层) 的概念,在A和B 制作 rootfs docker 镜像系统的时候,把每一步记录下来,作为一个 ,取AB rootfs 的交集形成我们 JAVA base 镜像 ,以后我们发布各自的应用都可以使用这个镜像。

UFS

联合文件系统 UFS Union File SystemUnionFS :功能是将多个不同的目录 unoin mount 到一个目录下,比如A和B目录的文件可以联合挂载到C目录下。这样 A&B下的文件就和C形成了挂载,同步 增减改变。

AUFS

AUFS 是对 Union FS 的重写和改进的版本,这也是 docker 使用的版本,以 Mysql:5.6 的镜像为例子,查看这个镜像(rootfs)的AUFS结构如下:

[root@macco-web ~]# docker image inspect mysql:5.6
"RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:9c2f1836d49346677f8280bf0eb89c20853f6af4aa6e2fad87b0000bb181fad2",
                "sha256:fd3b39222ee496a3cc115a4142a26babcad2f2008f4053ad5f893fcc503cd7fe",
                "sha256:7ffd9f004dec5b25c7861e97e8f4ed5534f980b270fe03d0b834c0e6db843564",
                "sha256:c782fd1b83e9e2b2a904c57cb887b59fd58704712ad73452de817abbd2d766a8",
                "sha256:db76afa2e4c2f4c0077d028f37d73a6408cf2fc4bca1b0156225edd02f7e5cbc"
            ]
        },

可以看到这个 docker 是由 5layer)组成的,每一层实际上就是 系统的一个组成部分,包含了文件和目录,在使用的时候使用 AUFS 挂载 组成了镜像rootfs 子系统,我们查看这个目录下有哪些文件:

# pwd
/statics/docker/overlay/f8611219ff61896ca3ac0edc4e1c2207f934da81492c901b7768d115896f8cab/root
# ls
bin  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var

总结

容器通过 aufsdocker 创建出了一个完整的 rootfs linux 文件系统,也就是我们说的一个容器镜像。
而镜像又通过 layer 层 分层设计,将镜像的设计变成了增量式的,使得协作的base 变得更小,协作的方式变得更迅捷,而每个人都是用 base 镜像 ,使得容器 一致性 得以实现。

Namespace做隔离;Cgroups做限制;Rootfs做子系统

GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐