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. lottie 动画在 vue 中的使用

    前言 最近我所负责的项目中,我采用了动画效果,并开始使用 gif 来实现.然而,在实践过程中,我发现 gif 格式的动画在 git 中出现了明显的锯齿感,这让我非常困扰.为了追求更完美的表现效果,我最 ...

  2. SpringBoot结合ajax实现登录功能

    1:ajax是什么(https://www.w3school.com.cn/ajax/ajax_intro.asp)? AJAX 是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术. AJA ...

  3. 调试分析Linux 0.00引导程序

    Bochs虚拟机的配置文件 简介 Bochs 虚拟机的配置文件 描述待启动的虚拟机的配置,例如内存大小.启动镜像.网络功能.存储配置. Bochs运行后,会先查找配置文件,解析模拟器要虚拟的系统相关信 ...

  4. MyBatis 的缓存处理

    作为常见的 ORM 框架,在使用 MyBatis 的过程中可以针对相关的查询进行缓存处理以提高查询的性能.本文将简要介绍一下 MyBatis 中默认的一级缓存和二级缓存,以及自定义缓存的处理 MyBa ...

  5. Feign源码解析5:loadbalancer

    背景 经过前面几篇的理解,我们大致梳理清楚了FeignClient的创建.Feign调用的大体流程,本篇会深入Feign调用中涉及的另一个重要组件:loadbalancer,了解loadbalance ...

  6. 快速入门Mybatis完成基本CURD(注解实现)

    一.什么是Mybatis? MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射. MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集. MyB ...

  7. SAM适配下游任务的探究:SAM Adapter

    本文分享自华为云社区<SAM适配下游任务的探究:SAM Adapter>,作者:Hint. 近期大模型的涌现给AI研究带来显著的发展,META的工作Segment Anything(SAM ...

  8. CSV:简单格式下隐藏的那些坑

    摘要:本文将盘点处理CSV数据时我遇到的一些坑. 本文分享自华为云社区<CSV-简单格式下隐藏的那些坑>,作者:aKi. 前言 CSV(Comma-Separated Values),是一 ...

  9. 聊聊Java的异常机制问题

    摘要:java异常指在程序运行时可能出现的一些错误,如:文件找不到.网络连接失败.非法参数等.异常是一个事件,它发生在程序运行期间,中断了正在执行的程序的正常指令流. 本文分享自华为云社区<Ja ...

  10. 认识Java的整形数据结构

    摘要:java中一切都是对象,为什么int不用创建对象实例化,而可以直接使用? 本文分享自华为云社区<[Java]对基本类型-整型数据结构的认识>,作者: huahua.Dr . 整型数据 ...