• 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-containerregistry/blob/main/cmd/crane/doc/crane.md

    在go-containerregistry的crane的文档目录中,有crane的详细文档。

    2)crane命令

    对于容器镜像下载功能来说,就是执行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
    

    file

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

    4) repositories文件

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

    描述镜像的名称和tag以及sha值。

    五、总结

    今天我们学习了go-containerregistry库中使用crane来进行容器镜像下载,将下载的镜像保存成tar包格式,并了解了镜像包的格式,以及内部的文件组织形式。

    参考资料:

    https://aliyun123.cn/2299.html

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

  • 相关阅读:
    信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言—— 1057:简单计算器
    信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言—— 1061:求整数的和与均值
    信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言—— 1061:求整数的和与均值
    信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言—— 1061:求整数的和与均值
    信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言—— 1060:均值
    信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言—— 1060:均值
    信息学奥赛一本通(C++)在线评测系统——基础(一)C++语言—— 1060:均值
    如何绕过Windows Server 2008 R2上的身份验证
    如何绕过Windows Server 2008 R2上的身份验证
    SQLServer中创建主键的方法
  • 原文地址:https://www.cnblogs.com/codergeek/p/15967758.html
Copyright © 2020-2023  润新知