🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[toc] ## **流程** 镜像上传的流程与下载刚好相反。上传的时候先上传layer,然后再上传manifests文件。 ## **上传layer** #### **上传初始化** 在上传每一个layer之前,先要调用一个api进行layer上传的初始始化操作, ``` POST /v2/<repository>/blobs/uploads ``` 该API调用会返回一个结果,告诉我们接下来如何去上传这一个layer,比如: ``` $ curl -X POST -I 192.168.1.103:8021/v2/library/registry/blobs/uploads/ HTTP/1.1 202 Accepted Server: nginx/1.11.5 Date: Thu, 13 Sep 2018 11:05:26 GMT Content-Type: text/plain; charset=utf-8 Content-Length: 0 Connection: keep-alive Docker-Distribution-Api-Version: registry/2.0 Docker-Upload-Uuid: 91cbb0a1-c335-45ae-b155-86bf06897d9d Location: http://192.168.1.103:8021/v2/library/registry/blobs/uploads/91cbb0a1-c335-45ae-b155-86bf06897d9d?_state=YeQZM_9WTPi9Gxfgi6chPo7gZ0fRsJisqthEwHrrmTl7Ik5hbWUiOiJsaWJyYXJ5L3JlZ2lzdHJ5IiwiVVVJRCI6IjkxY2JiMGExLWMzMzUtNDVhZS1iMTU1LTg2YmYwNjg5N2Q5ZCIsIk9mZnNldCI6MCwiU3RhcnRlZEF0IjoiMjAxOC0wOS0xM1QxMTowNToyNi45NzI2MjE4ODhaIn0%3D Range: 0-0 ``` 在返回结果中有一个`Location`字段,该字段表示上传该layer的URL。 #### **整块上传** 我们调用拿到上面的URL后,就可以上传实际的layer了。上传layer时可以把layer切成多块,分多个http请求上传,也可以在一个http请求中上传。接下来,我们一次性把整个layer都上传: ``` $ curl -X PUT -H "Content-Type: application/octet-stream" -H -I --upload-file /root/image/layers/06ba8e23299fcf9dd9efb3c5acd4c9d03badac5392953001c75d38197113a63a.tar.gz http://192.168.1.103:8021/v2/library/registry/blobs/uploads/91cbb0a1-c335-45ae-b155-86bf06897d9d?_state=YeQZM_9WTPi9Gxfgi6chPo7gZ0fRsJisqthEwHrrmTl7Ik5hbWUiOiJsaWJyYXJ5L3JlZ2lzdHJ5IiwiVVVJRCI6IjkxY2JiMGExLWMzMzUtNDVhZS1iMTU1LTg2YmYwNjg5N2Q5ZCIsIk9mZnNldCI6MCwiU3RhcnRlZEF0IjoiMjAxOC0wOS0xM1QxMTowNToyNi45NzI2MjE4ODhaIn0%3D\&digest=sha256:06ba8e23299fcf9dd9efb3c5acd4c9d03badac5392953001c75d38197113a63a HTTP/1.1 100 Continue HTTP/1.1 201 Created Server: nginx/1.11.5 Date: Thu, 13 Sep 2018 11:12:30 GMT Content-Type: text/plain; charset=utf-8 Content-Length: 0 Connection: keep-alive Docker-Content-Digest: sha256:06ba8e23299fcf9dd9efb3c5acd4c9d03badac5392953001c75d38197113a63a Docker-Distribution-Api-Version: registry/2.0 Location: http://192.168.1.103:8021/v2/library/registry/blobs/sha256:06ba8e23299fcf9dd9efb3c5acd4c9d03badac5392953001c75d38197113a63a ``` 当上传成功后,会返回状态码201,表示该layer已经上传成功。 #### **其他layer** 其他layer的上传重复上面的两个请求即可 #### **避免layer的重复上传** registry有两个API ``` HEAD /v2/<repository>/blobs/<digest> POST /v2/<repository>/blobs/uploads/?mount=<digest>&from=<repositoryName> ``` 第一个API可以判断该repository下某个layer是否已经存在,第二个API可以从registry中的另一个repository将某个layer挂载过来。 但是,对于docker-daemon,其默认行为是会调用第一个API,不会调用第二个(因为docker-daemon不知道registry上有哪些其他的repository)。所以,当docker push在上传镜像的时候,如果一个repository有两个tag,那么上传第二个tag时,重复的layer就不会上传。但如果两个镜像的repository不一样,那么即使它们有重复的layer,也会各自上传一次。 ## **上传manifest文件** manifest文件有两种格式,`schema2-v1`与`schema2-v2`。在这里,我们只能上传`schema2-v1`格式的manifest。 (未完待续)