將鏡像tar包通過API直接push到registry倉(cāng)庫(kù)
為了實(shí)現(xiàn)docker tar包能夠直接通過頁(yè)面上傳,調(diào)研了一下registry的api,以及如何解析tar包(其實(shí)就是docker daemon程序?qū)崿F(xiàn)的部分)。
要想實(shí)現(xiàn),首先要了解docker tar包中結(jié)構(gòu)組成:
tar包結(jié)構(gòu)
拿了一個(gè)包含一個(gè)鏡像的tar包進(jìn)行解壓:
.
├──?1ecf8bc84a7c3d60c0a6bbdd294f12a6b0e17a8269616fc9bdbedd926f74f50c
│???├──?VERSION
│???├──?json
│???└──?layer.tar
├──?6f4ec1f3d7ea33646d491a705f94442f5a706e9ac9acbca22fa9b117094eb720.json
├──?aaac5bde2c2bcb6cc28b1e6d3f29fe13efce6d6b669300cc2c6bfab96b942af4
│???├──?VERSION
│???├──?json
│???└──?layer.tar
├──?b63363f0d2ac8b3dca6f903bb5a7301bf497b1e5be8dc4f57a14e4dc649ef9bb
│???├──?VERSION
│???├──?json
│???└──?layer.tar
├──?c453224a84b8318b0a09a83052314dd876899d3a1a1cf2379e74bba410415059
│???├──?VERSION
│???├──?json
│???└──?layer.tar
├──?dd8ef1d42fbcccc87927eee94e57519c401b84437b98fcf35505fb6b7267a375
│???├──?VERSION
│???├──?json
│???└──?layer.tar
├──?manifest.json
└──?repositories
文件說明:
「manifest.json文件」:
[
????{
????????"Config":"6f4ec1f3d7ea33646d491a705f94442f5a706e9ac9acbca22fa9b117094eb720.json",
????????"RepoTags":[
????????????"alpine:filebeat-6.8.7-arm64"
????????],
????????"Layers":[
????????????"aaac5bde2c2bcb6cc28b1e6d3f29fe13efce6d6b669300cc2c6bfab96b942af4/layer.tar",
????????????"dd8ef1d42fbcccc87927eee94e57519c401b84437b98fcf35505fb6b7267a375/layer.tar",
????????????"c453224a84b8318b0a09a83052314dd876899d3a1a1cf2379e74bba410415059/layer.tar",
????????????"b63363f0d2ac8b3dca6f903bb5a7301bf497b1e5be8dc4f57a14e4dc649ef9bb/layer.tar",
????????????"1ecf8bc84a7c3d60c0a6bbdd294f12a6b0e17a8269616fc9bdbedd926f74f50c/layer.tar"
????????]
????}
]
manifest.json 包含了對(duì)這個(gè)tar包的描述信息,比如image config文件地址,tags說明,鏡像layer信息,在解析的時(shí)候也是根據(jù)這個(gè)文件去獲取關(guān)聯(lián)的文件。
「image config文件」
比如:6f4ec1f3d7ea33646d491a705f94442f5a706e9ac9acbca22fa9b117094eb720.json文件:
?內(nèi)容太多就不貼了 這里包含了鏡像運(yùn)行的信息,比如env,執(zhí)行參數(shù),以及鏡像歷史等。
?
「layer層文件:layer.tar」
鏡像的每一層的文件信息都打包在了一個(gè)單獨(dú)的layer.tar包中,也是在上傳的時(shí)候需要用到的。
registry api
「流程:」
1、獲取鑒權(quán)信息 2、檢查layer.tar是否已經(jīng)存在 3、上傳layer.tar 4、上傳image config 5、上傳manifest(非包中的 manifest.json而是Manifest struct)
?這里只列出了在上傳的時(shí)候需要用的api
?
1、獲取鑒權(quán)信息
這里跟registry倉(cāng)庫(kù)選擇的鑒權(quán)方式有關(guān),可選basic auth或者token鑒權(quán)。這里我是以最基本的basic auth為例子,如果是token鑒權(quán)的方式參考這里:https://docs.docker.com/registry/spec/auth/jwt/
2、檢查上傳
HEAD?/v2/image/blobs/
若返回200 OK 則表示存在,不用上傳
3、開始上傳服務(wù) 我這里是以分塊上傳的方式進(jìn)行
POST?/v2/image/blobs/uploads/
如果post請(qǐng)求返回202 accepted,一個(gè)url會(huì)在location字段返回.
?????202?Accepted
?????Location:?/v2/\/blobs/uploads/\
?????Range:?bytes=0-
?????Content-Length:?0
?????Docker-Upload-UUID:??#?可以用來查看上傳狀態(tài)和實(shí)現(xiàn)斷點(diǎn)續(xù)傳
4、分塊上傳
根據(jù)上一步獲取的url,以PATCH的方式提交分塊數(shù)據(jù)。如果是最后一塊數(shù)據(jù)上傳,則以PUT的方式提交,如下:
?>?PUT?/v2//blob/uploads/?digest=
?>?Content-Length:?
?>?Content-Range:?-
?>?Content-Type:?application/octet-stream
???
上傳layer,image config,manifests信息都是一樣的。
?我暫時(shí)只用到了以上api,更多的api參考:https://docs.docker.com/registry/spec/api/
?
實(shí)現(xiàn)
上面說API沒啥感覺,還是看代碼比較明白,所以實(shí)現(xiàn)了這么一個(gè)工具:https://github.com/silenceper/docker-tar-push
「Usage:」
push?your?docker?tar?archive?image?without?docker.
Usage:
??docker-tar-push?[flags]
Flags:
??-h,?--help??????????????help?for?docker-tar-push
??????--log-level?int?????log-level,?0:Fatal,1:Error,2:Warn,3:Info,4:Debug?(default?3)
??????--password?string???registry?auth?password
??????--registry?string???registry?url
??????--skip-ssl-verify???skip?ssl?verify
??????--username?string???registry?auth?username
「Example:」
docker-tar-push?alpine:latest?--registry=http://localhost:5000
「參考」
https://www.jianshu.com/p/6a7b80122602 https://github.com/Razikus/dockerregistrypusher https://docs.docker.com/registry/spec/auth/jwt/ https://github.com/docker/distribution/
推薦閱讀
站長(zhǎng) polarisxu
自己的原創(chuàng)文章
不限于 Go 技術(shù)
職場(chǎng)和創(chuàng)業(yè)經(jīng)驗(yàn)
Go語(yǔ)言中文網(wǎng)
每天為你
分享 Go 知識(shí)
Go愛好者值得關(guān)注
