今天,我们来聊下Docker/Podman 镜像该如何打标。究竟是用Tag好还是用Digest优秀
先说结论:能用Digest就不要用Tag!!!
先来看下面的一个例子,几天前从Quay 拉取到本地的一个镜像,它的tag是`latest`(你也可以类比为v1, v2, v3...等等),digest 是 `sha256:3d6450xxx`
# docker images quay.io/operator-framework/upstream-opm-builder --digests
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
quay.io/operator-framework/upstream-opm-builder latest sha256:3d64506612ee9991d9fb719f78cdd36ff9b330d6cb4eaff7e0c7ef9ec80f3010 f8275c28458d 4 days ago 56.8 MB
我们现在再重新拉取下`latest`这个image. 看到没?它的digest 变了!!!变成了`sha256:66d77b1b`,这也意味着这个镜像被更新了,它的内容变了
# docker pull quay.io/operator-framework/upstream-opm-builder
Using default tag: latest
Trying to pull repository quay.io/operator-framework/upstream-opm-builder ...
latest: Pulling from quay.io/operator-framework/upstream-opm-builder
f0045e846072: Pull complete
22a917d9a8ff: Pull complete
Digest: sha256:66d77b1b0af5bb2299916d0fed935bfd70720ce9d89406c10ccc08f2de910334
Status: Downloaded newer image for quay.io/operator-framework/upstream-opm-builder:latest
这个`latest` tag也指向了最新的镜像。似乎没有什么问题。但那些在不同主机,不同节点已经存在的这个镜像,如果不重新拉取的话,岂不是不一样了?!
# docker images quay.io/operator-framework/upstream-opm-builder --digests
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
quay.io/operator-framework/upstream-opm-builder latest sha256:66d77b1b0af5bb2299916d0fed935bfd70720ce9d89406c10ccc08f2de910334 6ff688cecdcc 3 days ago 56.8 MB
quay.io/operator-framework/upstream-opm-builder <none> sha256:3d64506612ee9991d9fb719f78cdd36ff9b330d6cb4eaff7e0c7ef9ec80f3010 f8275c28458d 4 days ago 56.8 MB
这个问题很严重。虽然看起来我们都是在用`latest`这个镜像,但其实我们用的不一样!!! 经常听到有人问,诶,咱们用的都是同样的镜像啊,都是xxx版本啊,为啥这个bug还在?
尤其是在Kubernetes/OpenShift这种云平台中,如果你的Pod中Image的拉取策略选择的是`IfNotPresent`, 那么恭喜你,中奖了!如果你用`digest`,就没有这个烦恼哦
我们再来看下digest, 从Docker 1.10 起,Docker镜像包含两部分: 1,文件内容的有序Layer层 2,构建容器时的参数构成
Digest 是压缩文件打包时(tar)根据相应算法随机生成的ID, 在同一个Registry中的不同Repo下,是不变的:
# docker inspect quay.io/jiazha/upstream-opm-builder:v1 --format={{.RepoDigests}}
[quay.io/jiazha/upstream-opm-builder@sha256:66d77b1b0af5bb2299916d0fed935bfd70720ce9d89406c10ccc08f2de910334 quay.io/operator-framework/upstream-opm-builder@sha256:66d77b1b0af5bb2299916d0fed935bfd70720ce9d89406c10ccc08f2de910334]
# docker tag quay.io/operator-framework/upstream-opm-builder quay.io/jiazha/upstream-opm-builder:v1
# docker images quay.io/jiazha/upstream-opm-builder:v1 --digests
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
quay.io/jiazha/upstream-opm-builder v1 <none> 6ff688cecdcc 3 days ago 56.8 MB
# docker push quay.io/jiazha/upstream-opm-builder:v1
The push refers to a repository [quay.io/jiazha/upstream-opm-builder]
537da2905474: Pushed
b1db8a3aea84: Pushed
v1: digest: sha256:66d77b1b0af5bb2299916d0fed935bfd70720ce9d89406c10ccc08f2de910334 size: 740
# docker rmi quay.io/jiazha/upstream-opm-builder:v1
Untagged: quay.io/jiazha/upstream-opm-builder:v1
Untagged: quay.io/jiazha/upstream-opm-builder@sha256:66d77b1b0af5bb2299916d0fed935bfd70720ce9d89406c10ccc08f2de910334
# docker pull quay.io/jiazha/upstream-opm-builder:v1
Trying to pull repository quay.io/jiazha/upstream-opm-builder ...
v1: Pulling from quay.io/jiazha/upstream-opm-builder
Digest: sha256:66d77b1b0af5bb2299916d0fed935bfd70720ce9d89406c10ccc08f2de910334
Status: Downloaded newer image for quay.io/jiazha/upstream-opm-builder:v1
# docker images quay.io/jiazha/upstream-opm-builder:v1 --digests
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
quay.io/jiazha/upstream-opm-builder v1 <none> 6ff688cecdcc 3 days ago 56.8 MB
那我们换个不同的Registry 这个digest 会变吗?
本地运行一个Docker reigstry:
# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7f8f51ae59c7 registry "/entrypoint.sh /e..." 5 days ago Up 5 days 0.0.0.0:5000->5000/tcp registry
tag, push, pull 等操作:
# docker tag quay.io/operator-framework/upstream-opm-builder localhost:5000/jiazha/upstream-opm-builder
# docker push localhost:5000/jiazha/upstream-opm-builder
The push refers to a repository [localhost:5000/jiazha/upstream-opm-builder]
537da2905474: Pushed
b1db8a3aea84: Pushed
latest: digest: sha256:66d77b1b0af5bb2299916d0fed935bfd70720ce9d89406c10ccc08f2de910334 size: 740
# docker rmi localhost:5000/jiazha/upstream-opm-builder
Untagged: localhost:5000/jiazha/upstream-opm-builder:latest
Untagged: localhost:5000/jiazha/upstream-opm-builder@sha256:66d77b1b0af5bb2299916d0fed935bfd70720ce9d89406c10ccc08f2de910334
# docker pull localhost:5000/jiazha/upstream-opm-builder
Using default tag: latest
Trying to pull repository localhost:5000/jiazha/upstream-opm-builder ...
latest: Pulling from localhost:5000/jiazha/upstream-opm-builder
Digest: sha256:66d77b1b0af5bb2299916d0fed935bfd70720ce9d89406c10ccc08f2de910334
Status: Downloaded newer image for localhost:5000/jiazha/upstream-opm-builder:latest
Digest 没有变化:
# docker inspect localhost:5000/jiazha/upstream-opm-builder:latest --format={{.RepoDigests}}
[localhost:5000/jiazha/upstream-opm-builder@sha256:66d77b1b0af5bb2299916d0fed935bfd70720ce9d89406c10ccc08f2de910334 quay.io/jiazha/upstream-opm-builder@sha256:66d77b1b0af5bb2299916d0fed935bfd70720ce9d89406c10ccc08f2de910334 quay.io/operator-framework/upstream-opm-builder@sha256:66d77b1b0af5bb2299916d0fed935bfd70720ce9d89406c10ccc08f2de910334]
换用Podman 拉取看下,可以看到digest始终没有变化,一直是"sha256:66d77b1b0af5bb2299916d0fed935bfd70720ce9d89406c10ccc08f2de910334"
[root@preserve-olm-env ~]# podman pull quay.io/operator-framework/upstream-opm-builder
Trying to pull quay.io/operator-framework/upstream-opm-builder...
Getting image source signatures
Copying blob 22a917d9a8ff done
Copying blob f0045e846072 done
Copying config 6ff688cecd done
Writing manifest to image destination
Storing signatures
6ff688cecdccb1bf2ad2826f10b4402776eeb678dadb1735251ca53a5afd40e0
# podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
quay.io/operator-framework/upstream-opm-builder latest 6ff688cecdcc 3 days ago 56.9 MB
# podman inspect localhost:5000/jiazha/upstream-opm-builder:latest |jq '.[]["Digest"]'
"sha256:66d77b1b0af5bb2299916d0fed935bfd70720ce9d89406c10ccc08f2de910334"
那如果使用Podman 运行的registry呢?使用podman搭建一个私有的registry, 如下:
[root@preserve-olm-env ~]# podman run -ti -d --name registry01 -p 5001:5000 -v /opt/registry/data:/var/lib/registry:z -v /opt/registry/auth:/auth:z -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd -v /opt/registry/certs:/certs:z -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key registry
d0385bb08bc1bdd1e305833363949b2969273dedd4a5b23ae1d46ea5fa71b6d4
[root@preserve-olm-env ~]# podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d0385bb08bc1 docker.io/library/registry:2 /etc/docker/regis... 3 seconds ago Up 3 seconds ago 0.0.0.0:5001->5000/tcp registry01
tag 镜像,rmi 本地镜像后,重新拉取:
[root@preserve-olm-env ~]# podman tag localhost:5000/jiazha/upstream-opm-builder localhost:5001/podman/upstream-opm-builder
[root@preserve-olm-env ~]# podman push localhost:5001/podman/upstream-opm-builder
Getting image source signatures
Copying blob b1db8a3aea84 done
Copying blob 537da2905474 done
Copying config 6ff688cecd done
Writing manifest to image destination
Storing signatures
[root@preserve-olm-env ~]# podman rmi localhost:5001/podman/upstream-opm-builder
Untagged: localhost:5001/podman/upstream-opm-builder:latest
[root@preserve-olm-env ~]# podman pull localhost:5001/podman/upstream-opm-builder
Trying to pull localhost:5001/podman/upstream-opm-builder...
Getting image source signatures
Copying blob e19f7f395db1 skipped: already exists
Copying blob 4469a46fbd96 skipped: already exists
Copying config 6ff688cecd done
Writing manifest to image destination
Storing signatures
6ff688cecdccb1bf2ad2826f10b4402776eeb678dadb1735251ca53a5afd40e0
查看新拉取的镜像的Digest, 没有变化,仍然是:"sha256:66d77bxxx"!
[root@preserve-olm-env ~]# podman inspect localhost:5001/podman/upstream-opm-builder |jq '.[]["Digest"]'
"sha256:66d77b1b0af5bb2299916d0fed935bfd70720ce9d89406c10ccc08f2de910334"