Go image registry
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
注意:
不能直接将 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
关于 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...)
这里省去了部分代码实现,重点关注:
- name.ParseReference 对 src(registry+RepoTag) 进行解析,并且以格式 name.StrictValidation 方式解析;
- remote.WithAuthFromKeychain 定义 client 和远端 registry 交互的认证方式。其中,认证方式添加到 remote.Option 作为 remote.Write 的入参实现认证;
- remote.Write 需要搭配 transport 包处理 the authentication handshake and structured errors.
2.3 附录
应用层上调用各种框架实现功能是在学,在用。这不是核心,要抓核心,抓主要矛盾,核心在于内部实现,过程,原理以及模式。image 数据是怎么传到 remote 的,中间经历了什么,代码是怎么实现的,本地 client 和远端是怎么交互的,这是内核,是要深挖的东西。这里只讲用,后续会深挖这方面内容,敬请期待。
Go image registry的更多相关文章
- 【java】Naming.bind和Registry.bind区别
Naming类和Registry类均在java.rmi包 Naming类通过解析URI绑定远程对象,将URI拆分成主机.端口和远程对象名称,使用的仍是Registry类. public static ...
- docker4dotnet #4 使用Azure云存储构建高速 Docker registry
使用Docker来构建应用程序最常见的操作就是 docker run 或者 docker pull了,但是由于众所周知的原因,在国内想要高速稳定的获取docker hub上面的资源并不是件容易的事情, ...
- StructureMap 代码分析之Widget 之Registry 分析 (1)
说句实话,本人基本上没用过Structuremap,但是这次居然开始看源码了,不得不为自己点个赞.Structuremap有很多的类,其中有一个叫做Widget的概念.那么什么是Widget呢?要明白 ...
- 安装 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 ...
- 部署私有Docker Registry和使用
环境 vmware虚拟机 Ip:192.168.190.139 Ip:192.168.190.140 Ip:192.168.0.122 registry Docker 1.12.2 Docker 版本 ...
- 【转】安装第三方库出现 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 内容如下. 然 ...
- Apache Kafka - Schema Registry
关于我们为什么需要Schema Registry? 参考, https://www.confluent.io/blog/how-i-learned-to-stop-worrying-and-love- ...
- Docker version 1.12.5建立registry私库
sudo docker run -d -p 5000:5000 -v /opt/data/registry:/var/lib/registry registry :前面的是宿主机的地址(/opt/da ...
- docker 使用非加密registry
配置docker成为服务,自启动 sudo systemctl enable docker.service 启动服务 sudo systemctl start docker docker默认要求我们使 ...
- 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/ ...
随机推荐
- NetSuite 开发日记:创建 Transfer(转账单)
经测试,截止到 2022.12.26,Transfer 只能使用 Client 脚本创建,使用服务端脚本创建报错:ReferenceError: "document" is not ...
- Sql整理
1:数据库 数据库是以某种有组织的方式存储的数据集合. 保存有组织数据的容器,通常是一个文件或者一组文件. SQL 是Structured Query Language (结构化查询语言)的缩写. 2 ...
- 我用 Laf 开发了一个非常好用的密码管理工具
[KeePass 密码管理]是一款简单.安全简洁的账号密码管理工具,服务端使用 Laf 云开发,支持指纹验证.FaceID,N 重安全保障,可以随时随地记录我的账号和密码. 写这个小程序之前,在国内市 ...
- 2023-05-30:Redis6.0为什么要引入多线程呢?
2023-05-30:Redis6.0为什么要引入多线程呢? 答案2023-05-30: Redis多线程比单线程性能提升一倍: Redis 6.0 引入多线程 IO 特性对性能提升至少是一倍以上.据 ...
- c#中用System.Diagnostics.Process.Start(Path.GetFullPath(“vlc.exe.lnk“), url);用vlc的快捷方式打开http的url不起作用?
vlc.exe.lnk双击这个文件,能正常打开vlc,但是用System.Diagnostics.Process.Start(Path.GetFullPath("vlc.exe.lnk&qu ...
- Flink实时处理入门
Flink实时处理入门 1.Flink框架介绍 Flink 诞生于欧洲的一个大数据研究项目 StratoSphere.它是由 3 所地处柏林的大学和欧洲其他一 些大学在 2010~2014 年共同进行 ...
- rasa train nlu详解:1.2-_train_graph()函数
本文使用<使用ResponseSelector实现校园招聘FAQ机器人>中的例子,主要详解介绍_train_graph()函数中变量的具体值. 一.rasa/model_trainin ...
- CUDA C编程权威指南:1.1-CUDA基础知识点梳理
主要整理了N多年前(2013年)学习CUDA的时候开始总结的知识点,好长时间不写CUDA代码了,现在LLM推理需要重新学习CUDA编程,看来出来混迟早要还的. 1.CUDA 解析:2007年,NV ...
- KubeCon China 2023 | 拥抱开源,华为云原生华彩绽放
本文分享自华为云社区<KubeCon China 2023 | 拥抱开源,华为云原生华彩绽放>,作者: 云容器大未来 . 2023 年度云原生全球旗舰盛会 KubeCon + CloudN ...
- 跨越全场景统一架构三大挑战,MindSpore亮出“四招”
摘要:本文重点剖析全场景统一的AI框架的挑战和MindSpore的解决思路. 2020年的最后一天,MindSpore发布了1.1版本,1.1中很重要的特性是构建了端边云全场景统一的基础架构: htt ...