以dockerhub上托管的以下存储库为例:
https://hub.docker.com/r/frolvlad/alpine-miniconda3
执行以下命令以通过摘要提取图像:
docker pull frolvlad/alpine-miniconda3:python3.7@sha256:9bc9c096713a6e47ca1b4a0d354ea3f2a1f67669c9a2456352d28481a6ce2fbe
基于docker documentation,通过摘要提取图像具有以下属性:
使用此功能可将图像及时“固定”到特定版本
据我了解,在任何时候用该摘要提取的docker镜像都是不可变的。
尽管它没有评论可变的或内部似乎可变的引用。
最重要的是,first line of the docker file读为
FROM frolvlad/alpine-glibc:alpine-3.9
如果作者更改了dockerfile中的第一行并推送(即使它是同一标签),我将根据我的阅读来假设,即使我指向图像摘要,也不会受到影响。然而,
由于作者引用了dockerfile中的标签而不是摘要,因此我如何确认使用了哪个dockerfile / base映像来构建其映像?似乎仅分析frolvlad/alpine-glibc:alpine-3.9
dockerfile是不够的,因为在创建映像时可能有所不同。
答案 0 :(得分:2)
您正确的说,通过摘要提取的图像实际上是(!)不变的。
图像摘要是从构成图像的层计算得出的SHA-256哈希。因此,不同的图像共享相同的摘要是极不可能的。
创建图像后,图层不会更改。因此,即使FROM
图片已更改,您现有的图片也不会被更改。
但是,如果您使用新的(标记相同的)FROM
图像重建图像,则图像的摘要将发生变化,这将向您发出信号,表明情况已经发生变化。
也可以(并且是一种很好的做法)在FROM
语句中使用摘要(出于您引用的原因),但是很少有开发人员这样做。您可能希望确保Dockerfiles
语句中的FROM
使用摘要,以确保始终使用相同的图像源。
但是,由于它一直都是乌龟,所以您递归地将信任委托给从中一直导出到SCRATCH
的图像。
这是推荐使用图像漏洞工具的原因之一。
我最近为自己的教育探索了这一点:
https://medium.com/google-cloud/adventures-w-docker-manifests-78f255d662ff
答案 1 :(得分:0)
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
图像,则摘要将不会相同,这意味着您仍然在这种情况下受到保护。