创建builder
docker buildx create \
--use --name mybuilder \
--driver-opt env.https_proxy="socks5://192.168.1.128:1080" \
--driver-opt env.no_proxy="harbor.local"
docker buildx inspect mybuilder --bootstrap
docker buildx use mybuilder
安装证书
若未使用自签名证书跳过这一步
BUILDER=$(docker ps | grep buildkitd | awk '{print $1}')
docker cp ./harbor.crt $BUILDER:/usr/local/share/ca-certificates/
sudo docker exec $BUILDER update-ca-certificates
sudo docker restart $BUILDER
同步镜像
docker-utils sync \
-p linux/amd64,linux/arm64 \
-r harbor.local/library/alpine:latest
编译命令行工具
package main
import (
"bufio"
"fmt"
"github.com/urfave/cli/v2"
"log"
"os"
"os/exec"
"strings"
)
const commandTpl = `
docker buildx build \
--platform=%s \
-f Dockerfile.tmp \
-t %s . \
--push
`
func Sync(ctx *cli.Context) error {
repo := ctx.String("repo")
args := strings.SplitN(repo, "/", 2)
content := []byte("FROM " + args[1])
if err := os.WriteFile("Dockerfile.tmp", content, 0644); err != nil {
return err
}
cmd := fmt.Sprintf(commandTpl, ctx.String("platform"), repo)
executor := exec.Command("sh", "-c", cmd)
// 创建一个管道用于读取标准输出
stdoutPipe, err := executor.StdoutPipe()
if err != nil {
log.Fatalf("Failed to create stdout pipe: %v", err)
}
// 创建一个管道用于读取标准错误
stderrPipe, err := executor.StderrPipe()
if err != nil {
log.Fatalf("Failed to create stderr pipe: %v", err)
}
// 启动命令
if err := executor.Start(); err != nil {
log.Fatalf("Failed to start command: %v", err)
}
// 读取标准输出
go func() {
scanner := bufio.NewScanner(stdoutPipe)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
log.Printf("Error reading stdout: %v", err)
}
}()
// 读取标准错误
go func() {
scanner := bufio.NewScanner(stderrPipe)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
log.Printf("Error reading stderr: %v", err)
}
}()
// 等待命令执行完成
if err := executor.Wait(); err != nil {
return err
}
return os.Remove("Dockerfile.tmp")
}
func main() {
app := cli.App{
Name: "docker-utils",
Usage: "docker工具箱",
Commands: []*cli.Command{
{
Name: "sync",
Usage: "同步镜像仓库",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "r",
Aliases: []string{"repo"},
Usage: "镜像仓库地址, 例如 harbor.com/library/alpine:latest",
},
&cli.StringFlag{
Name: "p",
Aliases: []string{"platform"},
DefaultText: "linux/amd64",
Usage: "平台架构, 例如 linux/amd64, 如有多个用逗号分隔",
},
},
Action: Sync,
},
},
}
if err := app.Run(os.Args); err != nil {
log.Println(err.Error())
}
}