aws ecr 使用golang实现的简单镜像转换工具
https://pkg.go.dev/github.com/docker/docker/client#section-readme
通过golang实现一个简单的镜像下载工具
总体步骤
- 启动一台海外区域的ec2实例
- 安装docker和awscli
- 配置凭证访问国内ecr仓库
- 编写web服务实现镜像转换和自动推送
安装docker和awscli
sudo yum remove awscli -y
sudo yum install less -y
sudo yum install unzip -y
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install --update
complete -C '/usr/local/bin/aws_completer' aws
sudo yum install docker -y
sudo systemctl start docker
sudo systemctl enable docker
sudo groupadd docker
sudo usermod -aG docker ec2-user
配置ecr凭证助手
https://github.com/awslabs/amazon-ecr-credential-helper
sudo yum install amazon-ecr-credential-helper
vim ~/.docker/config.json
{"credsStore": "ecr-login"
}
或者手动临时配置凭证
aws ecr get-login-password --region cn-north-1 | docker login --username AWS --password-stdin xxxxxx.dkr.ecr.cn-north-1.amazonaws.com.cn
编写web服务
使用golang原生的http包实现,比较简单粗糙,测试用的话足够了
前端页面

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>ToImage</title><style>* {margin: 0;padding: 0;}.container {height: 300px;width: 100%;margin: 100px auto 0 auto;}.parent {position: relative;top: 50%;left: 30%;}.search {width: 650px;height: 50px;border-radius: 18px;outline: none;border: 1px solid #ccc;padding-left: 20px;padding-right: 100px;position: absolute;font-size: 20px;}.btn {height: 36px;width: 100px;position: absolute;background: #fff;top: 6px;left: 650px;border: none;outline: none;font-size: 20px;}</style>
</head><body><div class="container"><form class="parent" method="get" action="/myrepo"><input type="text" class="search" placeholder="Please Input..." name="iamgename" /><input type="submit" class="btn" value="Search" /></form></div>
</body></html>
后端服务
package mainimport ("context""fmt""io""log""net/http""os/exec""strings""text/template""github.com/aws/aws-sdk-go/aws""github.com/aws/aws-sdk-go/aws/awserr""github.com/aws/aws-sdk-go/aws/session""github.com/aws/aws-sdk-go/service/ecr""github.com/aws/aws-sdk-go/service/sts""github.com/docker/docker/api/types""github.com/docker/docker/client"
)func main() {http.HandleFunc("/", index)http.HandleFunc("/myrepo", myrepo)log.Println("The server is listening on 0.0.0.0:8089")http.ListenAndServe(":8089", nil)
}
func index(w http.ResponseWriter, r *http.Request) {t, _ := template.ParseFiles("index.html")t.Execute(w, "hi")
}
func myrepo(w http.ResponseWriter, r *http.Request) {imagename := r.URL.Query().Get("iamgename")if imagename == "" {fmt.Fprintln(w, "Please input image name and tag")return}// imagename := "public.ecr.aws/docker/library/busybox:uclibc"// get account idstssvc := sts.New(session.New(), aws.NewConfig().WithRegion("cn-north-1"))input := &sts.GetCallerIdentityInput{}stsresult, err := stssvc.GetCallerIdentity(input)if err != nil {fmt.Fprintln(w, "Can not get account id")log.Println("Can not get account id")return}accountid := *stsresult.Accountlog.Println("Your account is", accountid)ctx := context.Background()cli, err := client.NewClientWithOpts(client.WithVersion("1.41"))if err != nil {fmt.Fprintln(w, "Unable to create docker client")fmt.Println("Unable to create docker client")return}// list imagesimages, err := cli.ImageList(ctx, types.ImageListOptions{})if err != nil {fmt.Fprintln(w, "Unable to list images")return}for _, image := range images {if imagename == image.RepoTags[0] {fmt.Fprintln(w, "The image has existed on the host!")fmt.Fprintln(w, "The image name is", imagename)}}// pull imagepullReader, err := cli.ImagePull(ctx, imagename, types.ImagePullOptions{})if err != nil {panic(err)}defer pullReader.Close()io.Copy(w, pullReader)//tag imagearr := strings.Split(imagename, "/")arrlen := len(arr)tempstr := arr[arrlen-1]split := strings.Split(tempstr, ":")splen := len(split)var tag stringvar shortname stringif splen == 2 {shortname = split[0]tag = split[1]} else {shortname = split[0]tag = "latest"}tagimage := accountid + ".dkr.ecr.cn-north-1.amazonaws.com.cn/" + shortname + ":" + taglog.Println("The image name is", tagimage)cli.ImageTag(ctx, imagename, tagimage)// create repomySession := session.Must(session.NewSession())ecrsvc := ecr.New(mySession, aws.NewConfig().WithRegion("cn-north-1"))ecrinput := &ecr.CreateRepositoryInput{RepositoryName: aws.String(shortname),}ecrresult, err := ecrsvc.CreateRepository(ecrinput)if err != nil {if aerr, ok := err.(awserr.Error); ok {switch aerr.Code() {case ecr.ErrCodeRepositoryAlreadyExistsException:log.Println(ecr.ErrCodeRepositoryAlreadyExistsException, aerr.Error())default:log.Println(aerr.Error())}} else {log.Println(err.Error())}} else {log.Println("Success creating repo", ecrresult.Repository.RepositoryArn)}log.Println("The repo name is", accountid+".dkr.ecr.cn-north-1.amazonaws.com.cn/"+shortname)// push image// cmd := exec.Command("docker", "push", tagimage)cmd := exec.Command("docker", "push", tagimage)cmdout, cmderr := cmd.CombinedOutput()if cmderr != nil {fmt.Fprint(w, cmderr.Error())log.Printf("docker push failed with %s\n", cmderr)return}fmt.Fprint(w, string(cmdout))// log.Println(string(cmdout))// remove image_, removeerr := cli.ImageRemove(ctx, tagimage, types.ImageRemoveOptions{})if removeerr != nil {log.Println("Failed to remover image", err)}// return infofmt.Fprintln(w, "The image is successful pushed!")fmt.Fprintln(w, "The image name is", tagimage)fmt.Fprintln(w, "login with")fmt.Fprintf(w, "aws ecr get-login-password --region cn-north-1 | docker login --username AWS --password-stdin %s.dkr.ecr.cn-north-1.amazonaws.com.cn", accountid)
}
测试推送镜像,推送到默认凭证所在的账号下,可以通过sts查看
{"status":"Pulling from bitnami/envoy","id":"latest"}
{"status":"Digest: sha256:1848240b060c9bad9c34f76fc87830da317628e6f7809aede6e634afa74913dd"}
{"status":"Status: Image is up to date for public.ecr.aws/bitnami/envoy:latest"}
The push refers to repository [xxxxxxxxx.dkr.ecr.cn-north-1.amazonaws.com.cn/envoy]
afe7743db796: Preparing
afe7743db796: Pushed
latest: digest: sha256:d5199964f061f4c28606f3bc8d867b12cdbb5e67af9a58821a9dacf2abd903d8 size: 529
The image is successful pushed!
The image name is xxxxxxxxx.dkr.ecr.cn-north-1.amazonaws.com.cn/envoy:latest
login with
aws ecr get-login-password --region cn-north-1 | docker login --username AWS --password-stdin xxxxxxxxx.dkr.ecr.cn-north-1.amazonaws.com.cn
相关文章:
aws ecr 使用golang实现的简单镜像转换工具
https://pkg.go.dev/github.com/docker/docker/client#section-readme 通过golang实现一个简单的镜像下载工具 总体步骤 启动一台海外区域的ec2实例安装docker和awscli配置凭证访问国内ecr仓库编写web服务实现镜像转换和自动推送 安装docker和awscli sudo yum remove awsc…...
【20230225】【剑指1】分治算法(中等)
1.重建二叉树class Solution { public:TreeNode* traversal(vector<int>& preorder,vector<int>& inorder){if(preorder.size()0) return NULL;int rootValuepreorder.front();TreeNode* rootnew TreeNode(rootValue);//int rootValuepreorder[0];if(preo…...
「JVM 高效并发」Java 线程
进程是资源分配(内存地址、文件 I/O 等)的基本单位,线程是执行调度(处理器资源调度)的基本单位; Loom 项目若成功为 Java 引入纤程(Fiber),则线程的执行调度单位可能变为…...
ADAS-可见光相机之Cmos Image Sensor
引言 “ 可见光相机在日常生活、工业生产、智能制造等应用有着重要的作用。在ADAS中更是扮演着重要的角色,如tesla model系列全车身10多个相机,不断感知周围世界。本文着重讲解下可见光相机中的CIS(CMOS Image Sensor)。” 定义 光是一种电磁波&…...
【ESP 保姆级教程】玩转emqx MQTT篇③ ——封装 EmqxIoTSDK,快速在项目集成
忘记过去,超越自己 ❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️❤️ 本篇创建记录 2023-02-26 ❤️❤️ 本篇更新记录 2023-02-26 ❤️🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言📝🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请…...
Python自动化测试面试题-编程篇
前言 随着行业的发展,编程能力逐渐成为软件测试从业人员的一项基本能力。因此在笔试和面试中常常会有一定量的编码题,主要考察以下几点。 基本编码能力及思维逻辑基本数据结构(顺序表、链表、队列、栈、二叉树)基本算法…...
CIT 594 Module 7 Programming AssignmentCSV Slicer
CIT 594 Module 7 Programming Assignment CSV Slicer In this assignment you will read files in a format known as “comma separated values” (CSV), interpret the formatting and output the content in the structure represented by the file. Q1703105484 Learning …...
链路追踪——【Brave】第一遍小结
前言 微服务链路追踪系列博客,后续可能会涉及到Brave、Zipkin、Sleuth内容的梳理。 Brave 何为Brave? github地址:https://github.com/openzipkin/brave Brave是一个分布式追踪埋点库。 #mermaid-svg-riwF9nbu1AldDJ7P {font-family:"…...
Vision Transformer(ViT)
1. 概述 Transformer[1]是Google在2017年提出的一种Seq2Seq结构的语言模型,在Transformer中首次使用Self-Atttention机制完全代替了基于RNN的模型结构,使得模型可以并行化训练,同时解决了在基于RNN模型中出现了长距离依赖问题,因…...
104-JVM优化
JVM优化为什么要学习JVM优化: 1:深入地理解 Java 这门语言 我们常用的布尔型 Boolean,我们都知道它有两个值,true 和 false,但你们知道其实在运行时,Java 虚拟机是 没有布尔型 Boolean 这种类型的&#x…...
QML 颜色表示法
作者: 一去、二三里 个人微信号: iwaleon 微信公众号: 高效程序员 如果你经常需要美化样式(最常见的有:文本色、背景色、边框色、阴影色等),那一定离不开颜色。而在 QML 中,颜色的表示方法有多种:颜色名、十六进制颜色值、颜色相关的函数,一起来学习一下吧。 老规矩…...
基础数据结构--线段树(Python版本)
文章目录前言特点操作数据存储updateLazy下移查询实现前言 月末了,划个水,赶一下指标(更新一些活跃值,狗头) 本文主要是关于线段树的内容。这个线段树的话,主要是适合求解我们一个数组的一些区间的问题&am…...
【micropython】SPI触摸屏开发
背景:最近买了几块ESP32模块,看了下mircopython支持还不错,所以买了个SPI触摸屏试试水,记录一下使用过程。硬件相关:SPI触摸屏使用2.4寸屏幕,常见淘宝均可买到,驱动为ILI9341,具体参…...
【云原生】k8s中Pod进阶资源限制与探针
一、Pod 进阶 1、资源限制 当定义 Pod 时可以选择性地为每个容器设定所需要的资源数量。 最常见的可设定资源是 CPU 和内存大小,以及其他类型的资源。 当为 Pod 中的容器指定了 request 资源时,调度器就使用该信息来决定将 Pod 调度到哪个节点上。当还…...
AI - stable-diffusion(AI绘画)的搭建与使用
最近 AI 火的一塌糊涂,除了 ChatGPT 以外,AI 绘画领域也有很大的进步,以下几张图片都是 AI 绘制的,你能看出来么? 一、环境搭建 上面的效果图其实是使用了开源的 AI 绘画项目 stable-diffusion 绘制的,这是…...
应用场景五: 西门子PLC通过Modbus协议连接DCS系统
应用描述: 西门子PLC(S7200/300/400/200SMART)通过桥接器可以支持ModbusRTU串口和ModbusTCP以太网(有线和无线WIFI同时支持)两种通讯方式连接DCS系统,不需要编程PLC通讯程序,直接在模块中进行地…...
我继续问了ChatGPT关于SAP顾问职业发展前景的问题,大家感受一下
目录 SAP 顾问 跟其他IT工作收入情况相比是怎么样的? 如何成为SAP FICO 优秀的顾问 要想成为SAP FICO 优秀的顾问 ,需要ABA开发技能吗 SAP 顾问中哪个类型收入最多? 中国的ERP软件能够取代SAP吗? 今天我继续撩 ChatGPT。随便问…...
Python小白入门---00开篇介绍(简单了解一下)
Python 小白入门 系列教程 第一部分:Python 基础 介绍 Python 编程语言安装 Python 环境变量和数据类型运算符和表达式控制流程语句函数和模块异常处理 第二部分:Python 标准库和常用模块 Python 标准库简介文本处理和正则表达式文件操作和目录操作时…...
【算法基础】C++STL容器
一、Vector 1. 初始化(定义) (1)vector最基本的初始化: vector <int> a;(2)定义长度为10的vector: vector <int> a(10);(3)定义长度为10的vector,并且把所有元素都初始化为-3: vector <int...
【经典蓝牙】蓝牙 A2DP协议分析
A2DP 介绍 A2DP(Advanced Audio Distribution Profile)是蓝牙高音质音频传输协议, 用于传输单声道, 双声道音乐(一般在 A2DP 中用于 stereo 双声道) , 典型应用为蓝牙耳机。 A2DP旨在通过蓝牙连接传输高质量的立体声音…...
JVM垃圾回收机制全解析
Java虚拟机(JVM)中的垃圾收集器(Garbage Collector,简称GC)是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象,从而释放内存空间,避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的----NTFS源代码分析--重要
根目录0xa0属性对应的Ntfs!_SCB中的FileObject是什么时候被建立的 第一部分: 0: kd> g Breakpoint 9 hit Ntfs!ReadIndexBuffer: f7173886 55 push ebp 0: kd> kc # 00 Ntfs!ReadIndexBuffer 01 Ntfs!FindFirstIndexEntry 02 Ntfs!NtfsUpda…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...
xmind转换为markdown
文章目录 解锁思维导图新姿势:将XMind转为结构化Markdown 一、认识Xmind结构二、核心转换流程详解1.解压XMind文件(ZIP处理)2.解析JSON数据结构3:递归转换树形结构4:Markdown层级生成逻辑 三、完整代码 解锁思维导图新…...
算术操作符与类型转换:从基础到精通
目录 前言:从基础到实践——探索运算符与类型转换的奥秘 算术操作符超级详解 算术操作符:、-、*、/、% 赋值操作符:和复合赋值 单⽬操作符:、--、、- 前言:从基础到实践——探索运算符与类型转换的奥秘 在先前的文…...
针对药品仓库的效期管理问题,如何利用WMS系统“破局”
案例: 某医药分销企业,主要经营各类药品的批发与零售。由于药品的特殊性,效期管理至关重要,但该企业一直面临效期问题的困扰。在未使用WMS系统之前,其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...
多元隐函数 偏导公式
我们来推导隐函数 z z ( x , y ) z z(x, y) zz(x,y) 的偏导公式,给定一个隐函数关系: F ( x , y , z ( x , y ) ) 0 F(x, y, z(x, y)) 0 F(x,y,z(x,y))0 🧠 目标: 求 ∂ z ∂ x \frac{\partial z}{\partial x} ∂x∂z、 …...
