docker rootfs
挂载在容器根目录上的文件系统,就是rootfs(根文件系统)。
rootfs只是一个操作系统所包含的文件,不包括操作系统内核。
在Linux中,操作系统文件和内核是分开存放的,操作系统只有在开机启动时才会加载指定版本的内核。同一台机器上的所有容器,都共享宿主机内核。
Docker创建容器主要流程是,配置Namespace和Cgroups,切换进程的根目录(优先使用pivot_root系统调用,如果系统不支持,那么会使用chroot)。
pivot_root和chroot以及chdir的区别
每个进程都有一个根目录,对应文件系统的真实根目录。每个进程都会继承父进程的根目录。
pivot_root:针对整个系统来切换根目录,umount原来的rootfs。创建临时目录来保存旧的rootfs,用镜像的根目录作为新的rootfs。切换根目录之后,需要通过chdir来修改当前工作目录到根目录。
chroot:针对某个进程来切换根目录,其他进程还是使用旧的rootfs。切换根目录之后,不需要通过chdir来修改当前工作目录到根目录。
chdir:针对某个进程来切换工作目录,对应的命令是cd。
rootfs联合挂载的3部分
第一部分,只读层
包含etc、bin、home等目录。
第二部分,Init层
存放/etc/hosts、/etc/resolv.conf等文件。这些配置信息只针对当前容器有效,修改这些文件docker commit后不会带入。
容器停止时,Init层不存在,重启容器丢失该层修改数据。
第三部分,可读写层
存放修改rootfs后产生的增量,原先的只读层里的内容不会有任何变化。针对删除操作,AUFS会在可读写层创建一个whiteout文件,把只读层里的文件“遮挡”起来,联合挂载后就看不到了。
只有当容器被删除时,这个可读写层才会被删除。
参考资料
《自己动手写docker》
https://time.geekbang.org/column/intro/100015201?tab=catalog