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. Mybatis-Flex之QueryWrapper

    1.完整DQL语句 /** * 使用QueryWrapper构建超复杂SQL语句 */ @Test public void testQueryWrapper1() { QueryWrapper wra ...

  2. 欧奈尔的RPS指标如何使用到股票预测

    前言 1988年,欧奈尔将他的投资理念写成了<笑傲股市How to Make Money in Stocks>.书中总结了选股模式CANSLIM模型,每一个字母都代表一种尚未发动大涨势的潜 ...

  3. postman——token传参

    问题描述: 有一个登陆接口获取token,其他接口再次访问都要带上token 解决方案: 1.在登陆接口访问后设置Postman的环境变量(Environment),例如设置环境变量名:token,值 ...

  4. Go 语言为什么建议多使用切片,少使用数组?

    大家好,我是 frank,「Golang 语言开发栈」公众号作者. 01 介绍 在 Go 语言中,数组固定长度,切片可变长度:数组和切片都是值传递,因为切片传递的是指针,所以切片也被称为"引 ...

  5. 27、flutter Dialog 弹窗

    AlertDialog //放在State<>之下 void _alertDialog() async { var result = await showDialog( barrierDi ...

  6. 资源成本降低70%!华为MetaERP资产核算的Serverless架构实践

    本文分享自华为云社区<资源成本降低70%!华为MetaERP资产核算的Serverless架构实践>,作者: 华为云PaaS服务小智. 资产核算是指在一定的财务周期,对企业拥有的房屋建筑物 ...

  7. 华为云GaussDB圈层活动走进香港,以技术创新构筑金融政企数智发展基石

    摘要:近日,华为云GaussDB圈层活动在中国·香港如期举办,活动聚集了22家香港金融政企客户和合作伙伴. 本文分享自华为云社区<华为云GaussDB圈层活动走进香港,赋能金融政企数字化转型&g ...

  8. 物联网常见协议之Amqp协议及使用场景解析

    摘要:本文围绕AMQP协议,为大家详细解析AMQP协议.核心技术亮点.多协议之间的对比以及使用实践. 本文分享自华为云社区<物联网常见协议之Amqp协议及使用场景解析>,作者:张俭. 引言 ...

  9. 聆听无声的话语:手把手教你用ModelArts实现手语识别

    摘要:ModelArts,化作我们与听力障碍之间的一座沟通桥梁. 据统计,我国有超过2000万人有听力语言障碍,每年有约3万名婴儿生来就失去了聆听的机会.或许是因为缺少与没有听力障碍的人交流的途径,环 ...

  10. Serverless时代的微服务开发指南:华为云提出七大实践新标准

    摘要:本文结合华为云在Serverless Microservice方面的实践,总结提炼出七大Serverless Microservice开发 "实践标准",为加速全域Serve ...