乐趣区

关于golang:gocontainerregistry-实战篇之容器镜像下载

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 layer
tar xvf layer.tar -C layer

具备启动一个零碎所须要的最小文件系统。

4)repositories 文件

{
    "alpine": {"latest": "47d7af55c64c2611fde7f765c544f305238fb7c7fd7d5118e170202f887e9987"}
}

形容镜像的名称和 tag 以及 sha 值。

五、总结

明天咱们学习了 go-containerregistry 库中应用 crane 来进行容器镜像下载,将下载的镜像保留成 tar 包格局,并理解了镜像包的格局,以及外部的文件组织模式。

参考资料:

https://aliyun123.cn/2299.html

本文由博客一文多发平台 OpenWrite 公布!

退出移动版