本文要谈谈容器和Linux发行版之间的关系,之前网上并没有任何相关的文档,然而我认为这确实是深入了解系统内部知识所必需的。Dockerfile中最简单的一行,例如:From debian:latest,在容器镜像里是如何实现的,或者说,是否可以创建一个可启动的Linux镜像,功能和容器一模一样?那么就需要深入容器root文件系统,看起来好像很简单只需要运行docker export,但是最终实现这个功能还是需要很多额外步骤的。
原理首先,简单讨论一下枯燥的理论。安装完成的Linux系统是什么样的?基本是上一个Linux kernel二进制文件,初始化ramdisk二进制文件和用户态程序和库(一般是GNU核心应用和BootLoader)构成的。
可以运行tree -L 1 / 查看root目录结构:
$ cat /etc/os-release | grep NAME
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
NAME="Debian GNU/Linux"
$ tree -L 1 /
/
├── bin
├── boot
├── data
├── dev
├── etc
├── home
├── initrd.img -> boot/initrd.img-4.9.0-9-amd64 # initial ramdisk
├── lib
├── lib64
├── media
├── mnt
├── opt
├── proc
├── root
├── run
├── sbin
├── srv
├── sys
├── tmp
├── usr
├── var
└── vmlinuz -> boot/vmlinuz-4.9.0-9-amd64 # kernel binary
现在集中看看Docker。Docker遵循OS层面虚拟化标准包装了容器,也就是容器运行重用了宿主机Linux发行版的kernel,而用户态空间却是完全分隔的。
查看一个启动的容器:
$ docker run -it debian:latest bash
root