Docker:通过摘要拉取图像,内部使用标记

问题描述 投票:4回答:2

以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是不够的,因为它可能在图像创建时不同。

docker dockerfile digest
2个回答
2
投票

你知道通过摘要拉出的图像有效(!)不可更改是正确的。

图像摘要是从构成图像的层计算的SHA-256哈希。因此,不同的图像将共享相同的摘要是非常不可能的。

创建后,图像的图层不会更改。因此,即使更改了FROM图像,您的现有图像也不会被其更改。

但是,如果您使用新的(相同标记的)FROM图像重建图像,则图像的摘要会发生变化,这将向您发出信号已发生变化的信号。

FROM语句中使用摘要也是可能的(并且是一种好的做法)(由于您引用的原因),但很少有开发人员这样做。您可能希望确保DockerfilesFROM语句中使用摘要,以确保您始终使用相同的图像源。

然而,它是乌龟一直向下(或向上),所以你递归地委托信任到你的源自SCRATCH的图像。

这是推荐使用图像漏洞工具的一个原因。

我最近为自己的教育探索了这个:

https://medium.com/google-cloud/adventures-w-docker-manifests-78f255d662ff


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图像改变,那么得到的摘要将不会是相同的,这意味着在那种情况下你仍然会受到保护。

© www.soinside.com 2019 - 2024. All rights reserved.