go-containerregistry 實戰篇之容器鏡像下載
一、庫介紹
go-containerregistry 是 google 公司開源的用于處理容器鏡像的golang客戶端庫,它提供了一個對鏡像的操作介面,這個介面背后的資源可以是 鏡像倉庫的遠程資源,鏡像的tar包,甚至是 docker daemon 行程,
它主要基于同名的python專案
下面我們就簡單介紹下如何使用這個專案來完成我們的目標—— 在代碼中決議鏡像,
庫提供了crane和遠程遠程鏡像進行互動,
二、crane初體驗
2、1 crane 安裝和使用
Crane 是一個與遠程鏡像和倉庫互動的工具,
1)安裝Crane
go install github.com/google/go-containerregistry/cmd/crane@latest
https://github.com/google/go-containerregistry/blob/main/cmd/crane/doc/crane.md
在go-containerregistry的crane的檔案目錄中,有crane的詳細檔案,
2)crane命令
- crane append - 將 tarball 的內容附加到遠程鏡像
- crane auth - 登錄或訪問憑證
- crane blob - 從倉庫中讀取blob
- crane catalog - 列舉倉庫中的repos
- crane config - 獲取鏡像的配置
- crane copy - 在保留摘要值的同時,有效地將遠程鏡像從 src 復制到 dst
- crane delete - 從registry倉庫中洗掉鏡像的參考
- crane digest - 獲取影像的摘要
- crane export - 將遠程鏡像的內容匯出為 tarball
- crane flatten - 將鏡像的多層合并為單個層
- crane ls - 列出 repo 中的標簽
- crane manifest - 獲取鏡像的manifest
- crane mutate - 修改鏡像標簽和注釋,需將容器推送到倉庫并更新manifest,
- crane pull - 通過參考拉取遠程鏡像,并將其內容存盤在本地,
- crane push - 將本地鏡像內容推送到遠程倉庫
- crane rebase - 將鏡像重定位到新的基礎鏡像上
- crane tag - 有效地標記遠程鏡像
- crane validate - 驗證image鏡像格式是否正確
- crane version - 列印版本
對于容器鏡像下載功能來說,就是執行crane pull <鏡像全名>這個命令
2、2 crane 鏡像下載API
我最關心的是下載鏡像功能,也就是crane pull命令以及其對應的api,
鏡像下載的API包括:
- Pull函式
- SaveLegacy或SaveOCI函式
func Pull(src string, opt ...Option) (v1.Image, error)
Pull 函式回傳遠程鏡像 src 的 v1.Image,src引數為鏡像的全程,如alpine:latest
func SaveLegacy(img v1.Image, src, path string) error
SaveLegacy 將 img指定的鏡像內容寫為tarball壓縮包,路徑為path
或
func SaveOCI(img v1.Image, path string) error
SaveOCI 將 img 指定的鏡像內容以 OCI 鏡像格式寫入path路徑上,
三、crane下載容器鏡像demo
func DownloadImage(imageFullName string) {
var (
image v1.Image
err error
)
//1.從遠程倉庫拉取鏡像
image, err = crane.Pull(imageFullName)
if err != nil {
fmt.Println("crane.Pull function failed")
return
}
//2.獲取鏡像的哈希值
m, err := image.Manifest()
imageFullHash := m.Config.Digest.Hex
fmt.Println("image hash:", imageFullHash)
//3.創建鏡像存盤路徑
imageStorageDir := "/tmp" //默認值為tmp目錄
err = os.MkdirAll(imageStorageDir, 0755)
if err != nil {
fmt.Printf("mkdir %s failed!\n")
return
}
imagePath := imageStorageDir + "/package.tar"
//4.保存鏡像到存盤路徑,SaveLegacy保存的鏡像格式為tarball
//你也可采用SaveOCI函式完成這個功能
err = crane.SaveLegacy(image, src, imagePath)
if err != nil {
fmt.Println("crane.SaveLegacy function failed")
return
}
}
使用crane下載鏡像很簡單,分為以下三步
1、從遠程倉庫拉取鏡像資訊
2、創建鏡像存盤路徑
3、保存鏡像到存盤路徑
四、鏡像包格式探秘
備注:go-containerregistry的tarball格式是有別于OCI規范的,
4、1 鏡像包的組織形式
上面的demo程式成功下載alpine:latest鏡像,并存盤到/tmp/packaget.tar后我們解壓packaget.tar,如下圖所示:
[root@t440s package]# tree
.
├── 47d7af55c64c2611fde7f765c544f305238fb7c7fd7d5118e170202f887e9987
│ ├── json
│ ├── layer.tar
│ └── VERSION
├── c059bfaa849c4d8e4aecaeb3a10c2d9b3d85f5165c66ad3a4d937758128c4d18.json
├── manifest.json
└── repositories
1 directory, 6 files
manifest.json檔案:在最頂層,有一個manifest.json檔案包含多個鏡像的資訊
對于每個層(layer),都會以鏡像層 ID作為目錄,目錄中包含以下內容:
layer.tar - 未壓縮的層 tar包
json - 以Layer ID命名的json檔案,包含Layer層的元資料
VERSION - 版本字串,始終設定為1.0
c059bfaa849c4d8e4aecaeb3a10c2d9b3d85f5165c66ad3a4d937758128c4d18.json :鏡像描述檔案
4、2 檔案內容
下面我們依次剖析以下檔案
manifest.json
鏡像描述檔案
Layer鏡像層資料
repositories檔案
1) manifest.json檔案
manifest.json 檔案中內容如下所示:
[{
"Config": "c059bfaa849c4d8e4aecaeb3a10c2d9b3d85f5165c66ad3a4d937758128c4d18.json",
"RepoTags": ["alpine:latest"],
"Layers": ["47d7af55c64c2611fde7f765c544f305238fb7c7fd7d5118e170202f887e9987/layer.tar"]
}]
其欄位解釋如下:
Config:組態檔路徑
Layers:指明了Layer層檔案的存盤路徑
RepoTags:鏡像的名稱,帶有標簽
其所有路徑都是相當于manifest.json檔案路徑的相對路徑,
2) 鏡像描述檔案
鏡像描述檔案是上面的c059bfaa849c4d8e4aecaeb3a10c2d9b3d85f5165c66ad3a4d937758128c4d18.json檔案
其json結構如下所示:
{
"architecture": "amd64", #架構
"config": {
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],
"Cmd": ["/bin/sh"],
"Image": "sha256:b747534ae29d08c0c84cc4326caf04e873c6d02bb67cd9c7644be2b4fa8d2f31",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": null
},
"container": "4292e8ed2ef2b6dc4bbaf8e1cda0cb5f95b96adc4aa2da3d15181b54d07a0b34",
"container_config": {
"Hostname": "4292e8ed2ef2",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],
"Cmd": ["/bin/sh", "-c", "#(nop) ", "CMD [\"/bin/sh\"]"],
"Image": "sha256:b747534ae29d08c0c84cc4326caf04e873c6d02bb67cd9c7644be2b4fa8d2f31",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {}
},
"created": "2021-11-24T20:19:40.483367546Z",
"docker_version": "20.10.7",
"history": [{
"created": "2021-11-24T20:19:40.199700946Z",
"created_by": "/bin/sh -c #(nop) ADD file:9233f6f2237d79659a9521f7e390df217cec49f1a8aa3a12147bbca1956acdb9 in / "
}, {
"created": "2021-11-24T20:19:40.483367546Z",
"created_by": "/bin/sh -c #(nop) CMD [\"/bin/sh\"]",
"empty_layer": true
}],
"os": "linux",
"rootfs": {
"type": "layers",
"diff_ids": ["sha256:8d3ac3489996423f53d6087c81180006263b79f206d3fdec9e66f0e27ceb8759"]
}
}
包含作業系統、容器配置、rootfs、創建時間、系統架構等資訊,
3) Layer鏡像層資料
由manifest.json檔案的Layers欄位可知,鏡像層資料的存盤路徑為47d7af55c64c2611fde7f765c544f305238fb7c7fd7d5118e170202f887e9987/layer.tar
將layer.tar包創建檔案夾layer并進行解壓:
mkdir layer
tar xvf layer.tar -C layer

具備啟動一個系統所需要的最小檔案系統,
4) repositories檔案
{
"alpine": {
"latest": "47d7af55c64c2611fde7f765c544f305238fb7c7fd7d5118e170202f887e9987"
}
}
描述鏡像的名稱和tag以及sha值,
五、總結
今天我們學習了go-containerregistry庫中使用crane來進行容器鏡像下載,將下載的鏡像保存成tar包格式,并了解了鏡像包的格式,以及內部的檔案組織形式,
參考資料:
https://aliyun123.cn/2299.html
本文由博客一文多發平臺 OpenWrite 發布!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/438009.html
標籤:其他
上一篇:Redis基本操作
下一篇:物件,Java集合總結
