当前位置: 首页 > news >正文

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 线程

进程是资源分配&#xff08;内存地址、文件 I/O 等&#xff09;的基本单位&#xff0c;线程是执行调度&#xff08;处理器资源调度&#xff09;的基本单位&#xff1b; Loom 项目若成功为 Java 引入纤程&#xff08;Fiber&#xff09;&#xff0c;则线程的执行调度单位可能变为…...

ADAS-可见光相机之Cmos Image Sensor

引言 “ 可见光相机在日常生活、工业生产、智能制造等应用有着重要的作用。在ADAS中更是扮演着重要的角色&#xff0c;如tesla model系列全车身10多个相机&#xff0c;不断感知周围世界。本文着重讲解下可见光相机中的CIS(CMOS Image Sensor)。” 定义 光是一种电磁波&…...

【ESP 保姆级教程】玩转emqx MQTT篇③ ——封装 EmqxIoTSDK,快速在项目集成

忘记过去,超越自己 ❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️❤️ 本篇创建记录 2023-02-26 ❤️❤️ 本篇更新记录 2023-02-26 ❤️🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言📝🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请…...

Python自动化测试面试题-编程篇

前言 随着行业的发展&#xff0c;编程能力逐渐成为软件测试从业人员的一项基本能力。因此在笔试和面试中常常会有一定量的编码题&#xff0c;主要考察以下几点。 基本编码能力及思维逻辑基本数据结构&#xff08;顺序表、链表、队列、栈、二叉树&#xff09;基本算法&#xf…...

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】第一遍小结

前言 微服务链路追踪系列博客&#xff0c;后续可能会涉及到Brave、Zipkin、Sleuth内容的梳理。 Brave 何为Brave&#xff1f; github地址&#xff1a;https://github.com/openzipkin/brave Brave是一个分布式追踪埋点库。 #mermaid-svg-riwF9nbu1AldDJ7P {font-family:"…...

Vision Transformer(ViT)

1. 概述 Transformer[1]是Google在2017年提出的一种Seq2Seq结构的语言模型&#xff0c;在Transformer中首次使用Self-Atttention机制完全代替了基于RNN的模型结构&#xff0c;使得模型可以并行化训练&#xff0c;同时解决了在基于RNN模型中出现了长距离依赖问题&#xff0c;因…...

104-JVM优化

JVM优化为什么要学习JVM优化&#xff1a; 1&#xff1a;深入地理解 Java 这门语言 我们常用的布尔型 Boolean&#xff0c;我们都知道它有两个值&#xff0c;true 和 false&#xff0c;但你们知道其实在运行时&#xff0c;Java 虚拟机是 没有布尔型 Boolean 这种类型的&#x…...

QML 颜色表示法

作者: 一去、二三里 个人微信号: iwaleon 微信公众号: 高效程序员 如果你经常需要美化样式(最常见的有:文本色、背景色、边框色、阴影色等),那一定离不开颜色。而在 QML 中,颜色的表示方法有多种:颜色名、十六进制颜色值、颜色相关的函数,一起来学习一下吧。 老规矩…...

基础数据结构--线段树(Python版本)

文章目录前言特点操作数据存储updateLazy下移查询实现前言 月末了&#xff0c;划个水&#xff0c;赶一下指标&#xff08;更新一些活跃值&#xff0c;狗头&#xff09; 本文主要是关于线段树的内容。这个线段树的话&#xff0c;主要是适合求解我们一个数组的一些区间的问题&am…...

【micropython】SPI触摸屏开发

背景&#xff1a;最近买了几块ESP32模块&#xff0c;看了下mircopython支持还不错&#xff0c;所以买了个SPI触摸屏试试水&#xff0c;记录一下使用过程。硬件相关&#xff1a;SPI触摸屏使用2.4寸屏幕&#xff0c;常见淘宝均可买到&#xff0c;驱动为ILI9341&#xff0c;具体参…...

【云原生】k8s中Pod进阶资源限制与探针

一、Pod 进阶 1、资源限制 当定义 Pod 时可以选择性地为每个容器设定所需要的资源数量。 最常见的可设定资源是 CPU 和内存大小&#xff0c;以及其他类型的资源。 当为 Pod 中的容器指定了 request 资源时&#xff0c;调度器就使用该信息来决定将 Pod 调度到哪个节点上。当还…...

AI - stable-diffusion(AI绘画)的搭建与使用

最近 AI 火的一塌糊涂&#xff0c;除了 ChatGPT 以外&#xff0c;AI 绘画领域也有很大的进步&#xff0c;以下几张图片都是 AI 绘制的&#xff0c;你能看出来么&#xff1f; 一、环境搭建 上面的效果图其实是使用了开源的 AI 绘画项目 stable-diffusion 绘制的&#xff0c;这是…...

应用场景五: 西门子PLC通过Modbus协议连接DCS系统

应用描述&#xff1a; 西门子PLC&#xff08;S7200/300/400/200SMART&#xff09;通过桥接器可以支持ModbusRTU串口和ModbusTCP以太网&#xff08;有线和无线WIFI同时支持&#xff09;两种通讯方式连接DCS系统&#xff0c;不需要编程PLC通讯程序&#xff0c;直接在模块中进行地…...

我继续问了ChatGPT关于SAP顾问职业发展前景的问题,大家感受一下

目录 SAP 顾问 跟其他IT工作收入情况相比是怎么样的&#xff1f; 如何成为SAP FICO 优秀的顾问 要想成为SAP FICO 优秀的顾问 &#xff0c;需要ABA开发技能吗 SAP 顾问中哪个类型收入最多&#xff1f; 中国的ERP软件能够取代SAP吗&#xff1f; 今天我继续撩 ChatGPT。随便问…...

Python小白入门---00开篇介绍(简单了解一下)

Python 小白入门 系列教程 第一部分&#xff1a;Python 基础 介绍 Python 编程语言安装 Python 环境变量和数据类型运算符和表达式控制流程语句函数和模块异常处理 第二部分&#xff1a;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)是蓝牙高音质音频传输协议&#xff0c; 用于传输单声道&#xff0c; 双声道音乐&#xff08;一般在 A2DP 中用于 stereo 双声道&#xff09; &#xff0c; 典型应用为蓝牙耳机。 A2DP旨在通过蓝牙连接传输高质量的立体声音…...

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...

内存分配函数malloc kmalloc vmalloc

内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

从零实现富文本编辑器#5-编辑器选区模型的状态结构表达

先前我们总结了浏览器选区模型的交互策略&#xff0c;并且实现了基本的选区操作&#xff0c;还调研了自绘选区的实现。那么相对的&#xff0c;我们还需要设计编辑器的选区表达&#xff0c;也可以称为模型选区。编辑器中应用变更时的操作范围&#xff0c;就是以模型选区为基准来…...

五年级数学知识边界总结思考-下册

目录 一、背景二、过程1.观察物体小学五年级下册“观察物体”知识点详解&#xff1a;由来、作用与意义**一、知识点核心内容****二、知识点的由来&#xff1a;从生活实践到数学抽象****三、知识的作用&#xff1a;解决实际问题的工具****四、学习的意义&#xff1a;培养核心素养…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

PHP 8.5 即将发布:管道操作符、强力调试

前不久&#xff0c;PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5&#xff01;作为 PHP 语言的又一次重要迭代&#xff0c;PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是&#xff0c;借助强大的本地开发环境 ServBay&am…...

破解路内监管盲区:免布线低位视频桩重塑停车管理新标准

城市路内停车管理常因行道树遮挡、高位设备盲区等问题&#xff0c;导致车牌识别率低、逃费率高&#xff0c;传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法&#xff0c;正成为破局关键。该设备安装于车位侧方0.5-0.7米高度&#xff0c;直接规避树枝遮…...