定海建设规划网站网站推广排名哪家公司好
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