企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
[TOC] # <span style="font-size:15px">**overlay2驱动文件系统的根目录结构**</span> ``` [root@iZbp1bum6107bp8mgzkeunZ docker]# ll /var/lib/docker/image/overlay2/ total 16 drwx------ 4 root root 4096 Apr 4 2022 distribution drwx------ 4 root root 4096 Apr 4 2022 imagedb drwx------ 5 root root 4096 Apr 4 2022 layerdb -rw------- 1 root root 2585 Jun 5 16:35 repositories.json ``` # <span style="font-size:15px">**镜像库元数据:repositories.json**</span> ``` [root@iZbp1bum6107bp8mgzkeunZ overlay2]# cat repositories.json | jq { "Repositories": { "alpine": { "alpine:latest": "sha256:76c8fb57b6fc8599de38027112c47170bd19f99e7945392bd78d6816db01f4ad", "sha256:9c6f0724472873bb50a2ae67a9e7adcb57673a183cea8b06eb778dca859181b5", "alpine@sha256:f22945d45ee2eb4dd463ed5a431d9f04fcd80ca768bb1acf898d91ce51f7bf04": "sha256:76c8fb57b6fc8599de38027112c47170bd19f99e7945392bd78d6816db01f4ad" }, "centos": { "centos:7": "sha256:eeb6ee3f44bd0b5103bb561b4c16bcb82328cfe5809ab675bb17ab3a16c517c9", "centos@sha256:c73f515d06b0fa07bb18d8202035e739a494ce760aa73129f60f4bf2bd22b407": "sha256:eeb6ee3f44bd0b5103bb561b4c16bcb82328cfe5809ab675bb17ab3a16c517c9" }, "elasticsearch": { "elasticsearch:7.17.2": "sha256:ff55ff4ded04f5512613ca71b29b0fdf093b6ba95aa4ed4264a18a8045ad0d59", "elasticsearch@sha256:f51e653b5dfca16afef88d870b697e087e4b562c63c3272d6e8c3c92657110d9": "sha256:ff55ff4ded04f5512613ca71b29b0fdf093b6ba95aa4ed4264a18a8045ad0d59" }, "hello_docker": { "hello_docker:latest": "sha256:9482dcef2f5d13b234ecfdd7ff43b2ebf12e2eef1c9d4fa3dadf8a574cd15d47" } } } ``` &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;repository 是由具有某个功能的 docker 镜像的所有迭代版本构成的镜像库。repository的信息记录在repositories.json文件中。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;repositories.json 文件存储了所有本地镜像的元数据,包括镜像库名字、镜像名字、标签和镜像ID。上面示例中的 alpine、centos、elasticsearch、hello_docker就是镜像库名字。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;docker默认采用SHA256算法根据镜像元数据配置文件计算出镜像ID。上面示例中的`alpine:latest`和`alpine@sha256:f22945d45ee2eb4dd463ed5a431d9f04fcd80ca768bb1acf898d91ce51f7bf04`本质上是一样的,因为他们都指向同一个镜像ID:`76c8fb57b6fc8599de38027112c47170bd19f99e7945392bd78d6816db01f4ad`。在docker images中可以看到对应的image id的缩写`76c8fb57b6fc`。 ``` [root@iZbp1bum6107bp8mgzkeunZ overlay2]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE alpine latest 76c8fb57b6fc 6 months ago 5.57MB elasticsearch 7.17.2 ff55ff4ded04 6 months ago 611MB kibana 7.17.2 19591c8c1eb3 6 months ago 889MB ubuntu latest ff0fea8310f3 7 months ago 72.8MB centos 7 eeb6ee3f44bd 13 months ago 204MB ``` 其中`sha256:f22945d45ee2eb4dd463ed5a431d9f04fcd80ca768bb1acf898d91ce51f7bf04`被称为镜像的摘要,在拉取镜像的时候可以看到。 ![](https://img.kancloud.cn/ed/c1/edc1cdaa71a7384de839ef3702d90d74_663x92.png) # <span style="font-size:15px">**镜像元数据**</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;image元数据包括了镜像架构(如amd64)、操作系统、镜像默认配置、构建该镜像的容器ID和配置、构建该镜像的docker版本、构建镜像的历史信息以及rottfs组成。其中构建镜像的历史信息和 rootfs 组成部分除了具有描述镜像的作用外,还将镜像和构成该镜像的镜像层关联了起来。**Docker 会根据历史信息和 rootfs 中的`diff_ids`计算出构成该镜像的镜像层的存储索引`chainID`,这也是 docker 1.10 镜像存储中基于内容寻址的核心技术。** &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; images元数据被保存在文件 `/var/lib/docker/image//imagedb/content/sha256/ `中。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;以elasticsearch镜像为例:elasticsearch:7.17.2镜像保存在`/var/lib/docker/image/overlay2/imagedb/content/sha256/ff55ff4ded04f5512613ca71b29b0fdf093b6ba95aa4ed4264a18a8045ad0d59`文件中。 ``` [root@iZbp1bum6107bp8mgzkeunZ sha256]# docker images | grep elast elasticsearch 7.17.2 ff55ff4ded04 6 months ago 611MB [root@iZbp1bum6107bp8mgzkeunZ sha256]# pwd /var/lib/docker/image/overlay2/imagedb/content/sha256 [root@iZbp1bum6107bp8mgzkeunZ sha256]# ls ff55ff4ded04f5512613ca71b29b0fdf093b6ba95aa4ed4264a18a8045ad0d59 ff55ff4ded04f5512613ca71b29b0fdf093b6ba95aa4ed4264a18a8045ad0d59 ``` ![](https://img.kancloud.cn/e5/c4/e5c4489cc37f6a5ef39e4f1f33d62844_1052x827.png)![](https://img.kancloud.cn/b7/b2/b7b2103cc94605126426eab4c15fb99a_776x252.png) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;从图片中可以看到,elasticsearch:7.17.镜像元数据中包含了镜像配置和构建配置,其中rootfs中的diff_ids就是镜像层,**在构建镜像容器时,会从上到下依次依赖构建。** # <span style="font-size:15px">**镜像层元数据**</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;在 docker 1.10 版本后,镜像元数据管理巨大的改变之一就是简化了镜像层的元数据,镜像层只包含一个具体的镜像层文件包。用户在 docker 宿主机上下载了某个镜像层之后,docker 会在宿主机上基于镜像层文件包和 image 元数据构建本地的 layer 元数据,包括 diff、parent、size 等。而当 docker 将在宿主机上产生的新的镜像层上传到 registry 时,与新镜像层相关的宿主机上的元数据也不会与镜像层一块打包上传。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;镜像层数据存储在`/var/lib/docker/image/<graph_driver>/layerdb/sha256/<chainID>/`目录下。 ``` // 目录结构如下 [root@iZbp1bum6107bp8mgzkeunZ db8dff71c91610e7c7e947bc060c9ecfe0a43d75fddc95de3f2002984f25ba0b]# tree . ├── cache-id # docker 随机生成的 uuid,内容是保存镜像层的目录索引,即是镜像层的数据文件存放的目录名 ├── diff # diff文件的内容正是diff_ids中的镜像层id ├── parent # parent文件记录的是上层镜像层的id,对于最底层的layer来说,由于没有父layer,所以没有这个文件 ├── size # 记录的是当前镜像层的大小,单位是字节 └── tar-split.json.gz # layer压缩包的是split文件,通过这个文件可以还原layer的tar包。在docker save导出image的时候会用到 ``` ## <span style="font-size:15px">**计算chainID的具体方法**</span> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;从image元数据中,拿到了`diff_ids`之后需要去找到对应的镜像层元数据。 以elasticsearch:7.17.镜像元数据的`diff_ids`为例: ``` [root@iZbp1bum6107bp8mgzkeunZ sha256]# cat ff55ff4ded04f5512613ca71b29b0fdf093b6ba95aa4ed4264a18a8045ad0d59 | jq { "architecture": "amd64", ... "rootfs": { "type": "layers", "diff_ids": [ "sha256:867d0767a47c392f80acb51572851923d6d3e55289828b0cd84a96ba342660c7", "sha256:b5965a019fc65d7950827a769b7a9e49b53fcef2f55ed54595a5f8b409afb00a", "sha256:a64b4c94a654b7617e8fdf0c56702e1347765f8e8f22abfcf0cb1e8edcb961f5", "sha256:339b287ac1a76218be5c6216f4698adb48142bdb0484132afd58256c1af23b5e", "sha256:16bb710c979fc3824ccbd473b7de579dc47bb6f5cffccc2a5753eb5a4c313617", "sha256:0f3c2698b8d05dad9c748902696f9f4e961f26c1388571217e54287214728fa1", "sha256:d9e6d48b0a3b739f2e31470066d65f1e2617541e1c9bfb67c0e3d4d02805e784", "sha256:96115e941eecd52363a4908b3b076abe68b1ced66e9fe7a33635254393e17c39", "sha256:9753a5f19e15c70e1764231cfd4b0dc8289b8f06447b48a11320d37a25d4fa90" ] } } } ``` &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;镜像层的 chainID 计算公式为 `chainID(n)=SHA256(chain(n-1) diffID(n))`,也就是根据父镜像层的 chainID 加上一个空格和当前层的 diffID,再计算 SHA256 的哈希值 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;计算步骤如下: 1. 由于镜像层在构建容器时,是由上到下依次构建,因此第一层的镜像层id是最底层的,sha256之后的随机数值即使chainID值 2. 根据公式,由第一层的值加上空格,拼接第二层的diffID值,使用sha256sum命令计算SHA256哈希值,得出的结果就是第二层的chainID。 3. 第三层的chainID,即使用 “sha256:”拼接第二层的chainID来与第三层的diffID来计算,依次类推。 ``` // edbab184adac1d80d52d20ad99196a61f9406640ccf96e1995285d3a72928517 就是第二层的chainID [root@iZbp1bum6107bp8mgzkeunZ sha256]# echo -n "sha256:867d0767a47c392f80acb51572851923d6d3e55289828b0cd84a96ba342660c7 sha256:b5965a019fc65d7950827a769b7a9e49b53fcef2f55ed54595a5f8b409afb00a" | sha256sum | awk '{print $1}' edbab184adac1d80d52d20ad99196a61f9406640ccf96e1995285d3a72928517 [root@iZbp1bum6107bp8mgzkeunZ sha256]# ls /var/lib/docker/image/overlay2/layerdb/sha256/edbab184adac1d80d52d20ad99196a61f9406640ccf96e1995285d3a72928517 cache-id diff parent size tar-split.json.gz [root@iZbp1bum6107bp8mgzkeunZ sha256]# cat /var/lib/docker/image/overlay2/layerdb/sha256/edbab184adac1d80d52d20ad99196a61f9406640ccf96e1995285d3a72928517/diff && echo sha256:b5965a019fc65d7950827a769b7a9e49b53fcef2f55ed54595a5f8b409afb00a // 第三层diffID (sha256:a64b4c94a654b7617e8fdf0c56702e1347765f8e8f22abfcf0cb1e8edcb961f5)计算方式 [root@iZbp1bum6107bp8mgzkeunZ sha256]# echo -n "sha256:edbab184adac1d80d52d20ad99196a61f9406640ccf96e1995285d3a72928517 sha256:a64b4c94a654b7617e8fdf0c56702e1347765f8e8f22abfcf0cb1e8edcb961f5" | sha256sum | awk '{print $1}' 1cf2d211cdb7a36dc7366f91b596c7d1f68940a529c5705aefa175e87c7b3aef [root@iZbp1bum6107bp8mgzkeunZ sha256]# ls /var/lib/docker/image/overlay2/layerdb/sha256/1cf2d211cdb7a36dc7366f91b596c7d1f68940a529c5705aefa175e87c7b3aef cache-id diff parent size tar-split.json.gz [root@iZbp1bum6107bp8mgzkeunZ sha256]# cat /var/lib/docker/image/overlay2/layerdb/sha256/1cf2d211cdb7a36dc7366f91b596c7d1f68940a529c5705aefa175e87c7b3aef/diff && echo sha256:a64b4c94a654b7617e8fdf0c56702e1347765f8e8f22abfcf0cb1e8edcb961f5 ``` # <span style="font-size:15px">**容器存储**</span> ``` [root@iZbp1bum6107bp8mgzkeunZ overlay2]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b8464578be3d elasticsearch:7.17.2 "/bin/tini -- /usr/l…" 6 months ago Exited (143) 7 hours ago elasticsearch ``` &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;通过 docker ps命令可以查询到容器的ID,由**CONTAINER ID**可以/var/lib/docker/下找到二个目录: ``` // 1、/var/lib/docker/containers/目录 // 很明显容器的hosts,hostname等配置文件是存储在这个目录下的 [root@iZbp1bum6107bp8mgzkeunZ layerdb]# ls /var/lib/docker/containers/*b8464578be3d* b8464578be3dcb1b260e31cf9a934232cf837fb37a6c8aa98c6eeafce8d38459-json.log checkpoints config.v2.json hostconfig.json hostname hosts mounts resolv.conf resolv.conf.hash // 2、/var/lib/docker/image/overlay2/layerdb/mounts/ 目录下 [root@iZbp1bum6107bp8mgzkeunZ mounts]# ls /var/lib/docker/image/overlay2/layerdb/mounts/*b8464578be3d* init-id mount-id parent ``` &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;以下例子可以看出该目录下init-id和mount-id的值是一样的 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;aba555ae0cdb873c0f4bed44f5320ec91e4e04d244acf537bc415489b8befcc2就是container的数据文件,在/var/lib/docker/overlay2中的目录名。 ``` [root@iZbp1bum6107bp8mgzkeunZ b8464578be3dcb1b260e31cf9a934232cf837fb37a6c8aa98c6eeafce8d38459]# pwd /var/lib/docker/image/overlay2/layerdb/mounts/b8464578be3dcb1b260e31cf9a934232cf837fb37a6c8aa98c6eeafce8d38459 [root@iZbp1bum6107bp8mgzkeunZ b8464578be3dcb1b260e31cf9a934232cf837fb37a6c8aa98c6eeafce8d38459]# cat mount-id && echo aba555ae0cdb873c0f4bed44f5320ec91e4e04d244acf537bc415489b8befcc2 [root@iZbp1bum6107bp8mgzkeunZ b8464578be3dcb1b260e31cf9a934232cf837fb37a6c8aa98c6eeafce8d38459]# cat init-id && echo aba555ae0cdb873c0f4bed44f5320ec91e4e04d244acf537bc415489b8befcc2-init [root@iZbp1bum6107bp8mgzkeunZ b8464578be3dcb1b260e31cf9a934232cf837fb37a6c8aa98c6eeafce8d38459]# ls /var/lib/docker/overlay2/aba555ae0cdb873c0f4bed44f5320ec91e4e04d244acf537bc415489b8befcc2 diff link lower work ```