0. 前言

OpenShift image registry 概述 介绍了 OpenShift 平台上 registry 的基本结构。进一步地,本文将介绍在 Kubernetes 平台上,如何使用 Go 实现 image 的 push 操作。

1. 本地 CLI push image

在本地将 image tar 包(image 的静态文件形式) push 到 registry:

// 将 repo image ubuntu 存储到本地
[root@chunqiu tarball]# docker images | grep ubuntu
ubuntu latest ba6acccedd29 2 months ago 72.8MB
[root@chunqiu tarball]# docker save ubuntu -o ubuntu:latest.tar
[root@chunqiu tarball]# ls
ubuntu:latest.tar // 删除仓库 image,重新上传本地 tar 到 repo
[root@chunqiu tarball]# docker rmi ubuntu
Untagged: ubuntu:latest
Untagged: ubuntu@sha256:626ffe58f6e7566e00254b638eb7e0f3b11d4da9675088f4781a50ae288f3322
Deleted: sha256:ba6acccedd2923aee4c2acc6a23780b14ed4b8a5fa4e14e252a23b846df9b6c1
Deleted: sha256:9f54eef412758095c8079ac465d494a2872e02e90bf1fb5f12a1641c0d1bb78b [root@chunqiu tarball]# docker images | grep ubuntu [root@chunqiu tarball]# docker load -i ubuntu\:latest.tar
9f54eef41275: Loading layer [==================================================>] 75.16MB/75.16MB
Loaded image: ubuntu:latest [root@chunqiu tarball]# docker images | grep ubuntu
ubuntu latest ba6acccedd29 2 months ago 72.8MB // 将 repo 的 image push 到 registry
// 提示 push 失败,是因为并未在 docker registry 认证
[root@chunqiu tarball]# docker push ubuntu:latest
The push refers to repository [docker.io/library/ubuntu]
9f54eef41275: Layer already exists
errors:
denied: requested access to the resource is denied
unauthorized: authentication required

注意:

  1. 不能直接将 tar 包 push 到 registry:

    [root@chunqiu tarball]# docker push ubuntu:latest.tar
    The push refers to repository [docker.io/library/ubuntu]
    An image does not exist locally with the tag: ubuntu
  2. 关于 registry,repo 的关系可看这段解释:

    Registries, Repositories, Images, and Tags
    
    There is a hierarchical system for storing images. The following terminology is used:
    
    Registry: A service responsible for hosting and distributing images. The default registry is the Docker Hub.
    
    Repository: A collection of related images (usually providing different versions of the same application or service).

2. Go push image

过了上节的流程,再看 Go 中是怎么 push image 到 repo 的。

2.1 tarball

首先用 tarball 将本地 tar 包转为 v1.Image,然后对 v1.Image 进行操作,这里举个例子,将本地 tar 包重新转换成不同 tag:

func main() {
tag, err := name.NewTag("ubuntu")
if err != nil {
panic(err)
} downloadPath := fmt.Sprintf("/home/hxia/vsWorkspace/studyGo/lib/tarball/ubuntu:latest.tar")
img, err := tarball.ImageFromPath(downloadPath, &tag)
if err != nil {
panic(err)
} // Write that tarball with a different tag.
newTag, err := name.NewTag("ubuntu:newest")
if err != nil {
panic(err)
}
f, err := os.Create("chunqiu")
if err != nil {
panic(err)
}
defer f.Close() if err := tarball.Write(newTag, img, f); err != nil {
panic(err)
}
}

运行上述代码,发现本地路径生成名为 chunqiu 的 tar 包,将该包 load 到 repo 发现 tag 转换为 newest:

[root@chunqiu tarball]# go run main.go
[root@chunqiu tarball]# ls
chunqiu go.mod go.sum main.go ubuntu:latest.tar [root@chunqiu tarball]# docker load -i chunqiu
9f54eef41275: Loading layer [==================================================>] 31.8MB/31.8MB
Loaded image: ubuntu:newest [root@chunqiu tarball]# docker images | grep ubuntu
ubuntu newest ba6acccedd29 2 months ago 72.8MB

2.2 remote push image

将 image push 到远端 registry,需要用到 go-containerregistry ,它是对容器 registries 处理的 golang 包实现。

代码实现如下:

import (
"github.com/google/go-containerregistry/pkg/name"
"github.com/google/go-containerregistry/pkg/v1/remote"
"github.com/google/go-containerregistry/pkg/v1/remote/transport"
) ref, err := name.ParseReference(src, name.StrictValidation)
if err != nil {
return err
} options := make([]remote.Option, 0)
options = append(options, remote.WithAuthFromKeychain(authn.DefaultKeychain)) if auth != nil {
options = append(options, remote.WithAuth(auth))
} trs, err := transport.New(ref.Context().Registry, auth, &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}, nil)
if err != nil {
return err
}
options = append(options, remote.WithTransport(trs)) return remote.Write(ref, img, options...)

这里省去了部分代码实现,重点关注:

  1. name.ParseReference 对 src(registry+RepoTag) 进行解析,并且以格式 name.StrictValidation 方式解析;
  2. remote.WithAuthFromKeychain 定义 client 和远端 registry 交互的认证方式。其中,认证方式添加到 remote.Option 作为 remote.Write 的入参实现认证;
  3. remote.Write 需要搭配 transport 包处理 the authentication handshake and structured errors.

2.3 附录

应用层上调用各种框架实现功能是在学,在用。这不是核心,要抓核心,抓主要矛盾,核心在于内部实现,过程,原理以及模式。image 数据是怎么传到 remote 的,中间经历了什么,代码是怎么实现的,本地 client 和远端是怎么交互的,这是内核,是要深挖的东西。这里只讲用,后续会深挖这方面内容,敬请期待。


Go image registry的更多相关文章

  1. 【java】Naming.bind和Registry.bind区别

    Naming类和Registry类均在java.rmi包 Naming类通过解析URI绑定远程对象,将URI拆分成主机.端口和远程对象名称,使用的仍是Registry类. public static ...

  2. docker4dotnet #4 使用Azure云存储构建高速 Docker registry

    使用Docker来构建应用程序最常见的操作就是 docker run 或者 docker pull了,但是由于众所周知的原因,在国内想要高速稳定的获取docker hub上面的资源并不是件容易的事情, ...

  3. StructureMap 代码分析之Widget 之Registry 分析 (1)

    说句实话,本人基本上没用过Structuremap,但是这次居然开始看源码了,不得不为自己点个赞.Structuremap有很多的类,其中有一个叫做Widget的概念.那么什么是Widget呢?要明白 ...

  4. 安装 pywin32-218.win32-py2.7.exe 报错python version 2.7 required,which was not found in the registry解决方案

    随便在一个盘下 新建register.py的文件,内容如下: #   # script to register Python 2.0 or later for use with win32all    ...

  5. 部署私有Docker Registry和使用

    环境 vmware虚拟机 Ip:192.168.190.139 Ip:192.168.190.140 Ip:192.168.0.122 registry Docker 1.12.2 Docker 版本 ...

  6. 【转】安装第三方库出现 Python version 2.7 required, which was not found in the registry

    安装第三方库出现 Python version 2.7 required, which was not found in the registry 建立一个文件 register.py 内容如下. 然 ...

  7. Apache Kafka - Schema Registry

    关于我们为什么需要Schema Registry? 参考, https://www.confluent.io/blog/how-i-learned-to-stop-worrying-and-love- ...

  8. Docker version 1.12.5建立registry私库

    sudo docker run -d -p 5000:5000 -v /opt/data/registry:/var/lib/registry registry :前面的是宿主机的地址(/opt/da ...

  9. docker 使用非加密registry

    配置docker成为服务,自启动 sudo systemctl enable docker.service 启动服务 sudo systemctl start docker docker默认要求我们使 ...

  10. System.UnauthorizedAccessException Access to the path "/etc/mono/registry" is denied.

    sudo mkdir /etc/mono/registry sudo mkdir /etc/mono/registry/LocalMachine sudo chmod g+rwx /etc/mono/ ...

随机推荐

  1. 【笔记整理】忽略https证书校验

    import requests url = "https://sam.huat.edu.cn:8443/selfservice/" # 默认不忽略ssl证书,如果有证书问题的网站会 ...

  2. MySQL 数据目录

    MySQL 的数据目录 1. MySQL 的主要目录结构 方式1:通过命令搜索 find / -name mysql 方式2(推荐):通过查看配置文件获取目录结构 vim /etc/my.cnf (重 ...

  3. ElasticSearch之cat fielddata API

    命令样例如下: curl -X GET "https://localhost:9200/_cat/fielddata?v=true&pretty" --cacert $ES ...

  4. Java注解,看完就会用

    一.什么是注解 定义:注解(Annotation),也叫元数据.一种代码级别的说明. 它是JDK1.5及以后版本引入的一个特性,与类.接口.枚举是在同一个层次. 它可以声明在包.类.字段.方法.局部变 ...

  5. 合宙esp32 c3 micro python 固件配置(基于thonny)

    首先,本文档是已经配置过其他esp32后发现合宙的配置需要修改一些地方. 为了让新手们减少掉坑成本,故做了一个图文指导. 准备工作: 1.thonny安装(不讲,自己去查教程) 2.esp32c3 m ...

  6. 高版本jdk的访问私有成员属性的正确姿势

    在jdk17+已经不能直接通过 setAccessible 来访问私有属性了 Field name = access.getClass().getDeclaredField("name&qu ...

  7. AI 图像自动补全 Uncrop 工具介绍

    ClipDrop Uncrop是一款基于AI的图像自动补全工具,由StabilityAI旗下的Clipdrop开发.通过利用StableDiffusionXL开发的算法和深度学习技术,Uncrop可以 ...

  8. 自动调优工具AOE,让你的模型在昇腾平台上高效运行

    摘要:当算子性能或者网络性能不佳时,可以使用AOE进行调优.本文就带大家了解自动调优工具AOE,让你的模型在昇腾平台上高效运行. 本文分享自华为云社区<自动调优工具AOE,让你的模型在昇腾平台上 ...

  9. TypeScript里string和String,真不是仅仅是大小写的区别

    摘要:通常来说,string表示原生类型,而String表示对象. 本文分享自华为云社区<TypeScript里string和String的区别>,作者:gentle_zhou . 背景 ...

  10. 近数据处理(NDP)——GaussDB(for MySQL)性能提升的秘密

    摘要:云堆栈的深度集成是释放云数据库力量的关键,华为云在实现这一目标方面处于领先地位,正如GaussDB(for MySQL)所证明的那样. 本文分享自华为云社区<近数据处理(NDP),为Gau ...