Docker容器基础:文件系统
在 Cgroup
和 Namespace
的管理下,容器其实是一个隔离和限制的 子系统
,那么容器的文件系统又是如何隔离开来的呢?
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 没有自己的内核
。所以 docker
的rootfs
实际上打包的不只是应用,而是整个 操作系统
,即应用运行的所有的依赖,而不是从语言层面上的依赖。这样解决了跨机器的环境同步问题。
Layer 按层发布
A同事发布一个JAVA应用,会包含了一个操作系统的rootfs ,B同事发布一个JAVA应用同样需要制作一个 rootfs ,如何提取我们之间的 共性
?制造出一个基础的镜像(base image
)?
docker 在这方面实现上,引入了 layer
(层) 的概念,在A和B 制作 rootfs docker
镜像系统的时候,把每一步
记录下来,作为一个 层
,取AB rootfs 的交集形成我们 JAVA base 镜像
,以后我们发布各自的应用都可以使用这个镜像。
UFS
联合文件系统 UFS Union File System
。UnionFS
:功能是将多个不同的目录 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 是由 5
个 layer
(层
)组成的,每一层实际上就是 系统的一个组成部分,包含了文件和目录
,在使用的时候使用 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
总结
容器通过 aufs
为 docker
创建出了一个完整的 rootfs linux
文件系统,也就是我们说的一个容器镜像。
而镜像又通过 layer 层
分层设计,将镜像的设计变成了增量式的,使得协作的base 变得更小,协作的方式变得更迅捷,而每个人都是用 base 镜像
,使得容器 一致性
得以实现。
Namespace做隔离;Cgroups做限制;Rootfs做子系统
更多推荐
所有评论(0)