使用Go进行Docker二次开发|Go主题月

1,459 阅读3分钟

简介

众所周知,Docker是用go进行开发的,所以自然Docker官方也开放了go的Docker API库。所以我们可以简单的调用Docker API来对Docker进行二次开发,下面就做个简单的示例,使用go来查看本地的容器,和启动一个容器。

确认版本

首先要看看本地Docker版本,然后去拉取对应的go库。如果拉取的go库版本大于本地Docker版本的话,就会出现类似client version 1.41 is too new. Maximum supported API version is 1.40的错误,所以一定要确保Docker API的go库版本小于等于本地的Docker版本

// 执行命令查看docker版本
docker version
Client: Docker Engine - Community
// docker版本
 Version:           20.10.5
 API version:       1.41
 Go version:        go1.13.15
 Git commit:        55c4c88
 Built:             Tue Mar  2 20:18:05 2021
 OS/Arch:           linux/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.5
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       363e9a8
  Built:            Tue Mar  2 20:16:00 2021
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.4.4
  GitCommit:        05f951a3781f4f2c1911b05e61c160e9c30eaa8e
 runc:
  Version:          1.0.0-rc93
  GitCommit:        12644e614e25b05da6fd08a38ffa0cfe1903fdec
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

可以看到我本地的Docker版本为20.10.5,所以我要拉取对应的go库的版本

可以去go官方库查看对应支持的版本,我里拉取了**v20.10.5+incompatible**这个版本的Docker API库。

go get github.com/docker/docker@v20.10.5+incompatible

这里推荐使用Goland这个IDE,真的超级好用,它会自动导入对应的依赖

mod依赖

我这边用的是moudle模式,所以对应的mod文件内容为。

module demo

go 1.16

require (
	github.com/Microsoft/go-winio v0.4.16 // indirect
	github.com/containerd/containerd v1.4.4 // indirect
	github.com/docker/distribution v2.7.1+incompatible // indirect
	github.com/docker/docker v20.10.5+incompatible
	github.com/docker/go-connections v0.4.0 // indirect
	github.com/docker/go-units v0.4.0 // indirect
	github.com/gogo/protobuf v1.3.2 // indirect
	github.com/gorilla/mux v1.8.0 // indirect
	github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 // indirect
	github.com/morikuni/aec v1.0.0 // indirect
	github.com/opencontainers/go-digest v1.0.0 // indirect
	github.com/opencontainers/image-spec v1.0.1 // indirect
	github.com/sirupsen/logrus v1.8.1 // indirect
	golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
	google.golang.org/grpc v1.36.1 // indirect
	gotest.tools/v3 v3.0.3 // indirect
)

代码示例

查看本地已启动的Docker容器

package main

import (
	"context"
	"fmt"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/client"
)

func main() {
	cli, err := client.NewClientWithOpts()
	if err != nil {
		panic(err)
	}
	// 获取本地已启动的Docker容器,如果要查看全部容器,可以配置types.ContainerListOptions{}参数
	containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{})
	if err != nil {
		panic(err)
	}

	for _, container := range containers {
		fmt.Printf("容器ID:%s,容器名称:%s,容器状态:%s\n", container.ID[:10],container.Image,container.State)
	}

}

输出:

容器ID:e7edbc9856,容器名称:zookeeper:3.6.2,容器状态:running
容器ID:0029fea937,容器名称:mysql:5.7,容器状态:running

启动一个容器

package main

import (
	"context"
	"github.com/docker/docker/api/types"
	"github.com/docker/docker/client"
)

func main() {
	cli, err := client.NewClientWithOpts()
	if err != nil {
		panic(err)
	}
	err=cli.ContainerStart(context.Background(),"6fe3752c98d8",types.ContainerStartOptions{})
	if err != nil {
		panic(err)
	}
}

然后再查看本地已启动Docker容器列表,输出:

容器ID:e7edbc9856,容器名称:zookeeper:3.6.2,容器状态:running
容器ID:0029fea937,容器名称:mysql:5.7,容器状态:running
容器ID:6fe3752c98,容器名称:mysql:8.0,容器状态:running

总结

这里只是简单的展示了go操作Docker的能力,具体还有很多玩法,我们可以用go构建自己的Docker容器管理平台,守护容器等等。具体的可以看官方文档,官方提供了很多API供我们使用