1. 镜像构建
镜像的构建需要根据oci定义的规范来进行构建,OCI镜像规范(image-spec)指定了镜像需要按照什么标准来构建,Dockerfile则决定了镜像的layer(镜像层)的内容和相关一些元数据 简而言之:
image-spec+DockerFile ====> image
1.1 镜像构建的过程
构建镜像docker build的流程:
-
在Docker Cli 执行镜像构建命令并且使用-f参数来指定Dockerfile文件,-t 指定构建出的镜像标签信息;
-
Docker Cli 会将构建命令后面指定的路径(.)上下文环境所有文件打包成一个 tar 包,并发送给 Docker 服务端;
-
Docker Deamon 收到客户端发送的 tar 包并解压,根据 Dockerfile 里面的指令进行镜像的分层构建;
-
Docker 下载 FROM 语句中指定的基础镜像,然后将基础镜像的 layer 联合挂载为一层并在上面创建一个空目录;
-
此时会启动一个临时的容器并在 chroot 中启动一个 bash, 运行 RUN 语句中的命令:RUN : chroot . bin/bash -c "apt get update ... ..."
-
在RUN命令执行完毕后,会将当前层目录进行压缩从而形成新镜像中的新的一层, 同时为下一层提供基础镜像;
-
如果 Dockerfile 中包含其它命令,就以之前构建的层次为基础,从第二步开始重复创建新层,直到完成所有语句后退出;
-
在 Dockerfile 中包含的所有指令命令执行完毕后镜像构建完成,并为该镜像打上Tag
2. 镜像存储
2.1 本地存储
当Docker 在构建完镜像后会将其存储在Docker 本地存储家目录中,默认情况即/var/lib/docker/
一个image 包含 Manifest 、images Index 、 Layer Filesystem、Image Configuration
对于镜像存储路径最重要的默认路径下的image 和 overlay2 这个两个目录,容器的元数据存放在 image 目录下,容器的 layer 数据则存放在 overlay2 目录下。
/var/lib/docker/image/overlay2/repositories.json
当我们 docker run 一个容器的时候也用到这个文件去索引本地是否存在该镜像,没有镜像的话就自动去 pull 这个镜像。
/var/lib/docker/image/overlay2/imagedb/content/sha256
存放目录名为镜像id内容是image config
2.2 容器在磁盘的存储
容器的文件系统分为三层: - r/o层:也就是镜像层 - init层:启动容器时的参数 - r/w层:可读写层
前面我们知道镜像存储在/var/lib/docker/overlay2下面,这里不仅包含了只读(r/o)层,init层和r/w层都在这个里面。
运行一个容器会返回一个容器id. 通过这个id,我们能在/var/lib/docker/image/overlay2/layerdb/mounts目录下找到该容器的信息:
2.3 查找本地镜像的过程
1. 查找/var/lib/docker/image/overlay2/repositories.json文件,找到对应版本的imageId
2. 根据imageId在/var/lib/docker/image/overlay2/imagedb/content/sha256文件,文件名为imageId,内容是对应镜像配置(image.config)
3. 根据Image.config内的diff_id 到image/overlay2/layerdb/sha256 查找,根据chainID和diff_id的计算公式
chaninid(1) = diffid(1) chainid(n) = sha256(chain(n-1) diffid(n) )
4. 上述计算可以获取各个不同镜像层在 /var/lib/docker/overlay2 目录下各个镜像层的uuid目录
5. 上述uuid目录下的diff 就是各个镜像层的文件系统
3 镜像id梳理
imageID是对Image Configuration文件的sha256哈希后的得到
manifest_digestId是对docker pull拉取镜像的manifest文件的sha256哈希得到的字符串
layer_diffId是对layer文件(.tar)sha256哈希得到的id
manifest_layer_digest是对压缩后的layer文件(.tar.gz) sha256哈希的到id
chainId 计算diff_id获取,公式:chaninid(1) = diffid(1) chainid(n) = sha256(chain(n-1) diffid(n) )
cache_id 宿主机随机生成的uuid