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旨在通过蓝牙连接传输高质量的立体声音…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
蓝桥杯3498 01串的熵
问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798, 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...
Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
【Go语言基础【12】】指针:声明、取地址、解引用
文章目录 零、概述:指针 vs. 引用(类比其他语言)一、指针基础概念二、指针声明与初始化三、指针操作符1. &:取地址(拿到内存地址)2. *:解引用(拿到值) 四、空指针&am…...
接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...
使用SSE解决获取状态不一致问题
使用SSE解决获取状态不一致问题 1. 问题描述2. SSE介绍2.1 SSE 的工作原理2.2 SSE 的事件格式规范2.3 SSE与其他技术对比2.4 SSE 的优缺点 3. 实战代码 1. 问题描述 目前做的一个功能是上传多个文件,这个上传文件是整体功能的一部分,文件在上传的过程中…...
《Offer来了:Java面试核心知识点精讲》大纲
文章目录 一、《Offer来了:Java面试核心知识点精讲》的典型大纲框架Java基础并发编程JVM原理数据库与缓存分布式架构系统设计二、《Offer来了:Java面试核心知识点精讲(原理篇)》技术文章大纲核心主题:Java基础原理与面试高频考点Java虚拟机(JVM)原理Java并发编程原理Jav…...
Linux操作系统共享Windows操作系统的文件
目录 一、共享文件 二、挂载 一、共享文件 点击虚拟机选项-设置 点击选项,设置文件夹共享为总是启用,点击添加,可添加需要共享的文件夹 查询是否共享成功 ls /mnt/hgfs 如果显示Download(这是我共享的文件夹)&…...
MeanFlow:何凯明新作,单步去噪图像生成新SOTA
1.简介 这篇文章介绍了一种名为MeanFlow的新型生成模型框架,旨在通过单步生成过程高效地将先验分布转换为数据分布。文章的核心创新在于引入了平均速度的概念,这一概念的引入使得模型能够通过单次函数评估完成从先验分布到数据分布的转换,显…...
