searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

容器本地存储

2024-07-03 09:52:34
0
0

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

 

 

 

 

 

0条评论
0 / 1000
genius
4文章数
0粉丝数
genius
4 文章 | 0 粉丝