🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] ## **一、环境** 与上篇文章使用同一台主机 ## **二、安装Harbor** 首先,使用的是harbor-offline-installer-0.5.0.tgz安装的一个Harbor,数据目录设置为`/data`,然后把`library/registry:2.5.0`镜像上传到harbor中 ## **三、查看registry的目录结构** 镜像仓库挂载到本地的根目录为`/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`下,接下来我们使用的相对路径都是在该目录下。 ### **3.1 blobs** ##### **3.1.1 镜像层文件** blobs目录下存储着所有的layer压缩包。根据《镜像的本地存储》一文可以知道,`library/registry:2.5.0`只有五个layer,分别是blobs目录下的(注意如果docker的版本不一样,五个镜像层的命字会不一样) ``` 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命令不一样。 ##### **3.1.2 manifest与config文件** blobs目录下除了上述五个目录外,还有另外两个: ``` c6c14b3960bdf9f5c50b672ff566f3dabd3e450b54ae5496f326898513362c98 51d8869caea35f58dd6a2309423ec5382f19c4e649b5d2c0e3898493f42289d6 ``` 如果我们在某台主机上下载该镜像,会发现二者分别是镜像`library/registry:2.5.0`的image-id及digest ``` c6c14b3960bdf9f5c50b672ff566f3dabd3e450b54ae5496f326898513362c98 : 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`命令) ``` $ 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}`,根据路径参数`repository`与`layer-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`。