1. 什么是镜像
镜像是Docker容器的基石,容器时镜像的运行实例,有了镜像才能启动容器
简单来说,Docker镜像是一个不包含linux内核而又精简的linux操作系统。它就好比是一个只有可读权限的压缩包,我们只能查看不能写。
2. 镜像从哪里来
Docker Hub是由Docker公司负责维护的公共注册中心,包含大量的容器镜像,Docker工具默认从这个公共镜像库下载镜像。公共镜像库,默认是国外的源,即使可能做了CDN,下载速度还是比较慢,可以使用国内的源例如阿里云来加速阿里云镜像加速
3. 镜像的内部结构
3.1 hello-world -----最小的镜像
hello-world是Docker官方提供的一个镜像,可以用来验证Docker是否安装成功。我们从Docker Hub上下载它,如下图所示:
用docker images命令查看镜像信息,如下图所示:
可以看到这个镜像只有13k左右,十分小
3.2 bash镜像
base镜像有两层含义:
不依赖其他镜像
其他镜像可以在这基础上进行扩展
能被称作bash镜像的通常是各种linux发行版的Docker镜像,例如Ubuntu、Debian、centos等
我们以centos镜像为例分析bash镜像
我们在自己的虚拟机上安装centos至少要几个G,而centos的镜像才200多M,这足以说明了镜像的精简。
linux操作系统由内核空间和用户空间组成,如图:
3.2.1 rootfs
内核空间是kernel,linux刚启动时会加载bootfs文件系统,之后bootfs就会被卸载。用户空间的文件系统是rootfs,包含我们熟悉的/dev、/proc、/bin等目录,对于base镜像来说,底层直接用host的kernel,自己只需要提供rootfs就行了。对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以。
3.2.2 base镜像提供的是最小安装
centos镜像的dockerfile文件内容如下:
FROM scratch ADD centos-7-docker.tar.xz / CMD ["/bin/bash"]
第二行ADD指令添加到镜像的tar包就是centos7的rootfs,在制作镜像时,这个tar包会自动解压到根目录下,生成/dev、/proc、/bin等目录
3.2.3 支持运行多种linux OS
不同linux发行版的区别主要就是rootfs,比如Ubuntu 14.04使用的upstart管理服务,apt管理软件包,而centos7使用systemd和yum。这些都是用户空间上的区别,内核空间区别不大。
Docker 可以同时支持多种Linux镜像,模拟出多种操作系统环境,如下图所示:
上图Debian和BusyBox(一种嵌入式Linux)上层提供各自的rootfs,底层共用Docker Host的kernel。
4.镜像的分层结构
dockerfile中的每一个run命令,都会生成一层镜像,新镜像是从base镜像上一层层叠加起来生成的,镜像的分层结构最大的好处就是共享资源。
多个容器共享一个基础镜像,当某个容器修改了基础镜像的内容,例如/etc下的文件,其他容器的/etc不会改变,因为只有当使用镜像运行一个容器实例时,才会在rootfs只读层上挂载一层可读可写层,下面的都是可读层,原来的镜像不会被修改。
5.工作过程
当我们启动一个新的容器时,Docker会只加载只读镜像,在最后添加一个读写层,并将镜像中的目录复制一份到/var/lib/docker/aufs/mnt/容器ID为目录的目录下,我们可以使用chroot进入此目录。如果运行中的容器修改一个已经存在的文件,那么会将该文件从下面的只读层复制到读写层,只读层的这个文件就会覆盖,但还存在,这就实现了文件系统隔离,当删除容器后,读写层的数据就会删除,只读镜像不变。