以dockerhub上托管的以下存储库为例:https://hub.docker.com/r/frolvlad/alpine-miniconda3 执行以下命令以通过摘要拉取图像:
docker pull frolvlad/alpine-miniconda3:python3.7@sha256:9bc9c096713a6e47ca1b4a0d354ea3f2a1f67669c9a2456352d28481a6ce2fbe
基于docker documentation通过摘要拉图像具有以下属性:
使用此功能可以及时将图像“固定”到特定版本
根据我的理解,在任何时候用该摘要拉出的码头图像是不可变的。 虽然它没有评论内部的可变或看似可变的引用。 最重要的是first line of the docker file读
FROM frolvlad/alpine-glibc:alpine-3.9
如果作者更改了dockerfile中的第一行并推送(即使它是相同的标签),我会假设根据我的读数,我不会受到影响,因为我指向图像摘要。但是,由于作者引用了dockerfile中的标记而不是摘要,我如何确认使用dockerfile / base映像构建其映像?因为它似乎只是分析frolvlad/alpine-glibc:alpine-3.9
dockerfile是不够的,因为它可能在图像创建时不同。
你知道通过摘要拉出的图像有效(!)不可更改是正确的。
图像摘要是从构成图像的层计算的SHA-256哈希。因此,不同的图像将共享相同的摘要是非常不可能的。
创建后,图像的图层不会更改。因此,即使更改了FROM
图像,您的现有图像也不会被其更改。
但是,如果您使用新的(相同标记的)FROM
图像重建图像,则图像的摘要会发生变化,这将向您发出信号已发生变化的信号。
在FROM
语句中使用摘要也是可能的(并且是一种好的做法)(由于您引用的原因),但很少有开发人员这样做。您可能希望确保Dockerfiles
在FROM
语句中使用摘要,以确保您始终使用相同的图像源。
然而,它是乌龟一直向下(或向上),所以你递归地委托信任到你的源自SCRATCH
的图像。
这是推荐使用图像漏洞工具的一个原因。
我最近为自己的教育探索了这个:
https://medium.com/google-cloud/adventures-w-docker-manifests-78f255d662ff
看起来docker image history
可以帮助你识别那种变化。
以下是您使用的标记和摘要上的完整示例:
$ docker image history --no-trunc 34982ce484b5
IMAGE CREATED CREATED BY SIZE COMMENT
sha256:34982ce484b5d709bffb6bf8cca2163ff9231d1a900305f888a5baf59a3414cd 4 weeks ago /bin/sh -c CONDA_VERSION="4.5.12" && CONDA_MD5_CHECKSUM="866ae9dff53ad0874e1d1a60b1ad1ef8" && apk add --no-cache --virtual=.build-dependencies wget ca-certificates bash && mkdir -p "$CONDA_DIR" && wget "http://repo.continuum.io/miniconda/Miniconda3-${CONDA_VERSION}-Linux-x86_64.sh" -O miniconda.sh && echo "$CONDA_MD5_CHECKSUM miniconda.sh" | md5sum -c && bash miniconda.sh -f -b -p "$CONDA_DIR" && echo "export PATH=$CONDA_DIR/bin:\$PATH" > /etc/profile.d/conda.sh && rm miniconda.sh && conda update --all --yes && conda config --set auto_update_conda False && rm -r "$CONDA_DIR/pkgs/" && apk del --purge .build-dependencies && mkdir -p "$CONDA_DIR/locks" && chmod 777 "$CONDA_DIR/locks" 190MB
<missing> 4 weeks ago /bin/sh -c #(nop)ENV PATH=/opt/conda/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 0B
<missing> 4 weeks ago /bin/sh -c #(nop)ENV CONDA_DIR=/opt/conda 0B
<missing> 6 weeks ago /bin/sh -c ALPINE_GLIBC_BASE_URL="https://github.com/sgerrand/alpine-pkg-glibc/releases/download" && ALPINE_GLIBC_PACKAGE_VERSION="2.29-r0" && ALPINE_GLIBC_BASE_PACKAGE_FILENAME="glibc-$ALPINE_GLIBC_PACKAGE_VERSION.apk" && ALPINE_GLIBC_BIN_PACKAGE_FILENAME="glibc-bin-$ALPINE_GLIBC_PACKAGE_VERSION.apk" && ALPINE_GLIBC_I18N_PACKAGE_FILENAME="glibc-i18n-$ALPINE_GLIBC_PACKAGE_VERSION.apk" && apk add --no-cache --virtual=.build-dependencies wget ca-certificates && echo "-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApZ2u1KJKUu/fW4A25y9m y70AGEa/J3Wi5ibNVGNn1gT1r0VfgeWd0pUybS4UmcHdiNzxJPgoWQhV2SSW1JYu tOqKZF5QSN6X937PTUpNBjUvLtTQ1ve1fp39uf/lEXPpFpOPL88LKnDBgbh7wkCp m2KzLVGChf83MS0ShL6G9EQIAUxLm99VpgRjwqTQ/KfzGtpke1wqws4au0Ab4qPY KXvMLSPLUp7cfulWvhmZSegr5AdhNw5KNizPqCJT8ZrGvgHypXyiFvvAH5YRtSsc Zvo9GI2e2MaZyo9/lvb+LbLEJZKEQckqRj4P26gmASrZEPStwc+yqy1ShHLA0j6m 1QIDAQAB -----END PUBLIC KEY-----" | sed 's/ */\n/g' > "/etc/apk/keys/sgerrand.rsa.pub" && wget "$ALPINE_GLIBC_BASE_URL/$ALPINE_GLIBC_PACKAGE_VERSION/$ALPINE_GLIBC_BASE_PACKAGE_FILENAME" "$ALPINE_GLIBC_BASE_URL/$ALPINE_GLIBC_PACKAGE_VERSION/$ALPINE_GLIBC_BIN_PACKAGE_FILENAME" "$ALPINE_GLIBC_BASE_URL/$ALPINE_GLIBC_PACKAGE_VERSION/$ALPINE_GLIBC_I18N_PACKAGE_FILENAME" && apk add --no-cache "$ALPINE_GLIBC_BASE_PACKAGE_FILENAME" "$ALPINE_GLIBC_BIN_PACKAGE_FILENAME" "$ALPINE_GLIBC_I18N_PACKAGE_FILENAME" && rm "/etc/apk/keys/sgerrand.rsa.pub" && /usr/glibc-compat/bin/localedef --force --inputfile POSIX --charmap UTF-8 "$LANG" || true && echo "export LANG=$LANG" >/etc/profile.d/locale.sh && apk del glibc-i18n && rm "/root/.wget-hsts" && apk del .build-dependencies && rm "$ALPINE_GLIBC_BASE_PACKAGE_FILENAME" "$ALPINE_GLIBC_BIN_PACKAGE_FILENAME" "$ALPINE_GLIBC_I18N_PACKAGE_FILENAME" 6.71MB
<missing> 6 weeks ago /bin/sh -c #(nop)ENV LANG=C.UTF-8 0B
<missing> 8 weeks ago /bin/sh -c #(nop)CMD ["/bin/sh"] 0B
<missing> 8 weeks ago /bin/sh -c #(nop) ADD file:2a1fc9351afe35698918545b2d466d9805c2e8afcec52f916785ee65bbafeced in / 5.53MB
在输出的第四行,我可以看到6周前,图像似乎已经被一个以ALPINE_GLIBC_BASE_URL=...
开头的shell命令改变了,这正是RUN
的第一个parent image命令。
确实,在这里你可以看到这个图像已经及时改变了,因为这个。
但是这里对你来说很重要:你也可以看到docker图像由其父图像的RUN
组成,并且不包含对它的任何引用(你也可以运行docker image inspect [image_digest]
,仔细检查)。
这意味着docker将图像的每个部分压缩在一起,并从最初创建图像的命令中获取摘要,而不是因为FROM
没有改变但是底层图像没有改变。
所以我非常怀疑,考虑到这一点并且参考this other answer about digest,如果你FROM
图像改变,那么得到的摘要将不会是相同的,这意味着在那种情况下你仍然会受到保护。