最近项目中,要求实现一个harbor镜像管理功能的controller,查看官方文档,发现harbor没有镜像push/pull相关的api接口。那么在我们实际操作过程中,都是通过docker push/pull 命令完成的,那么docker有没有sdk,供我们程序调用呢?

下面就展示一下是怎么通过docker sdk 实现harbor镜像管理功能的

1、环境准备

docker 安装,此处不展开
harbor 安装 此处不展开
docker sdk 安装 go get github.com/docker/docker/client
官网文档请参考:https://docs.docker.com/develop/sdk/

下面以golang 为例,也有python sdk , 这里就不做详细解释了

2、image load

func ImageLoad(input io.Reader) error {
	ctx := context.Background()
	cli, err := client.NewClientWithOpts(client.FromEnv)
	if err != nil {
		fmt.Print("client NewClientWithOpts err.%v",err)
		return err
	}
	cli.NegotiateAPIVersion(ctx)

	response, err := cli.ImageLoad(ctx, input, false)
	if err != nil{
		fmt.Println("image load err.%v",err)
		return err
	}
	defer response.Body.Close()
	return nil
}

上面是一个image load 的例子,
连接代码: 使用默认环境变量配置生成新的连接 client.FromEnv

  client.NewClientWithOpts(WithHost(host), WithVersion(version), WithHTTPClient(client), WithHTTPHeaders(httpHeaders))

此接口也可通过host指定docker地址,version指定api版本等相关信息

3、image push

func ImagePush(username string, passwd string, tag string) error {
	ctx := context.Background()
	cli, err := client.NewClientWithOpts(client.FromEnv)
	if err != nil {
		fmt.Print("client NewClientWithOpts err.%v",err)
		return err
	}
	cli.NegotiateAPIVersion(ctx)

	authConfig := types.AuthConfig{
		Username: username,
		Password: passwd,
	}
	encodedJSON, err := json.Marshal(authConfig)
	if err != nil {
		return err
	}
	authStr := base64.URLEncoding.EncodeToString(encodedJSON)
	response, err := cli.ImagePush(ctx, tag, types.ImagePushOptions{RegistryAuth: authStr})
	if err != nil {
		fmt.Print("failed to push image %s err.%v",tag, err)
		return err
	}

	defer response.Close()
	io.Copy(os.Stdout, response)
	return nil
}

authConfig 为对接的harbor用户名密码

4、image tag

func ImageTag(source string, target string) error {
	ctx := context.Background()
	cli, err := client.NewClientWithOpts(client.FromEnv)
	if err != nil {
		fmt.Print("client NewClientWithOpts err.%v",err)
		return err
	}
	cli.NegotiateAPIVersion(ctx)

	if err := cli.ImageTag(ctx, source, target); err != nil {
		fmt.Println("failed to tag %s as %s", source, target)
		return err
	}
	return nil
}

为镜像打上tag ,打上符合harbor命名规则的 ip/project/images
以为上传image 到harbor

5、image pull

func ImagePull(img string) error {
	ctx := context.Background()
	cli, err := client.NewClientWithOpts(client.FromEnv)
	if err != nil {
		fmt.Print("client NewClientWithOpts err.%v",err)
		return err
	}
	cli.NegotiateAPIVersion(ctx)

    reader, err := cli.ImagePull(ctx, "docker.io/library/alpine", types.ImagePullOptions{})
    if err != nil {
        return err
    }
	return nil
}

总结:通过以上几个步骤,就可实现push/pull镜像到harbor
load–>tag–>push 完成镜像的上传工作
pull 完成镜像的下载工作