Registry中的存储

首先,我们用docker官网的library/registry:2.5.0在本地搭建一个私有镜像仓库,然后把该镜像本身上传到私有镜像仓库中。

镜像仓库挂载到本地的根目录为/data/registry,我们查看上传library/registry:2.5.0镜像后的目录树:

/data/registry/
└── docker
└── registry
└── v2
├── blobs
│ └── sha256
│ ├── 06
│ │ └── 06ba8e23299fcf9dd9efb3c5acd4c9d03badac5392953001c75d38197113a63a
│ │ └── data
│ ├── 2e
│ │   └── 2ee5ed28ffa762104505295c3c256c52a87fe8af0114b9e0198e9036495e10b8
│   │   └── data
│   ├── 51
│   │   └── 51d8869caea35f58dd6a2309423ec5382f19c4e649b5d2c0e3898493f42289d6
│   │   └── data
│   ├── 80
│   │   └── 802d2a9c64e8f556e510b4fe6c5378b9d49d8335a766d156ef21c7aeac64c9d6
│   │   └── data
│   ├── c6
│   │   └── c6c14b3960bdf9f5c50b672ff566f3dabd3e450b54ae5496f326898513362c98
│   │   └── data
│   ├── d1
│   │   └── d1562c23a8aa4913a2fc720a3c478121f45d26597b58bbf9a29238276ca420a7
│   │   └── data
│   └── e1
│   └── e110a4a1794126ef308a49f2d65785af2f25538f06700721aad8283b81fdfa58
│   └── data
└── repositories
└── library
└── registry
├── _layers
│   └── sha256
│   ├── 06ba8e23299fcf9dd9efb3c5acd4c9d03badac5392953001c75d38197113a63a
│   │   └── link
│   ├── 2ee5ed28ffa762104505295c3c256c52a87fe8af0114b9e0198e9036495e10b8
│   │   └── link
│   ├── 802d2a9c64e8f556e510b4fe6c5378b9d49d8335a766d156ef21c7aeac64c9d6
│   │   └── link
│   ├── c6c14b3960bdf9f5c50b672ff566f3dabd3e450b54ae5496f326898513362c98
│   │   └── link
│   ├── d1562c23a8aa4913a2fc720a3c478121f45d26597b58bbf9a29238276ca420a7
│   │   └── link
│   └── e110a4a1794126ef308a49f2d65785af2f25538f06700721aad8283b81fdfa58
│   └── link
├── _manifests
│   ├── revisions
│   │   └── sha256
│   │   └── 51d8869caea35f58dd6a2309423ec5382f19c4e649b5d2c0e3898493f42289d6
│   │   └── link
│   └── tags
│   └── 2.5.0
│   ├── current
│   │   └── link
│   └── index
│   └── sha256
│   └── 51d8869caea35f58dd6a2309423ec5382f19c4e649b5d2c0e3898493f42289d6
│   └── link
└── _uploads

数据都在/data/registry/docker/registry/v2下,接下来我们使用的相对路径都是在该目录下。

blobs

blobs目录下存储着所有的layer压缩包。根据《镜像的本地存储》一文可以知道,library/registry:2.5.0只有五个layer,分别是blobs目录下的

06ba8e23299fcf9dd9efb3c5acd4c9d03badac5392953001c75d38197113a63a
2ee5ed28ffa762104505295c3c256c52a87fe8af0114b9e0198e9036495e10b8
802d2a9c64e8f556e510b4fe6c5378b9d49d8335a766d156ef21c7aeac64c9d6
d1562c23a8aa4913a2fc720a3c478121f45d26597b58bbf9a29238276ca420a7
e110a4a1794126ef308a49f2d65785af2f25538f06700721aad8283b81fdfa58

这五个目录下的data文件是二进制文件。对这些二进制文件的内容做sha256哈希,得到的哈希值就是目录的名字。比如:

$ sha256sum blobs/sha256/e1/e110a4a1794126ef308a49f2d65785af2f25538f06700721aad8283b81fdfa58/data
e110a4a1794126ef308a49f2d65785af2f25538f06700721aad8283b81fdfa58

对这些data文件解压,得到的就是该layer的文件系统(目录与文件),比如:

$ mkdir layer
$ tar xzf blobs/sha256/e1/e110a4a1794126ef308a49f2d65785af2f25538f06700721aad8283b81fdfa58/data -C layer
$ ll layer/
total 12
drwxr-xr-x. 2 root root 4096 Jun 24 2016 bin
drwxr-xr-x. 4 root root 40 Jun 24 2016 dev
drwxr-xr-x. 14 root root 4096 Jun 24 2016 etc
drwxr-xr-x. 2 root root 6 Jun 24 2016 home
drwxr-xr-x. 5 root root 188 Jun 24 2016 lib
lrwxrwxrwx. 1 root root 12 Jun 24 2016 linuxrc -> /bin/busybox
drwxr-xr-x. 5 root root 44 Jun 24 2016 media
drwxr-xr-x. 2 root root 6 Jun 24 2016 mnt
drwxr-xr-x. 2 root root 6 Jun 24 2016 proc
drwx------. 2 root root 6 Jun 24 2016 root
drwxr-xr-x. 2 root root 6 Jun 24 2016 run
drwxr-xr-x. 2 root root 4096 Jun 24 2016 sbin
drwxr-xr-x. 2 root root 6 Jun 24 2016 srv
drwxr-xr-x. 2 root root 6 Jun 24 2016 sys
drwxrwxrwt. 2 root root 6 Jun 24 2016 tmp
drwxr-xr-x. 7 root root 66 Jun 24 2016 usr
drwxr-xr-x. 12 root root 125 Jun 24 2016 var

值得注意的是,虽然我们可以用tar命令把layer压缩包解压,但是解压后我们用tar命令重新压缩tar czvf layer.tar.gzip layer/*,再对压缩后的layer.tar.gzip做sha256哈希,得到的hash值与直接对data做哈希得到的值不一样。实验证明不是文件名的问题,对data文件重命名,哈希值都是一样的,因为哈希是对文件内容做的,与文件名无关。猜测是data的打包压缩方式与直接用tar命令不一样。

blobs目录下除了上述五个目录外,还有另外两个:

c6c14b3960bdf9f5c50b672ff566f3dabd3e450b54ae5496f326898513362c98
51d8869caea35f58dd6a2309423ec5382f19c4e649b5d2c0e3898493f42289d6

如果我们在某台主机上下载该镜像,会发现 c6c14b3960bdf9f5c50b672ff566f3dabd3e450b54ae5496f326898513362c98就是镜像library/registry:2.5.0的image-id,51d8869caea35f58dd6a2309423ec5382f19c4e649b5d2c0e3898493f42289d6就是镜像的digest。

$ docker images --digests --no-trunc
REPOSITORY TAG DIGEST IMAGE ID CREATED SIZE
192.168.1.103:8021/library/registry 2.5.0 sha256:51d8869caea35f58dd6a2309423ec5382f19c4e649b5d2c0e3898493f42289d6 sha256:c6c14b3960bdf9f5c50b672ff566f3dabd3e450b54ae5496f326898513362c98 2 years ago 33.31 MB

image-id是镜像的config文件的哈希值:

$ sha256sum blobs/sha256/c6/c6c14b3960bdf9f5c50b672ff566f3dabd3e450b54ae5496f326898513362c98/data
c6c14b3960bdf9f5c50b672ff566f3dabd3e450b54ae5496f326898513362c98

查看镜像的config文件的内容(不要用cat命令,用jq . blobs/sha256/c6/c6c14b3960bdf9f5c50b672ff566f3dabd3e450b54ae5496f326898513362c98/data命令可以格式化输出,方便查看):

从config文件可以看出,library/registry:2.5.0有五个layer。不过在该文件里,使用的是layer的diffid。

image-digest是镜像的manifest文件的哈希值:

$ sha256sum blobs/sha256/51/51d8869caea35f58dd6a2309423ec5382f19c4e649b5d2c0e3898493f42289d6/data
51d8869caea35f58dd6a2309423ec5382f19c4e649b5d2c0e3898493f42289d6

查看digest文件的内容如下(与查看config文件一样的命令查看):

从manifest文件也同样可以看出,镜像library/registry:2.5.0有五个layer。只不过在该文件里,使用的是layer的digest。从mediaType字段可以看出,blobs目录下面layer的data文件是经过tar及gzip算法进行了打包与压缩的。

这里讲一下layer的diffid与digest的区别:

  • layer-diffid:未压缩的layer打包文件的哈希值

  • layer-digest:压缩后的layer打包文件的哈希值

repositories

我们上传镜像library/registry:2.5.0后,便会在repositories目录下生成library/registry目录。接下来我们都以repositories/library/registry作为当前路径

该目录下有三个目录 _layers_manifests_uploads

  • _layers

_layers目录下存储了该repository的所有layer的索引(layer-digest)以及所有的image的索引(image-id)。例如,我们查看某个layer下link文件的内容及image-id下link文件的内容如下:

$ cat _layers/sha256/e110a4a1794126ef308a49f2d65785af2f25538f06700721aad8283b81fdfa58/link
sha256:e110a4a1794126ef308a49f2d65785af2f25538f06700721aad8283b81fdfa58

$ cat _layers/sha256/c6c14b3960bdf9f5c50b672ff566f3dabd3e450b54ae5496f326898513362c98/link
sha256:c6c14b3960bdf9f5c50b672ff566f3dabd3e450b54ae5496f326898513362c98

link文件的内容指向blobs中的实际数据。

registry的API-v2中,下载layer的接口为GET /v2/{repository}/blobs/{layer-digest},根据路径参数repositorylayer-digest,就可以在repositories/{repository}/_layers目录下搜索layer-digest,然后去blobs目录下下载。

  • _manifests

_manifests目录下存储的实际是镜像的digest以及镜像的tag到digest的映射关系。revisions/下存储的就是image-digest,tags/下就是tag到image-digest的映射。

目录树如下:

$ tree _manifests
_manifests/
├── revisions
│   └── sha256
│   └── 51d8869caea35f58dd6a2309423ec5382f19c4e649b5d2c0e3898493f42289d6
│   └── link
└── tags
└── 2.5.0
├── current
│   └── link
└── index
└── sha256
└── 51d8869caea35f58dd6a2309423ec5382f19c4e649b5d2c0e3898493f42289d6
└── link

上面三个link文件的内容全部是sha256:51d8869caea35f58dd6a2309423ec5382f19c4e649b5d2c0e3898493f42289d6,就是镜像library/registry:2.5.0的image-digest,指向实际的manifest文件blobs/sha256/51/51d8869caea35f58dd6a2309423ec5382f19c4e649b5d2c0e3898493f42289d6

在registry的API-v2中,下载镜像的manifest文件的接口为GET /v2/{repository}/mainfests/{tag_or_digest}。如果提供是的是tag 2.5.0,根据tags/2.5.0/current/link文件的内容,得到的manifest文件为blobs/sha256/51/51d8869caea35f58dd6a2309423ec5382f19c4e649b5d2c0e3898493f42289d6;如果提供是的digest sha256:51d8869caea35f58dd6a2309423ec5382f19c4e649b5d2c0e3898493f42289d6,根据revisions/sha256/51d8869caea35f58dd6a2309423ec5382f19c4e649b5d2c0e3898493f42289d6/link文件的内容,得到的manifest文件还是blobs/sha256/51/51d8869caea35f58dd6a2309423ec5382f19c4e649b5d2c0e3898493f42289d6

Last updated