如何判断两个镜像是否是同一个

有时候,我们需要从google下载镜像,但是由于网络原因又下载不下来。此时,网上有教程说,阿里云同步了google的镜像,从阿里云下载就可以了。

然而,我们担心,阿里云上的镜像与google上的镜像,内容是否一样呢(镜像层一样)?本文将介绍如何判断两个镜像,内容是否一样。

根据Digest

同一台主机,不同Registry

有人说,我们在本地有两个不同Registry来源的镜像,能不能根据Digest来判断两个镜像内容是否一样?答案为“否”。

我们回顾前两节的内容,镜像的Digest是镜像的Manifest文件哈希值。Manifest文件在本地是没有存储的,只在Registry端才有存储。如果再回顾Digest文件的内容,大致如下:

{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
   "config": {
      "mediaType": "application/vnd.docker.container.image.v1+json",
      "size": 3017,
      "digest": "sha256:c6c14b3960bdf9f5c50b672ff566f3dabd3e450b54ae5496f326898513362c98"
   },
   "layers": [
      {
         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
         "size": 2310286,
         "digest": "sha256:e110a4a1794126ef308a49f2d65785af2f25538f06700721aad8283b81fdfa58"
      },
      ...
   ]
}

根据上面的内容可以发现,镜像的Manifest文件在Registry端的存储是有版本(schemaVersion)和类型(mediaType)的。

也就是说,对于同一个镜像,上传到不同的Registry,其Manifest文件的内容在不同的Registry中可能不一样。即同一个镜像,在不同的Registry中的Digest可能不一样

我们可以做如下的实验,首先我们从docker hub下载一个镜像registry:2.5.0

$ docker pull registry:2.5.0
2.5.0: Pulling from library/registry
e110a4a17941: Pull complete 
2ee5ed28ffa7: Pull complete 
d1562c23a8aa: Pull complete 
06ba8e23299f: Pull complete 
802d2a9c64e8: Pull complete 
Digest: sha256:1b68f0d54837c356e353efb04472bc0c9a60ae1c8178c9ce076b01d2930bcc5d
Status: Downloaded newer image for registry:2.5.0

$ docker images --digests
REPOSITORY          TAG                 DIGEST                                                                    IMAGE ID            CREATED             SIZE
registry            2.5.0               sha256:1b68f0d54837c356e353efb04472bc0c9a60ae1c8178c9ce076b01d2930bcc5d   c6c14b3960bd        3 years ago         33.3MB

接着,我们把这个镜像重新打一个tag

$ docker tag registry:2.5.0 10.142.232.151:8021/library/registry:2.5.0

$ docker images --digests
REPOSITORY                             TAG                 DIGEST                                                                    IMAGE ID            CREATED             SIZE
10.142.232.151:8021/library/registry   2.5.0               <none>                                                                    c6c14b3960bd        3 years ago         33.3MB
registry                               2.5.0               sha256:1b68f0d54837c356e353efb04472bc0c9a60ae1c8178c9ce076b01d2930bcc5d   c6c14b3960bd        3 years ago         33.3MB

此时,我们竟然发现,重新打上tag的镜像10.142.232.151:8021/library/registry:2.5.0竟然没有Digest。

接着,我们把这个镜像上传到我们自已搭建的Harbor仓库10.142.232.151:8021

$ docker push 10.142.232.151:8021/library/registry:2.5.0
The push refers to repository [10.142.232.151:8021/library/registry]
3bb5bc5ad373: Pushed 
35039a507f7a: Pushed 
d00444e19d65: Pushed 
aa3a31ee27f3: Pushed 
4fe15f8d0ae6: Pushed 
2.5.0: digest: sha256:bf0b4fc3833f908017d650af94071d62a12390020b30658dd623b98b80af81ed size: 1363

根据push的输出日志,我们看到Harbor返回了一个Digest,值为sha256:bf0b4fc3833f908017d650af94071d62a12390020b30658dd623b98b80af81ed,与registry:2.5.0的digest不一样

$ docker images --digests
docker images --digests
REPOSITORY                             TAG                 DIGEST                                                                    IMAGE ID            CREATED             SIZE
10.142.232.151:8021/library/registry   2.5.0               sha256:bf0b4fc3833f908017d650af94071d62a12390020b30658dd623b98b80af81ed   c6c14b3960bd        3 years ago         33.3MB
registry                               2.5.0               sha256:1b68f0d54837c356e353efb04472bc0c9a60ae1c8178c9ce076b01d2930bcc5d   c6c14b3960bd        3 years ago         33.3MB

也说是说,同一个镜像,存储在不同的Registry端,其Digest是不一样的。

相同Registry,不同主机

假如我们在两台不同的主机上下载registry:2.5.0,那么它的Digest是否一样呢?两台主机上下载下来的镜像是否是同一个呢?

答案是,不同主机从同一个Registry下载相同名字的镜像,两台主机上的镜像的Digest可能是一样的,如果一样,也不能表明两台主机上下载的是同一个镜像。

比如我们在amd主机上和arm主机上下载镜像centos:7,我们会发现,两台主机上镜像的Digest是一样的,但ImageID与镜像大小不一样

[root@amd] $ docker images --digests
REPOSITORY                             TAG                 DIGEST                                                                    IMAGE ID            CREATED             SIZE
centos                                 7                   sha256:4a701376d03f6b39b8c2a8f4a8e499441b0d567f9ab9d58e4991de4472fb813c   5e35e350aded        6 weeks ago         203MB
[root@arm] $ docker images --digests
REPOSITORY                    TAG                     DIGEST                                                                    IMAGE ID            CREATED             SIZE
centos                        7                       sha256:4a701376d03f6b39b8c2a8f4a8e499441b0d567f9ab9d58e4991de4472fb813c   4dfd99be812b        6 weeks ago         273MB

根据ImageID

同一台主机,不同镜像名

如果两个镜像(名字不同)在同一台主机上的ImageID是一样的,那么这两个镜像就是同一个镜像(内容是一样的)。如果在同一台主机上,两个名字的镜像的ImageID不一样,那么这两个镜像肯定不是同一个镜像。

相同Registry,不同主机

假如我们在两台不同的主机上下载registry:2.5.0,那么它的ImageID是否一样呢?两台主机上下载下来的镜像是否是同一个呢?

参考上文的Digest中的“相同Registry,不同主机”

总结

可以确定两个镜像一样的方法

  • 如果两个镜像的ImageID一样,那么这两个镜像一样,不管两个镜像在同一台主机上,或者不是同一台主机上(一般对于同一个镜像,如果两台主机的存储驱动一样,这两个镜像的ImageID一般是一样的)

Last updated