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-...
在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 layertar xvf layer.tar -C layer
具备启动一个零碎所须要的最小文件系统。
4) repositories文件
{ "alpine": { "latest": "47d7af55c64c2611fde7f765c544f305238fb7c7fd7d5118e170202f887e9987" }}
形容镜像的名称和tag以及sha值。
五、总结
明天咱们学习了go-containerregistry库中应用crane来进行容器镜像下载,将下载的镜像保留成tar包格局,并理解了镜像包的格局,以及外部的文件组织模式。
参考资料:
https://aliyun123.cn/2299.html
本文由博客一文多发平台 OpenWrite 公布!