Description
描述如何使用dockerhub提供的API V2上传镜像,而不经过docker
Reference:
- https://docs.docker.com/registry/spec/api/#pushing-an-image
- https://forums.docker.com/t/401-unauthorized-when-pushing-an-image-layer-to-dockerhub/34832
- http://web.archive.org/web/20180926062602/https://gist.github.com/jlhawn/8f218e7c0b14c941c41f
- https://gist.github.com/alex-bender/55fefa42f47ca4e3013a8c51afa8f3d2
Steps
Auth
首先需要验证账号和密码。具体格式是base64($username:$password)
。编码后的结果应当作为下一步的请求头
在获得正确的base64编码之后,应当向https://auth.docker.io/token?service=registry.docker.io&scope=repository:$reponame:$actions"
发送请求,其中$reponame:$actions
为要访问的repo名称+请求的权限(一般是"push,pull"
)
Overview
要对dockerhub推送镜像,需要认证用户。在之后需要先逐层推送,然后上传manifest。
Auth
1 | UNAME="" |
这里response返回一个对于该repo的token…?
Push layers
推送一个镜像层分两步:第一步通过下面的请求提起一个upload流程并获取一个URL
1 | POST /v2/<name>/blobs/uploads/ |
name
: 镜像所属的namespace,通常为用户名。
返回的示例如下:
1 | $ curl -X POST -I 192.168.1.103:8021/v2/library/registry/blobs/uploads/ |
这里Location
即为下一步上传layer需要的的URL
Chcek existance
1 | HEAD /v2/<name>/blobs/<digest> |
digest
: 镜像层的sha256摘要
如果该层存在则会返回:
1 | 200 OK |
这时候不需要再次上传该层。有时候在之前的tag中上传过,也会提示存在。
这个检测范围有多少?如果是同一个人别的镜像呢?如果是别人的镜像呢?更离谱,别人的私人镜像呢?
Pushing layer
1 | POST /v2/<name>/blobs/uploads/ |
这里调用上面得到的URL,用PUT方法,例如:
1 | 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 |
如果成功会返回Code201
当docker push在上传镜像的时候,如果一个repository有两个tag,那么上传第二个tag时,重复的layer就不会上传。但如果两个镜像的repository不一样,那么即使它们有重复的layer,也会各自上传一次。