Docker镜像缓存与拉取疑问:提示信息矛盾原因求解
问题背景
使用以下Dockerfile构建镜像:
FROM alpine:latest RUN apk add --update redis CMD ["redis-server"]
执行docker run -i -t alpine sh时得到提示:
Unable to find image 'alpine:latest' locally latest: Pulling from library/alpine 8c6d1654570f: Already exists Digest: sha256:82d1e9d7ed48a7523bdebc18cf6290bdb97b82302a8a9c27d4fe885949ea94d1 Status: Downloaded newer image for alpine:latest
针对你提出的三个疑问,解答如下:
为何之前构建镜像时已拉取alpine作为基础镜像,现在却提示本地找不到'alpine:latest'镜像?
Docker构建镜像时,会将基础镜像的层缓存到本地,但这些层不一定会被打上alpine:latest的标签。你构建自己的镜像时,Docker只是复用了基础镜像的底层数据,但如果本地没有显式存在alpine:latest这个标签对应的镜像(比如之前拉取后标签被删除,或者构建过程中仅缓存层未保留标签),docker run命令查找的是带有指定标签的镜像,因此会提示本地找不到。既然提示本地找不到要拉取,为何显示"Already exists"?
这里的Already exists指的是镜像的底层数据层(8c6d1654570f)已经存在于本地Docker缓存中。拉取镜像的过程本质是下载组成镜像的各个层,由于该层已经存在,不需要重新下载,Docker只需要将alpine:latest标签关联到这些已有的层对应的镜像上即可。摘要和镜像ID与之前构建的一致,说明复用了缓存,为何提示"Downloaded newer image for alpine:latest"?
这个提示里的"newer"并不是指镜像内容有更新,而是指本地现在新增了alpine:latest这个标签指向的镜像。之前本地没有这个标签关联到对应镜像,现在通过拉取操作完成了标签的绑定,Docker就用这个提示表示成功获取到了带有该标签的镜像,实际镜像内容和之前构建时使用的缓存层完全一致。
内容的提问来源于stack exchange,提问作者sahurahul

