[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`。
- 安装
- 在线安装
- 离线安装
- 下载镜像
- 下载DockerHub镜像
- 下载Google镜像
- 阿里云镜像中心
- 下载ARM镜像
- 容器命名空间
- Linux命名空间概述
- 根据PID快速定位到容器
- 进入到容器的命名空间
- Dockerfile
- 基本语法
- 前台运行
- 镜像存储
- 本地存储
- Registry中的存储
- 如何判断两个镜像是否是同一个
- Registry
- Notification
- Auth
- 基本原理
- Token认证的设计
- API
- Pull镜像
- Push镜像
- Docker设置代理
- 日志
- 磁盘占用与清理
- Docker选项与K8S的Yaml
- 运维总结
- 常用命令
- DockerCompose
- 构建ARM版本
- 跨架构
- x86架构下构建arm64镜像
- Containerd
- ctr-crictl-nerdctl
- ctr
- Insecure-Registry
- Kata
- 构建OS镜像
- 进入到kata虚机