背景说明

解决方案

镜像导出

  1. [root@vm1 work]# docker save nginx -o nginx.tar
  2. [root@vm1 work]# ls
  3. nginx.tar

文件解压

  1. [root@vm1 work]# tar -xvf nginx.tar
  2. [root@vm1 work]#
  3. [root@vm1 work]# tree .
  4. .
  5. ├── 0cb59b23812a64ae9115a5cf081f05d3d1915c5d7d2304c64b1c3a07629122a9
  6. ├── json
  7. ├── layer.tar
  8. └── VERSION
  9. ├── 0e9f59de25dca39e1cc33d1b7a83f27668c800221d7f1062a5da0df9ba684f44
  10. ├── json
  11. ├── layer.tar
  12. └── VERSION
  13. ├── 5df3f744c961b85bb93947d6a4288543c06e64b3130562ae7be85fdc9f7a5691
  14. ├── json
  15. ├── layer.tar
  16. └── VERSION
  17. ├── 605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85.json
  18. ├── 728205feeb04d15cbf0b889a9336e553bf6d472a311724e567a156afe3cb105d
  19. ├── json
  20. ├── layer.tar
  21. └── VERSION
  22. ├── 7e8578b7bc47a5f07742264aace8ee761078c30c1c2c2dafbc79a8ebd340c191
  23. ├── json
  24. ├── layer.tar
  25. └── VERSION
  26. ├── 8c46511b06be8a5ed3d1478039cd8e3bcb0842b8a68c42babb5e9c4b6dc6beeb
  27. ├── json
  28. ├── layer.tar
  29. └── VERSION
  30. ├── manifest.json
  31. ├── nginx.tar
  32. └── repositories
  33. 6 directories, 22 files
  34. [root@vm1 work]#

层级说明

0cb59b23812a64ae9115a5cf081f05d3d1915c5d7d2304c64b1c3a07629122a9
0e9f59de25dca39e1cc33d1b7a83f27668c800221d7f1062a5da0df9ba684f44
5df3f744c961b85bb93947d6a4288543c06e64b3130562ae7be85fdc9f7a5691
728205feeb04d15cbf0b889a9336e553bf6d472a311724e567a156afe3cb105d
7e8578b7bc47a5f07742264aace8ee761078c30c1c2c2dafbc79a8ebd340c191
8c46511b06be8a5ed3d1478039cd8e3bcb0842b8a68c42babb5e9c4b6dc6beeb
如上一个目录表示一个镜像的层级,文件夹内的内容表示当前层相对上一层的变化,比如文件改动,环境变量改动,端口改动,启动命令等。

文件说明

605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85.json表示镜像构建过程的元数据。

  1. [root@vm1 work]# cat 605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85.json
  2. {"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.com\u003e"},"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.com\u003e"},"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.com\u003e","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 \u0026\u0026 addgroup --system --gid 101 nginx \u0026\u0026 adduser --system --disabled-login --ingroup nginx --no-create-home --home /nonexistent --gecos \"nginx user\" --shell /bin/false --uid 101 nginx \u0026\u0026 apt-get update \u0026\u0026 apt-get install --no-install-recommends --no-install-suggests -y gnupg1 ca-certificates \u0026\u0026 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\" \u0026\u0026 found=yes \u0026\u0026 break; done; test -z \"$found\" \u0026\u0026 echo \u003e\u00262 \"error: failed to fetch GPG key $NGINX_GPGKEY\" \u0026\u0026 exit 1; apt-get remove --purge --auto-remove -y gnupg1 \u0026\u0026 rm -rf /var/lib/apt/lists/* \u0026\u0026 dpkgArch=\"$(dpkg --print-architecture)\" \u0026\u0026 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} \" \u0026\u0026 case \"$dpkgArch\" in amd64|arm64) echo \"deb https://nginx.org/packages/mainline/debian/ bullseye nginx\" \u003e\u003e /etc/apt/sources.list.d/nginx.list \u0026\u0026 apt-get update ;; *) echo \"deb-src https://nginx.org/packages/mainline/debian/ bullseye nginx\" \u003e\u003e /etc/apt/sources.list.d/nginx.list \u0026\u0026 tempDir=\"$(mktemp -d)\" \u0026\u0026 chmod 777 \"$tempDir\" \u0026\u0026 savedAptMark=\"$(apt-mark showmanual)\" \u0026\u0026 apt-get update \u0026\u0026 apt-get build-dep -y $nginxPackages \u0026\u0026 ( cd \"$tempDir\" \u0026\u0026 DEB_BUILD_OPTIONS=\"nocheck parallel=$(nproc)\" apt-get source --compile $nginxPackages ) \u0026\u0026 apt-mark showmanual | xargs apt-mark auto \u003e /dev/null \u0026\u0026 { [ -z \"$savedAptMark\" ] || apt-mark manual $savedAptMark; } \u0026\u0026 ls -lAFh \"$tempDir\" \u0026\u0026 ( cd \"$tempDir\" \u0026\u0026 dpkg-scanpackages . \u003e Packages ) \u0026\u0026 grep '^Package: ' \"$tempDir/Packages\" \u0026\u0026 echo \"deb [ trusted=yes ] file://$tempDir ./\" \u003e /etc/apt/sources.list.d/temp.list \u0026\u0026 apt-get -o Acquire::GzipIndexes=false update ;; esac \u0026\u0026 apt-get install --no-install-recommends --no-install-suggests -y $nginxPackages gettext-base curl \u0026\u0026 apt-get remove --purge --auto-remove -y \u0026\u0026 rm -rf /var/lib/apt/lists/* /etc/apt/sources.list.d/nginx.list \u0026\u0026 if [ -n \"$tempDir\" ]; then apt-get purge -y --auto-remove \u0026\u0026 rm -rf \"$tempDir\" /etc/apt/sources.list.d/temp.list; fi \u0026\u0026 ln -sf /dev/stdout /var/log/nginx/access.log \u0026\u0026 ln -sf /dev/stderr /var/log/nginx/error.log \u0026\u0026 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"]}}
  3. [root@vm1 work]#

repositories和manifest.json表示当前镜像的元数据

  1. [root@vm1 work]# cat repositories
  2. {"nginx":{"latest":"8c46511b06be8a5ed3d1478039cd8e3bcb0842b8a68c42babb5e9c4b6dc6beeb"}}
  3. [root@vm1 work]# cat manifest.json
  4. [{"Config":"605c77e624ddb75e6110f997c58876baa13f8754486b461117934b24a9dc3a85.json","RepoTags":["nginx:latest"],"Layers":["5df3f744c961b85bb93947d6a4288543c06e64b3130562ae7be85fdc9f7a5691/layer.tar","0cb59b23812a64ae9115a5cf081f05d3d1915c5d7d2304c64b1c3a07629122a9/layer.tar","728205feeb04d15cbf0b889a9336e553bf6d472a311724e567a156afe3cb105d/layer.tar","0e9f59de25dca39e1cc33d1b7a83f27668c800221d7f1062a5da0df9ba684f44/layer.tar","7e8578b7bc47a5f07742264aace8ee761078c30c1c2c2dafbc79a8ebd340c191/layer.tar","8c46511b06be8a5ed3d1478039cd8e3bcb0842b8a68c42babb5e9c4b6dc6beeb/layer.tar"]}]
  5. [root@vm1 work]#

json文件表示每一层的配置元数据

  1. [root@vm1 work]# cd 0cb59b23812a64ae9115a5cf081f05d3d1915c5d7d2304c64b1c3a07629122a9/
  2. [root@vm1 0cb59b23812a64ae9115a5cf081f05d3d1915c5d7d2304c64b1c3a07629122a9]# ls
  3. json layer.tar VERSION
  4. [root@vm1 0cb59b23812a64ae9115a5cf081f05d3d1915c5d7d2304c64b1c3a07629122a9]# cat json
  5. {"id":"0cb59b23812a64ae9115a5cf081f05d3d1915c5d7d2304c64b1c3a07629122a9","parent":"5df3f744c961b85bb93947d6a4288543c06e64b3130562ae7be85fdc9f7a5691","created":"1970-01-01T08:00:00+08:00","container_config":{"Hostname":"","Domainname":"","User":"","AttachStdin":false,"AttachStdout":false,"AttachStderr":false,"Tty":false,"OpenStdin":false,"StdinOnce":false,"Env":null,"Cmd":null,"Image":"","Volumes":null,"WorkingDir":"","Entrypoint":null,"OnBuild":null,"Labels":null},"os":"linux"}
  6. [root@vm1 0cb59b23812a64ae9115a5cf081f05d3d1915c5d7d2304c64b1c3a07629122a9]#

再次解压layer.tar即可看到镜像中的文件

  1. [root@vm1 work]# cd 0cb59b23812a64ae9115a5cf081f05d3d1915c5d7d2304c64b1c3a07629122a9/
  2. [root@vm1 work]# tar -xvf layer.tar
  3. [root@vm1 0cb59b23812a64ae9115a5cf081f05d3d1915c5d7d2304c64b1c3a07629122a9]# ls
  4. docker-entrypoint.d etc json layer.tar lib tmp usr var VERSION
  5. [root@vm1 0cb59b23812a64ae9115a5cf081f05d3d1915c5d7d2304c64b1c3a07629122a9]# cd usr/share/nginx/html/
  6. [root@vm1 html]# ls
  7. 50x.html index.html
  8. [root@vm1 html]#

VERSION表示当前镜像使用的版本规范

  1. [root@vm1 0cb59b23812a64ae9115a5cf081f05d3d1915c5d7d2304c64b1c3a07629122a9]# ls
  2. docker-entrypoint.d etc json layer.tar lib tmp usr var VERSION
  3. [root@vm1 0cb59b23812a64ae9115a5cf081f05d3d1915c5d7d2304c64b1c3a07629122a9]# cat VERSION
  4. 1.0
  5. [root@vm1 0cb59b23812a64ae9115a5cf081f05d3d1915c5d7d2304c64b1c3a07629122a9]#