# pull镜像

## 流程

镜像下载的流程如下：

1、下载镜像的manifest 2、从manifest中获取镜像的imageid，若imageid在本地已存在，则结束 3、从manifest中获取各个layer的digest，根据digest查找该layer是否存在本地，若存在则无需下载该layer；若不存在，则从registry下载该layer 4、根据本地的后端存储更新相应的文件

## 下载manifest

在registry的API-V2中，下载manifest的API为

```
/v2/{repository}/manifests/{tag}
```

由于mainfest的schema定义有两个版本，我们一般去拿`schemaversion=2`的mainfest。那么在上述的URL请求中还需要在Header参数中添加 `Accept: application/vnd.docker.distribution.manifest.v2+json`

比如，我们使用docker官网的镜像`registry:2.5.0`搭建一个私有的镜像仓库，然后把该镜像本身上传到私有镜像仓库中。那么，我们获取该镜像的manifest的内容如下：

```
{
    "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"
        },
        {
            "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
            "size": 614066,
            "digest": "sha256:2ee5ed28ffa762104505295c3c256c52a87fe8af0114b9e0198e9036495e10b8"
        },
        {
            "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
            "size": 6726616,
            "digest": "sha256:d1562c23a8aa4913a2fc720a3c478121f45d26597b58bbf9a29238276ca420a7"
        },
        {
            "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
            "size": 370,
            "digest": "sha256:06ba8e23299fcf9dd9efb3c5acd4c9d03badac5392953001c75d38197113a63a"
        },
        {
            "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",
            "size": 215,
            "digest": "sha256:802d2a9c64e8f556e510b4fe6c5378b9d49d8335a766d156ef21c7aeac64c9d6"
        }
    ]
}
```

## 下载layer

在得到镜像的manifest之后，根据layers中layer的digest，去registry的API中下载相应的layer。关于layer的API有如下几个：

```
HEAD /v2/{repository}/blobs/{digest}
GET /v2/{repository}/blobs/{digest}
```

注意，在下载layer的时候，在GET方法中需要在HEADER中传入参数 `mediaType: application/vnd.docker.image.rootfs.diff.tar.gzip`
