天天看点

《Docker进阶与实战》——3.3节Docker image的组织结构

本节书摘来自华章社区《docker进阶与实战》一书中的第3章,第3.3节docker image的组织结构,作者华为docker实践小组,更多章节内容可以访问云栖社区“华章社区”公众号查看

3.3 docker image的组织结构

上节讲到docker image是用来启动容器的只读模板,提供容器启动所需要的rootfs,那么docker是怎么组织这些数据的呢?

3.3.1 数据的内容

docker image包含着数据及必要的元数据。数据由一层层的image layer组成,元数据则是一些json文件,用来描述数据(image layer)之间的关系以及容器的一些配置信息。下面使用overlay存储驱动对docker image的组织结构进行分析,首先需要启动docker daemon,命令如下:

这里从官方镜像库下载busybox镜像用作分析。由于前面已经下载过该镜像,所以这里并没有重新下载,而只是做了简单的校验。可以看到docker对镜像进行了完整性校验,这种完整性的凭证是由镜像仓库提供的。相关内容会在后面的章节提到,这里不再展开

介绍。

1.总体信息

从repositories-overlay文件可以看到该存储目录下的所有image以及其对应的layer id。为了减少干扰,实验环境之中只包含一个镜像,其id为8c2e06607696bd4af,如下。

2.数据和元数据

graph目录和overlay目录包含本地镜像库中的所有元数据和数据信息。对于不同的存储驱动,数据的存储位置和存储结构是不同的,本章不做深入的讨论。可以通过下面的命令观察数据和元数据中的具体内容。元数据包含json和layersize两个文件,其中json文件包含了必要的层次和配置信息,layersize文件则包含了该层的大小。

可以看到docker镜像存储路径下已经存储了足够的信息,docker daemon可以通过这些信息还原出docker image:先通过repositories-overlay获得image对应的layer id;再根据layer对应的元数据梳理出image包含的所有层,以及层与层之间的关系;然后使用联合挂载技术还原出容器启动所需要的 rootfs和一些基本的配置信息。

3.3.2 数据的组织

从上节看到,通过repositories-overlay可以找到某个镜像的最上层layer id,进而找到对应的元数据,那么元数据都存了哪些信息呢?可以通过docker inspect得到该层的元数据。为了简单起见,下面的命令输出中删除了一些与讨论无关的层次信息。

意 docker inspect并不是直接输出磁盘中的元数据文件,而是对元数据文件进行了整理,使其更易读,比如标记镜像创建时间的条目由created改成了created;标记容器配置的条目由container_config改成了containerconfig,但是两者的数据是完全一致的。

对于上面的输出,有几项需要重点说明一下:

id:image的id。通过上面的讨论,可以看到image id实际上只是最上层的layer id,所以docker inspect也适用于任意一层layer。

parent:该layer的父层,可以递归地获得某个image的所有layer信息。

comment:非常类似于git的commit message,可以为该层做一些历史记录,方便其他人理解。

container:这个条目比较有意思,其中包含哲学的味道。比如前面提到容器的启动需要以image为模板。但又可以把该容器保存为镜像,所以一般来说image的每个layer都保存自一个容器,所以该容器可以说是image layer的“模板”。

config:包含了该image的一些配置信息,其中比较重要的是:“env”容器启动时会作为容器的环境变量;“cmd”作为容器启动时的默认命令;“labels”参数可以用于docker images命令过滤。

architecture:该image对应的cpu体系结构。现在docker官方支持amd64,对其他体系架构的支持也在进行中。

通过这些元数据信息,可以得到某个image包含的所有layer,进而组合出容器的rootfs,再加上元数据中的配置信息(环境变量、启动参数、体系架构等)作为容器启动时的参数。至此已经具备启动容器必需的所有信息。