使用Docker拉取镜像的时候,我们一条命令就可以完成该工作。
有的时候可能会遇到需要登录的情况。
此时,只需要执行 docker login docker.gz.test.cn 就可以了。
如果你的好奇心多一点,会看到拉取某些镜像的时候是分层的。
那么,在这个过程中,docker是怎么认证的?又是如何实现分层拉取的呢?
Docker Registry的认证
- 尝试从Registry拉取镜像
- 如果该Registry需要认证,那么会返回401未认证,并且在HTTP响应头中返回如何进行认证的信息。
- Registry 客户端带到认证服务请求一个Bearer Token。
- 认证服务认证通过,返回Token
- Docker客户端在HTTP 请求头中带上 Bearer Token到registry
- Registry验证Bearer Token之后,就可以开始拉取镜像的操作了。
docker pull
首先,镜像是一个 JSON 格式的清单(manifest)和单个的层文件的组合。拉取镜像的过程就围绕着检索这两个组件而进行。
那么,在拉取镜像的时候,需要首先获取该镜像的清单数据。该接口的定义如下:
|
|
获取该清单之后,我们就知道,该镜像都有哪些分层数据组成,然后将这些数据一层一层下载下来即可。
|
|
这里明确指出,拉取镜像的时候会出现307或者302,在 Harbor存储使用S3的坑会 我们曾遇到类似的问题。
验证
看完官方文档,我们来验证一下。
拉取一个镜像:1docker pull docker.gz.test.cn/ccloud/ccloud-server:master-20f6fe2
打开Harbor的nginx的日志,可以看到如下的信息:
|
|
第一行: Harbor本身检查该tags是否存在
第二行:尝试pull,registry v2接口返回401未认证。
第三行:Registry客户端到获取token,返回Docker客户端。
第四行:Docker客户端获取镜像的清单。
第五行~最后:Docker客户端按照清单,逐层下载镜像数据。
当这一系列过程都完成的时候,镜像就被拉取下来了。
各位感兴趣的还可以去探索一下:
1、已经存在的镜像层,怎么处理?
2、自己动手写一个Docker Pull的客户端(单线程版和多线程版)