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/ ...
随机推荐
- 【笔记整理】忽略https证书校验
import requests url = "https://sam.huat.edu.cn:8443/selfservice/" # 默认不忽略ssl证书,如果有证书问题的网站会 ...
- MySQL 数据目录
MySQL 的数据目录 1. MySQL 的主要目录结构 方式1:通过命令搜索 find / -name mysql 方式2(推荐):通过查看配置文件获取目录结构 vim /etc/my.cnf (重 ...
- ElasticSearch之cat fielddata API
命令样例如下: curl -X GET "https://localhost:9200/_cat/fielddata?v=true&pretty" --cacert $ES ...
- Java注解,看完就会用
一.什么是注解 定义:注解(Annotation),也叫元数据.一种代码级别的说明. 它是JDK1.5及以后版本引入的一个特性,与类.接口.枚举是在同一个层次. 它可以声明在包.类.字段.方法.局部变 ...
- 合宙esp32 c3 micro python 固件配置(基于thonny)
首先,本文档是已经配置过其他esp32后发现合宙的配置需要修改一些地方. 为了让新手们减少掉坑成本,故做了一个图文指导. 准备工作: 1.thonny安装(不讲,自己去查教程) 2.esp32c3 m ...
- 高版本jdk的访问私有成员属性的正确姿势
在jdk17+已经不能直接通过 setAccessible 来访问私有属性了 Field name = access.getClass().getDeclaredField("name&qu ...
- AI 图像自动补全 Uncrop 工具介绍
ClipDrop Uncrop是一款基于AI的图像自动补全工具,由StabilityAI旗下的Clipdrop开发.通过利用StableDiffusionXL开发的算法和深度学习技术,Uncrop可以 ...
- 自动调优工具AOE,让你的模型在昇腾平台上高效运行
摘要:当算子性能或者网络性能不佳时,可以使用AOE进行调优.本文就带大家了解自动调优工具AOE,让你的模型在昇腾平台上高效运行. 本文分享自华为云社区<自动调优工具AOE,让你的模型在昇腾平台上 ...
- TypeScript里string和String,真不是仅仅是大小写的区别
摘要:通常来说,string表示原生类型,而String表示对象. 本文分享自华为云社区<TypeScript里string和String的区别>,作者:gentle_zhou . 背景 ...
- 近数据处理(NDP)——GaussDB(for MySQL)性能提升的秘密
摘要:云堆栈的深度集成是释放云数据库力量的关键,华为云在实现这一目标方面处于领先地位,正如GaussDB(for MySQL)所证明的那样. 本文分享自华为云社区<近数据处理(NDP),为Gau ...