MySQL, Oracle, Linux, 软件架构及大数据技术知识分享平台

网站首页 > 精选文章 / 正文

docker镜像存储查看

2024-12-07 12:53 huorong 精选文章 4 ℃ 0 评论

工作中遇到问题 kong:2.8 docker容器启动后,/tmp目录权限应该为 drwxrwxrwt,但是容器启动后权限却变为 -rwx-r-xr-x,无法通过普通用户写 /tmp 导致启动失败,怀疑 kong:2.8 镜像文件被改动,却不知道镜像文件存放目录。经过一番学习,终于知道 docker 镜像文件存放逻辑,记录于此,以兹学习。

此文通过查看 kong:2.8 镜像文件存放路径,学习 docker 镜像是如何存储的。

查看镜像元信息

查看镜像,容易获取它的镜像id,查看镜像 kong:2.8 镜像 id。

?  ~ docker images  kong:2.8
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
kong         2.8       97a4481ac0d6   22 months ago   139MB

docker images 获取到的镜像 id 97a4481ac0d6 是12位,它是完整64位镜像 id 的前12位,根据此 id 到路径/var/lib/docker/image/overlay2/imagedb/content/sha256/ 查找镜像元信息,镜像元信息存储在64位镜像 id 作为文件名的文件中。

?  ~ sudo ls -l /var/lib/docker/image/overlay2/imagedb/content/sha256/
total 16
-rw------- 1 root root 6440 9月  16 09:52 97a4481ac0d615c6a0ae74e00fa1e67ac5efbe29eb4429e696bd6020f6fb919e
-rw------- 1 root root 5374 9月  16 18:01 e86c63a0b2588b1e18c00e652765fbe242025686d529656adb7451375a936ae9

查看镜像 id 97a4481ac0d6 元信息 diff_ids 可知此镜像有4层,diff_ids 数组中各层的排列顺序和它们 mount 时顺序一致即数组中靠前的层最先被 mount 处于覆盖文件系统的底层,数组中靠后的层最后被 mount 处于文件系统的上层。diff_id 值是对应镜像层数据 tar 包的 sha256sum 值,在此不再计算说明。

?  ~ sudo cat /var/lib/docker/image/overlay2/imagedb/content/sha256/97a4481ac0d615c6a0ae74e00fa1e67ac5efbe29eb4429e696bd6020f6fb919e |  jq .
{
。。。省略部分信息 。。。
  "os": "linux",
  "rootfs": {
    "type": "layers",
    "diff_ids": [
      "sha256:e5e13b0c77cbb769548077189c3da2f0a764ceca06af49d8d558e759f5c232bd",
      "sha256:fc7ff2b1ae216a7fd12085b08bd6e7e6498d05db521e1074ce319fb2ad601fab",
      "sha256:db66cd706e1b432ea202fdee890c05265dbbc916bc3b577945f9fa0a3121afe4",
      "sha256:c7ac29fcbbe4eecf112b89c16546429658856df1c92397ecec9fbbdc05471999"
    ]
  }
}

通过镜像 id 获取镜像元信息示意图如下

查看镜像层信息

根据镜像层 diff_id,计算镜像层 chain_id。diff_id 是对应镜像层数据 tar 包的 sha256sum 值,是一个唯一值,为什么还要有 chain_id ? 从下面的计算逻辑可知,chain_id 也是唯一的,并包含层级信息,chain_id 的作用是要避免镜像层数据 tar 包内容不同但是 diff_id 值相同的情况?或许是吧,只是个人猜测。

  • 若镜像层是最底层,chain_id = diff_id
  • 若镜像层不是最底层,chain_id = sha256sum(父镜像层chain_id + " " + 镜像层diff_id)

计算得到chain_id,可以查看镜像层信息目录 /var/lib/docker/image/overlay2/layerdb/sha256/{chain_id},下面计算 kong:2.8 各个镜像层对应的 chain_id(注意图中为了方便展示,只保留了 diff_id 和 chain_id 的前12位)。

diff_id 为 e5e13b0c77cbb769548077189c3da2f0a764ceca06af49d8d558e759f5c232bd 的镜像层是最底层,所以对应 chain_id 为 e5e13b0c77cbb769548077189c3da2f0a764ceca06af49d8d558e759f5c232bd 。

diff_id 为 fc7ff2b1ae216a7fd12085b08bd6e7e6498d05db521e1074ce319fb2ad601fab 的镜像层对应 chain_id 计算如下

?  ~ echo -n "sha256:e5e13b0c77cbb769548077189c3da2f0a764ceca06af49d8d558e759f5c232bd sha256:fc7ff2b1ae216a7fd12085b08bd6e7e6498d05db521e1074ce319fb2ad601fab" | sha256sum
c7e6f695e04b75463959c2a91d22d6cd816712c3f54840d44b603ef9c4b78878  -

diff_id 为 db66cd706e1b432ea202fdee890c05265dbbc916bc3b577945f9fa0a3121afe4 的镜像层对应 chain_id 计算如下

?  ~ echo -n "sha256:c7e6f695e04b75463959c2a91d22d6cd816712c3f54840d44b603ef9c4b78878 sha256:db66cd706e1b432ea202fdee890c05265dbbc916bc3b577945f9fa0a3121afe4" | sha256sum
08c81880d450f594d0debf691e3f310a115ce97e1ac2b047c2c7ca9827a0ddd4  -

diff_id 为 c7ac29fcbbe4eecf112b89c16546429658856df1c92397ecec9fbbdc05471999 的镜像层对应 chain_id 计算如下

?  ~ echo -n "sha256:08c81880d450f594d0debf691e3f310a115ce97e1ac2b047c2c7ca9827a0ddd4 sha256:c7ac29fcbbe4eecf112b89c16546429658856df1c92397ecec9fbbdc05471999" | sha256sum
ec1ac5d8298d4b154a6842d0b96a426ef7930f0d51e1945c55ee866ab481c0d8  -

查看 chain_id ec1ac5d8298d4b154a6842d0b96a426ef7930f0d51e1945c55ee866ab481c0d8 对应镜像层目录内容,其中 parent 文件内容为父镜像层对应的 chain_id

?  ~ sudo ls /var/lib/docker/image/overlay2/layerdb/sha256/ec1ac5d8298d4b154a6842d0b96a426ef7930f0d51e1945c55ee866ab481c0d8
cache-id  diff  parent  size  tar-split.json.gz
?  ~ sudo cat /var/lib/docker/image/overlay2/layerdb/sha256/ec1ac5d8298d4b154a6842d0b96a426ef7930f0d51e1945c55ee866ab481c0d8/parent
sha256:08c81880d450f594d0debf691e3f310a115ce97e1ac2b047c2c7ca9827a0ddd4

通过镜像层 diff_id 获取镜像层 chain_id 示意图如下

查看镜像层文件

计算得到 chain_id,镜像层文件位置记录于 /var/lib/docker/image/overlay2/layerdb/sha256/{chain_id}/cache-id,譬如查看 chain_id ec1ac5d8298d4b154a6842d0b96a426ef7930f0d51e1945c55ee866ab481c0d8 对应的 cache-id,通过此 cache-id 查看镜像层文件。

?  ~ sudo cat /var/lib/docker/image/overlay2/layerdb/sha256/ec1ac5d8298d4b154a6842d0b96a426ef7930f0d51e1945c55ee866ab481c0d8/cache-id
23619984faf040169dec940c29798319ad0479e974fc7d0d0df2523c565a75f7
?  ~ sudo ls -l /var/lib/docker/overlay2/23619984faf040169dec940c29798319ad0479e974fc7d0d0df2523c565a75f7/    
total 16
drwxr-xr-x 2 root root 4096 9月  16 09:52 diff
-rw-r--r-- 1 root root   26 9月  16 09:52 link
-rw-r--r-- 1 root root   86 9月  16 09:52 lower
drwx------ 2 root root 4096 9月  16 09:52 work

cache-id 是创建或拉取镜像时随机生成的,可以把 kong:2.8 删除再拉取验证下,chain_id ec1ac5d8298d4b154a6842d0b96a426ef7930f0d51e1945c55ee866ab481c0d8 对应的 cache-id 此时为 779f7fc23306bb64e612581cde7ec3ded3515cee2bae7a6d867b79f8a6cfce67

?  ~ docker image remove kong:2.8 
Untagged: kong:2.8
Deleted: sha256:97a4481ac0d615c6a0ae74e00fa1e67ac5efbe29eb4429e696bd6020f6fb919e
Deleted: sha256:ec1ac5d8298d4b154a6842d0b96a426ef7930f0d51e1945c55ee866ab481c0d8
Deleted: sha256:08c81880d450f594d0debf691e3f310a115ce97e1ac2b047c2c7ca9827a0ddd4
Deleted: sha256:c7e6f695e04b75463959c2a91d22d6cd816712c3f54840d44b603ef9c4b78878
Deleted: sha256:e5e13b0c77cbb769548077189c3da2f0a764ceca06af49d8d558e759f5c232bd
?  ~ docker pull kong:2.8           
2.8: Pulling from op/kong
ca7dd9ec2225: Pull complete 
cb280baa9a48: Pull complete 
1a483e5d8293: Pull complete 
0809b8d42267: Pull complete 
Digest: sha256:a8eb48a7e0b6a6231f4f44f8e0ec795dd322b44c7004dc00922862dad7d68199
Status: Downloaded newer image for kong:2.8
kong:2.8
?  ~ sudo cat /var/lib/docker/image/overlay2/layerdb/sha256/ec1ac5d8298d4b154a6842d0b96a426ef7930f0d51e1945c55ee866ab481c0d8/cache-id
779f7fc23306bb64e612581cde7ec3ded3515cee2bae7a6d867b79f8a6cfce67
?  ~ sudo ls -l /var/lib/docker/overlay2/779f7fc23306bb64e612581cde7ec3ded3515cee2bae7a6d867b79f8a6cfce67                                                               
total 16
drwxr-xr-x 2 root root 4096 9月  17 17:16 diff
-rw-r--r-- 1 root root   26 9月  17 17:16 link
-rw-r--r-- 1 root root   86 9月  17 17:16 lower
drwx------ 2 root root 4096 9月  17 17:16 work

通过 cach-id 查看镜像层文件示意图如下

快速获取镜像层文件位置

docker inspect <镜像名称> 返回信息中有镜像层 diff_id 和 cache-id 信息,可以快速查看镜像层文件位置。下面示例通过 docker inspect 查看 kong:2.8 镜像层信息,注意因为 kong:2.8 在上面示例中删除并重新拉取过,所以 cache-id 有变化。

Layers 数据结构中存储的是镜像层 diff_id, GraphDriver.Data 数据结构中存储的是镜像层文件位置,镜像层文件位置路径包含 cache-id。

?  ~ docker inspect kong:2.8
。。。省略部分信息 。。。
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/f778208403bff5802be961d87854cb9dc3dcd6dc82efed42823546ac3ec8bd5a/diff:/var/lib/docker/overlay2/7173fdebbc099050511ac7
cda5d69360435fd292f7ce3d21b358366488cf2417/diff:/var/lib/docker/overlay2/05bf9070f77576f5396b4236c1f765379e9ec7dd26492fa59465162f3f2ea5ac/diff",
                "MergedDir": "/var/lib/docker/overlay2/779f7fc23306bb64e612581cde7ec3ded3515cee2bae7a6d867b79f8a6cfce67/merged",
                "UpperDir": "/var/lib/docker/overlay2/779f7fc23306bb64e612581cde7ec3ded3515cee2bae7a6d867b79f8a6cfce67/diff",
                "WorkDir": "/var/lib/docker/overlay2/779f7fc23306bb64e612581cde7ec3ded3515cee2bae7a6d867b79f8a6cfce67/work"
            },
            "Name": "overlay2"
        },
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:e5e13b0c77cbb769548077189c3da2f0a764ceca06af49d8d558e759f5c232bd",
                "sha256:fc7ff2b1ae216a7fd12085b08bd6e7e6498d05db521e1074ce319fb2ad601fab",
                "sha256:db66cd706e1b432ea202fdee890c05265dbbc916bc3b577945f9fa0a3121afe4",
                "sha256:c7ac29fcbbe4eecf112b89c16546429658856df1c92397ecec9fbbdc05471999"
            ]
        },
        "Metadata": {
            "LastTagTime": "2024-09-17T17:25:51.543963735+08:00"
        }
    }
]

通过 docker inspect 获取镜像层文件示意图如下


回到文章开头问题,查看到 kong:2.8 镜像层文件 /tmp 目录权限确实被人为修改为-rwx-r-xr-x,这下真相大白,只需恢复 /tmp 目录权限 kong:2.8 容器就可以正常启动。

本文参考: http://walkerdu.com/2022/12/15/docker_storage/

Tags:docker查看镜像详细信息

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言