网上关于ID描述的文章很多(例如:https://blog.csdn.net/u010566813/article/details/117789154),大家可自行参考。
执行docker pull nginx 命令,下载nginx镜像,查看下载过程日志:
1)Digest: sha256:0d17b565c37bcbd895e9d92315a05c1c3c9a29f762b011a10c54a66cd53c9b31,是对manifest 文件进行hash计算的结果,manifest内容如下:
{
"schemaVersion": 2,
"mediaType": "application/vnd.docker.distribution.manifest.v2+json",
"config": {
"mediaType": "application/vnd.docker.container.image.v1+json",
"size": 7656,
"digest": "sha256:605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85"
},
"layers": [
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 31357624,
"digest": "sha256:a2abf6c4d29d43a4bf9fbb769f524d0fb36a2edab49819c1bf3e76f409f953ea"
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 25350007,
"digest": "sha256:a9edb18cadd1336142d6567ebee31be2a03c0905eeefe26cb150de7b0fbc520b"
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 602,
"digest": "sha256:589b7251471a3d5fe4daccdddfefa02bdc32ffcba0a6d6a2768bf2c401faf115"
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 894,
"digest": "sha256:186b1aaa4aa6c480e92fbd982ee7c08037ef85114fbed73dbb62503f24c1dd7d"
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 666,
"digest": "sha256:b4df32aa5a72e2a4316aad3414508ccd907d87b4ad177abd7cbd62fa4dab2a2f"
},
{
"mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
"size": 1395,
"digest": "sha256:a0bcbecc962ed2552e817f45127ffb3d14be31642ef3548997f58ae054deb5b2"
}
]
}
2)每个layer的压缩文件digest计算,成为layerID
3)执行docker images命令,IMAGE_ID是构建该镜像的元数据配置的digest。
该镜像的元数据所在位置如下:
查看文件内容如下:
{
"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.5", "NJS_VERSION=0.7.1", "PKG_RELEASE=1~bullseye"],
"Cmd": ["nginx", "-g", "daemon off;"],
"Image": "sha256:82941edee2f4d17c55563bb926387c3ae39fa1a99777f088bc9d3db885192209",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": ["/docker-entrypoint.sh"],
"OnBuild": null,
"Labels": {
"maintainer": "NGINX Docker Maintainers u003cdocker-maint@nginx.comu003e"
},
"StopSignal": "SIGQUIT"
},
"container": "ca3e48389f7160bc9d9a892d316fcbba459344ee3679998739b1c3cd8e56f7da",
"container_config": {
"Hostname": "ca3e48389f71",
"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.5", "NJS_VERSION=0.7.1", "PKG_RELEASE=1~bullseye"],
"Cmd": ["/bin/sh", "-c", "#(nop) ", "CMD ["nginx" "-g" "daemon off;"]"],
"Image": "sha256:82941edee2f4d17c55563bb926387c3ae39fa1a99777f088bc9d3db885192209",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": ["/docker-entrypoint.sh"],
"OnBuild": null,
"Labels": {
"maintainer": "NGINX Docker Maintainers u003cdocker-maint@nginx.comu003e"
},
"StopSignal": "SIGQUIT"
},
"created": "2021-12-29T19:28:29.892199479Z",
"docker_version": "20.10.7",
"history": [{
"created": "2021-12-21T01:22:43.418913408Z",
"created_by": "/bin/sh -c #(nop) ADD file:09675d11695f65c55efdc393ff0cd32f30194cd7d0fbef4631eebfed4414ac97 in / "
}, {
"created": "2021-12-21T01:22:43.799429634Z",
"created_by": "/bin/sh -c #(nop) CMD ["bash"]",
"empty_layer": true
}, {
"created": "2021-12-21T03:00:06.15011478Z",
"created_by": "/bin/sh -c #(nop) LABEL maintainer=NGINX Docker Maintainers u003cdocker-maint@nginx.comu003e",
"empty_layer": true
}, {
"created": "2021-12-29T19:28:08.071260391Z",
"created_by": "/bin/sh -c #(nop) ENV NGINX_VERSION=1.21.5",
"empty_layer": true
}, {
"created": "2021-12-29T19:28:08.248669935Z",
"created_by": "/bin/sh -c #(nop) ENV NJS_VERSION=0.7.1",
"empty_layer": true
}, {
"created": "2021-12-29T19:28:08.472939138Z",
"created_by": "/bin/sh -c #(nop) ENV PKG_RELEASE=1~bullseye",
"empty_layer": true
}, {
"created": "2021-12-29T19:28:27.976946316Z",
"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": "2021-12-29T19:28:28.390440509Z",
"created_by": "/bin/sh -c #(nop) COPY file:65504f71f5855ca017fb64d502ce873a31b2e0decd75297a8fb0a287f97acf92 in / "
}, {
"created": "2021-12-29T19:28:28.640632824Z",
"created_by": "/bin/sh -c #(nop) COPY file:0b866ff3fc1ef5b03c4e6c8c513ae014f691fb05d530257dfffd07035c1b75da in /docker-entrypoint.d "
}, {
"created": "2021-12-29T19:28:28.864872406Z",
"created_by": "/bin/sh -c #(nop) COPY file:0fd5fca330dcd6a7de297435e32af634f29f7132ed0550d342cad9fd20158258 in /docker-entrypoint.d "
}, {
"created": "2021-12-29T19:28:29.113627588Z",
"created_by": "/bin/sh -c #(nop) COPY file:09a214a3e07c919af2fb2d7c749ccbc446b8c10eb217366e5a65640ee9edcc25 in /docker-entrypoint.d "
}, {
"created": "2021-12-29T19:28:29.296888541Z",
"created_by": "/bin/sh -c #(nop) ENTRYPOINT ["/docker-entrypoint.sh"]",
"empty_layer": true
}, {
"created": "2021-12-29T19:28:29.498026198Z",
"created_by": "/bin/sh -c #(nop) EXPOSE 80",
"empty_layer": true
}, {
"created": "2021-12-29T19:28:29.705311925Z",
"created_by": "/bin/sh -c #(nop) STOPSIGNAL SIGQUIT",
"empty_layer": true
}, {
"created": "2021-12-29T19:28:29.892199479Z",
"created_by": "/bin/sh -c #(nop) CMD ["nginx" "-g" "daemon off;"]",
"empty_layer": true
}],
"os": "linux",
"rootfs": {
"type": "layers",
"diff_ids": ["sha256:2edcec3590a4ec7f40cf0743c15d78fb39d8326bc029073b41ef9727da6c851f", "sha256:e379e8aedd4d72bb4c529a4ca07a4e4d230b5a1d3f7a61bc80179e8f02421ad8", "sha256:b8d6e692a25e11b0d32c5c3dd544b71b1085ddc1fddad08e68cbd7fda7f70221", "sha256:f1db227348d0a5e0b99b15a096d930d1a69db7474a1847acbc31f05e4ef8df8c", "sha256:32ce5f6a5106cc637d09a98289782edf47c32cb082dc475dd47cbf19a4f866da", "sha256:d874fd2bc83bb3322b566df739681fbd2248c58d3369cb25908d68e7ed6040a6"]
}
}
4)执行 docker inspect nginx,可以看到 DiffID,每个layer解压后的数据计算sha256 得到的,从上往下表示镜像分层 从底到顶层。
5)通过layerID如何找到DiffID,在下图的路径中保存所有以layerID命名文件,文件里保存DiffID
6)通过DiffID找到layerID,在下图的路径中保存以DiffID命名的文件,文件里保存该layer相关的layerID
7)每一个layer层DiffID与前一层的DiffID联合计算hash,得到chainID,根据chainID查看关联属性信息,路径如下图:
每个chainID存储内容如下,包括DiffID、上一层的DiffID、大小 与 cache-id:
8)通过cache-id可以查看到graphdriver存储的联合文件系统内容,路径在/var/lib/docker/overlay2
注: docker的images目录基本分析差不多,还有两块内容一个是当前image有依赖image,依赖image的ID存储位置;第二个是layerdb下的mount-id,关联到/var/lib/docker/overlay2/:mount-id内容。



