go-containerregistry 實戰篇之容器映象下載
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 釋出!