栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

docker镜像文件分层的原理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

docker镜像文件分层的原理

概念性的东西: 1、layerID:

[root@tlzs diff]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
1fe172e4850f: Pull complete
35c195f487df: Pull complete
213b9b16f495: Pull complete
a8172d9e19b9: Pull complete
f5eee2cb2150: Pull complete
93e404ba8667: Pull complete
Digest: sha256:859ab6768a6f26a79bc42b231664111317d095a4f04e4b6fe79ce37b3d199097
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest

1fe172e4850f、35c195f487df、213b9b16f495、a8172d9e19b9、f5eee2cb2150、93e404ba8667为压缩的layer层的哈希值,这些值为layerID!!!

2、diffID
[root@tlzs diff]# docker inspect nginx:latest
......
......
        "RootFS": {
            "Type": "layers",
            "Layers": [
                "sha256:9c1b6dd6c1e6be9fdd2b1987783824670d3b0dd7ae8ad6f57dc3cea5739ac71e",
                "sha256:4b7fffa0f0a4a72b2f901c584c1d4ffb67cce7f033cc7969ee7713995c4d2610",
                "sha256:f5ab86d69014270bcf4d5ce819b9f5c882b35527924ffdd11fecf0fc0dde81a4",
                "sha256:c876aa251c80272eb01eec011d50650e1b8af494149696b80a606bbeccf03d68",
                "sha256:7046505147d7f3edbf7c50c02e697d5450a2eebe5119b62b7362b10662899d85",
                "sha256:b6812e8d56d65d296e21a639b786e7e793e8b969bd2b109fd172646ce5ebe951"
            ]
        },
        "Metadata": {
            "LastTagTime": "0001-01-01T00:00:00Z"
        }
    }
]

这是镜像的底层的rootfs,但是我们发现这些sha256值和第一步拉取下来的层layerID不一致。这是为什么呢?

因为pull下来的是压缩的数据,layerID是压缩数据的sha256的值(Layer ID指Distribution根据layer compressed data计算的),而inspect rootfs中的值是解压后,对解压的内容进行sha256的值他们是diffID,是在本地由Docker根据layer uncompressed data计算的。

记住这里的rootfs layers的值是diffID。

3、chainID

从diffID组成chainID:

layer.ChainID只用本地,根据layer.DiffID计算,并用于layerdb的目录名称。

chainID唯一标识了一组(像糖葫芦一样的串的底层)diffID的hash值,包含了这一层和它的父层(底层),当然这个糖葫芦可以有一颗山楂,也就是chainID(layer0)==diffID(layer0);对于多颗山楂的糖葫芦,ChainID(layerN) = SHA256hex(ChainID(layerN-1) + " " + DiffID(layerN))

详解:

 首先下载一个nginx的镜像:

1、查找nginx对应的短IMAGE ID的sha256:

[root@tlzs overlay2]# cat /var/lib/docker/image/overlay2/repositories.json | grep fa5269854a5e
{"Repositories":{"java":{"java:8":"sha256:d23bdf5b1b1b1afce5f1d0fd33e7ed8afbc084b594b9ccf742a5b27080d8a4a8","java@sha256:c1ff613e8ba25833d2e1940da0940c3824f03f802c449f3d1815a66b7f8c0e9d":"sha256:d23bdf5b1b1b1afce5f1d0fd33e7ed8afbc084b594b9ccf742a5b27080d8a4a8"},"nginx":{"nginx:latest":"sha256:fa5269854a5e615e51a72b17ad3fd1e01268f278a6684c8ed3c5f0cdce3f230b","nginx@sha256:859ab6768a6f26a79bc42b231664111317d095a4f04e4b6fe79ce37b3d199097":"sha256:fa5269854a5e615e51a72b17ad3fd1e01268f278a6684c8ed3c5f0cdce3f230b"}}}

 2、根据查找出来的nginx的长IMAGE ID进行查询镜像各分层的信息以及其他信息:

cat /var/lib/docker/image/overlay2/imagedb/content/sha256/fa5269854a5e615e51a72b17ad3fd1e01268f278a6684c8ed3c5f0cdce3f230b
[root@tlzs sha256]# cat /var/lib/docker/image/overlay2/imagedb/content/sha256/fa5269854a5e615e51a72b17ad3fd1e01268f278a6684c8ed3c5f0cdce3f230b
{"architecture":"amd64","config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"ExposedPorts":{"80/tcp":{}},"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","NGINX_VERSION=1.21.6","NJS_VERSION=0.7.2","PKG_RELEASE=1~bullseye"],"Cmd":["nginx","-g","daemon off;"],"Image":"sha256:e158bbfdf1201dbc8876232cef4465c5f69c1fd0986f05ee48291a92debc21a0","Volumes":null,"WorkingDir":"","Entrypoint":["/docker-entrypoint.sh"],"OnBuild":null,"Labels":{"maintainer":"NGINX Docker Maintainers u003cdocker-maint@nginx.comu003e"},"StopSignal":"SIGQUIT"},"container":"3c8758320eb6a5293e75ce1ff5afe91584a72b4ee400792f34985a27673ffbc2","container_config":{"Hostname":"3c8758320eb6","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"ExposedPorts":{"80/tcp":{}},"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","NGINX_VERSION=1.21.6","NJS_VERSION=0.7.2","PKG_RELEASE=1~bullseye"],"Cmd":["/bin/sh","-c","#(nop) ","CMD ["nginx" "-g" "daemon off;"]"],"Image":"sha256:e158bbfdf1201dbc8876232cef4465c5f69c1fd0986f05ee48291a92debc21a0","Volumes":null,"WorkingDir":"","Entrypoint":["/docker-entrypoint.sh"],"OnBuild":null,"Labels":{"maintainer":"NGINX Docker Maintainers u003cdocker-maint@nginx.comu003e"},"StopSignal":"SIGQUIT"},"created":"2022-04-20T10:43:12.055940177Z","docker_version":"20.10.12","history":[{"created":"2022-04-20T04:43:27.318712902Z","created_by":"/bin/sh -c #(nop) ADD file:8b1e79f91081eb527b455431af58e823d8b84d9d0c8e5c47cb7bda7507954ae4 in / "},{"created":"2022-04-20T04:43:27.692067537Z","created_by":"/bin/sh -c #(nop)  CMD ["bash"]","empty_layer":true},{"created":"2022-04-20T10:42:53.18912297Z","created_by":"/bin/sh -c #(nop)  LABEL maintainer=NGINX Docker Maintainers u003cdocker-maint@nginx.comu003e","empty_layer":true},{"created":"2022-04-20T10:42:53.284644364Z","created_by":"/bin/sh -c #(nop)  ENV NGINX_VERSION=1.21.6","empty_layer":true},{"created":"2022-04-20T10:42:53.377551587Z","created_by":"/bin/sh -c #(nop)  ENV NJS_VERSION=0.7.2","empty_layer":true},{"created":"2022-04-20T10:42:53.474229449Z","created_by":"/bin/sh -c #(nop)  ENV PKG_RELEASE=1~bullseye","empty_layer":true},{"created":"2022-04-20T10:43:11.169975933Z","created_by":"/bin/sh -c set -x     u0026u0026 addgroup --system --gid 101 nginx     u0026u0026 adduser --system --disabled-login --ingroup nginx --no-create-home --home /nonexistent --gecos "nginx user" --shell /bin/false --uid 101 nginx     u0026u0026 apt-get update     u0026u0026 apt-get install --no-install-recommends --no-install-suggests -y gnupg1 ca-certificates     u0026u0026     NGINX_GPGKEY=573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62;     found='';     for server in         hkp://keyserver.ubuntu.com:80         pgp.mit.edu     ; do         echo "Fetching GPG key $NGINX_GPGKEY from $server";         apt-key adv --keyserver "$server" --keyserver-options timeout=10 --recv-keys "$NGINX_GPGKEY" u0026u0026 found=yes u0026u0026 break;     done;     test -z "$found" u0026u0026 echo u003eu00262 "error: failed to fetch GPG key $NGINX_GPGKEY" u0026u0026 exit 1;     apt-get remove --purge --auto-remove -y gnupg1 u0026u0026 rm -rf /var/lib/apt/lists/*     u0026u0026 dpkgArch="$(dpkg --print-architecture)"     u0026u0026 nginxPackages="         nginx=${NGINX_VERSION}-${PKG_RELEASE}         nginx-module-xslt=${NGINX_VERSION}-${PKG_RELEASE}         nginx-module-geoip=${NGINX_VERSION}-${PKG_RELEASE}         nginx-module-image-filter=${NGINX_VERSION}-${PKG_RELEASE}         nginx-module-njs=${NGINX_VERSION}+${NJS_VERSION}-${PKG_RELEASE}     "     u0026u0026 case "$dpkgArch" in         amd64|arm64)             echo "deb https://nginx.org/packages/mainline/debian/ bullseye nginx" u003eu003e /etc/apt/sources.list.d/nginx.list             u0026u0026 apt-get update             ;;         *)             echo "deb-src https://nginx.org/packages/mainline/debian/ bullseye nginx" u003eu003e /etc/apt/sources.list.d/nginx.list                         u0026u0026 tempDir="$(mktemp -d)"             u0026u0026 chmod 777 "$tempDir"                         u0026u0026 savedAptMark="$(apt-mark showmanual)"                         u0026u0026 apt-get update             u0026u0026 apt-get build-dep -y $nginxPackages             u0026u0026 (                 cd "$tempDir"                 u0026u0026 DEB_BUILD_OPTIONS="nocheck parallel=$(nproc)"                     apt-get source --compile $nginxPackages             )                         u0026u0026 apt-mark showmanual | xargs apt-mark auto u003e /dev/null             u0026u0026 { [ -z "$savedAptMark" ] || apt-mark manual $savedAptMark; }                         u0026u0026 ls -lAFh "$tempDir"             u0026u0026 ( cd "$tempDir" u0026u0026 dpkg-scanpackages . u003e Packages )             u0026u0026 grep '^Package: ' "$tempDir/Packages"             u0026u0026 echo "deb [ trusted=yes ] file://$tempDir ./" u003e /etc/apt/sources.list.d/temp.list             u0026u0026 apt-get -o Acquire::GzipIndexes=false update             ;;     esac         u0026u0026 apt-get install --no-install-recommends --no-install-suggests -y                         $nginxPackages                         gettext-base                         curl     u0026u0026 apt-get remove --purge --auto-remove -y u0026u0026 rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx.list         u0026u0026 if [ -n "$tempDir" ]; then         apt-get purge -y --auto-remove         u0026u0026 rm -rf "$tempDir" /etc/apt/sources.list.d/temp.list;     fi     u0026u0026 ln -sf /dev/stdout /var/log/nginx/access.log     u0026u0026 ln -sf /dev/stderr /var/log/nginx/error.log     u0026u0026 mkdir /docker-entrypoint.d"},{"created":"2022-04-20T10:43:11.389412383Z","created_by":"/bin/sh -c #(nop) COPY file:65504f71f5855ca017fb64d502ce873a31b2e0decd75297a8fb0a287f97acf92 in / "},{"created":"2022-04-20T10:43:11.492647157Z","created_by":"/bin/sh -c #(nop) COPY file:0b866ff3fc1ef5b03c4e6c8c513ae014f691fb05d530257dfffd07035c1b75da in /docker-entrypoint.d "},{"created":"2022-04-20T10:43:11.595228483Z","created_by":"/bin/sh -c #(nop) COPY file:0fd5fca330dcd6a7de297435e32af634f29f7132ed0550d342cad9fd20158258 in /docker-entrypoint.d "},{"created":"2022-04-20T10:43:11.696928206Z","created_by":"/bin/sh -c #(nop) COPY file:09a214a3e07c919af2fb2d7c749ccbc446b8c10eb217366e5a65640ee9edcc25 in /docker-entrypoint.d "},{"created":"2022-04-20T10:43:11.783761903Z","created_by":"/bin/sh -c #(nop)  ENTRYPOINT ["/docker-entrypoint.sh"]","empty_layer":true},{"created":"2022-04-20T10:43:11.877035082Z","created_by":"/bin/sh -c #(nop)  EXPOSE 80","empty_layer":true},{"created":"2022-04-20T10:43:11.966420855Z","created_by":"/bin/sh -c #(nop)  STOPSIGNAL SIGQUIT","empty_layer":true},{"created":"2022-04-20T10:43:12.055940177Z","created_by":"/bin/sh -c #(nop)  CMD ["nginx" "-g" "daemon off;"]","empty_layer":true}],"os":"linux","rootfs":{"type":"layers","diff_ids":["sha256:9c1b6dd6c1e6be9fdd2b1987783824670d3b0dd7ae8ad6f57dc3cea5739ac71e","sha256:4b7fffa0f0a4a72b2f901c584c1d4ffb67cce7f033cc7969ee7713995c4d2610","sha256:f5ab86d69014270bcf4d5ce819b9f5c882b35527924ffdd11fecf0fc0dde81a4","sha256:c876aa251c80272eb01eec011d50650e1b8af494149696b80a606bbeccf03d68","sha256:7046505147d7f3edbf7c50c02e697d5450a2eebe5119b62b7362b10662899d85","sha256:b6812e8d56d65d296e21a639b786e7e793e8b969bd2b109fd172646ce5ebe951"]}}

 从上图可以看出,nginx:latest分层里有几个分层,第一个分层为rootfs分层(该分层位于镜像的最底层),其他的为中间分层。

3、根据rootfs分层进行查看该分层的目录结构信息

(1) 根据rootfs分层的sha256找到该分层的cache-id

[root@tlzs sha256]# ls /var/lib/docker/image/overlay2/layerdb/sha256/9c1b6dd6c1e6be9fdd2b1987783824670d3b0dd7ae8ad6f57dc3cea5739ac71e

 (2)查看cache-id文件里的内容(里面存放的就是目录路径) 

[root@tlzs 9c1b6dd6c1e6be9fdd2b1987783824670d3b0dd7ae8ad6f57dc3cea5739ac71e]# cat cache-id
8d8d934d9a1843b57e3ba7a6228d6683d71d3ba89639e574abfc3a2c1eebb99f

 (3)根据cache-id里的内容查看该层(rootfs分层)的目录结构(即根目录)

cd /var/lib/docker/overlay2/8d8d934d9a1843b57e3ba7a6228d6683d71d3ba89639e574abfc3a2c1eebb99f

 上图中diff文件夹里就是目录结构:

4、查找除了rootfs分层的其他的中间分层的目录结构

备注:由于根据第3步骤的方式查找其他分层信息,就是查找不到。

其原因:

docker引入了内容寻址机制,该机制会根据文件内容来索引镜像和镜像层,docker利用rootfs中的cache-id计算出内容寻址的cache-id,通过cache-id的内容获取layer相关信息,最终索引到镜像层文件内容。

对于最底层镜像层其cache-id的内容即是layerId,因此我们可以查找到它的文件内容信息。除最底层外,layerId需通过ChainID(layerN) = SHA256hex(ChainID(layerN-1) + " " + DiffID(layerN))。

从diffID组成chainID:

layer.ChainID只用本地,根据layer.DiffID计算,并用于layerdb的目录名称。

chainID唯一标识了一组(像糖葫芦一样的串的底层)diffID的hash值,包含了这一层和它的父层(底层),当然这个糖葫芦可以有一颗山楂,也就是chainID(layer0)==diffID(layer0);对于多颗山楂的糖葫芦,ChainID(layerN) = SHA256hex(ChainID(layerN-1) + " " + DiffID(layerN))

(1)计算中间层layerId:

echo -n "sha256:9c1b6dd6c1e6be9fdd2b1987783824670d3b0dd7ae8ad6f57dc3cea5739ac71e sha256:4b7fffa0f0a4a72b2f901c584c1d4ffb67cce7f033cc7969ee7713995c4d2610" | sha256sum | awk '{print $1}'

(2)查看cache-id文件里的内容(里面存放的就是目录路径) 

[root@tlzs docker]# cat /var/lib/docker/image/overlay2/layerdb/sha256/186315e6b3b440e7935f059ccdaea035e03ccdb3133bc87055a299469d51717c/cache-id 
d303be7c7a879cc62477eb35d89d0bebea4805b437d5f246e7df1a5428c7e1f8

(3)根据cache-id里的内容查看该层(rootfs分层)的目录结构(即根目录)

[root@tlzs docker]# cd /var/lib/docker/overlay2/d303be7c7a879cc62477eb35d89d0bebea4805b437d5f246e7df1a5428c7e1f8/

 上图中diff文件夹里就是目录结构:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/830585.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号