温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

Docker API如何在Golang中使用

发布时间:2021-04-06 15:40:13 来源:亿速云 阅读:481 作者:Leah 栏目:开发技术

Docker API如何在Golang中使用?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。

安装 SDK

通过下面的命令就可以安装 SDK 了:

go get github.com/docker/docker/client

管理本地的 Docker

该部分会介绍如何使用 Golang + Docker API 进行管理本地的 Docker。

运行容器

第一个例子将展示如何运行容器,相当于 docker run docker.io/library/alpine echo "hello world":

package main import (  "context"  "io"  "os"  "github.com/docker/docker/api/types"  "github.com/docker/docker/api/types/container"  "github.com/docker/docker/client"  "github.com/docker/docker/pkg/stdcopy" ) func main() {  ctx := context.Background()  cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())  if err != nil {  panic(err)  }  reader, err := cli.ImagePull(ctx, "docker.io/library/alpine", types.ImagePullOptions{})  if err != nil {  panic(err)  }  io.Copy(os.Stdout, reader)  resp, err := cli.ContainerCreate(ctx, &container.Config{  Image: "alpine",  Cmd: []string{"echo", "hello world"},  }, nil, nil, "")  if err != nil {  panic(err)  }  if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {  panic(err)  }  statusCh, errCh := cli.ContainerWait(ctx, resp.ID, container.WaitConditionNotRunning)  select {  case err := <-errCh:  if err != nil {   panic(err)  }  case <-statusCh:  }  out, err := cli.ContainerLogs(ctx, resp.ID, types.ContainerLogsOptions{ShowStdout: true})  if err != nil {  panic(err)  }  stdcopy.StdCopy(os.Stdout, os.Stderr, out) }

后台运行容器

还可以在后台运行容器,相当于 docker run -d bfirsh/reticulate-splines:

package main import (  "context"  "fmt"  "io"  "os"  "github.com/docker/docker/api/types"  "github.com/docker/docker/api/types/container"  "github.com/docker/docker/client" ) func main() {  ctx := context.Background()  cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())  if err != nil {  panic(err)  }  imageName := "bfirsh/reticulate-splines"  out, err := cli.ImagePull(ctx, imageName, types.ImagePullOptions{})  if err != nil {  panic(err)  }  io.Copy(os.Stdout, out)  resp, err := cli.ContainerCreate(ctx, &container.Config{  Image: imageName,  }, nil, nil, "")  if err != nil {  panic(err)  }  if err := cli.ContainerStart(ctx, resp.ID, types.ContainerStartOptions{}); err != nil {  panic(err)  }  fmt.Println(resp.ID) }

查看容器列表

列出正在运行的容器,就像使用 docker ps 一样:

package main import (  "context"  "fmt"  "github.com/docker/docker/api/types"  "github.com/docker/docker/client" ) func main() {  ctx := context.Background()  cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())  if err != nil {   panic(err)  }  containers, err := cli.ContainerList(ctx, types.ContainerListOptions{})  if err != nil {   panic(err)  }  for _, container := range containers {   fmt.Println(container.ID)  } }

如果是 docker ps -a,我们可以通过修改 types.ContainerListOptions 中的 All 属性达到这个目的:

// type ContainerListOptions struct { // Quiet bool // Size bool // All  bool // Latest bool // Since string // Before string // Limit int // Filters filters.Args // } options := types.ContainerListOptions{  All: true, } containers, err := cli.ContainerList(ctx, options) if err != nil {  panic(err) }

停止所有运行中的容器

通过上面的例子,我们可以获取容器的列表,所以在这个案例中,我们可以去停止所有正在运行的容器。

注意:不要在生产服务器上运行下面的代码。

package main import (  "context"  "fmt"  "github.com/docker/docker/api/types"  "github.com/docker/docker/client" ) func main() {  ctx := context.Background()  cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())  if err != nil {   panic(err)  }  containers, err := cli.ContainerList(ctx, types.ContainerListOptions{})  if err != nil {   panic(err)  }  for _, container := range containers {   fmt.Print("Stopping container ", container.ID[:10], "... ")   if err := cli.ContainerStop(ctx, container.ID, nil); err != nil {    panic(err)   }   fmt.Println("Success")  } }

获取指定容器的日志

通过指定容器的 ID,我们可以获取对应 ID 的容器的日志:

package main import (  "context"  "io"  "os"  "github.com/docker/docker/api/types"  "github.com/docker/docker/client" ) func main() {  ctx := context.Background()  cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())  if err != nil {   panic(err)  }  options := types.ContainerLogsOptions{ShowStdout: true}  out, err := cli.ContainerLogs(ctx, "f1064a8a4c82", options)  if err != nil {   panic(err)  }  io.Copy(os.Stdout, out) }

查看镜像列表

获取本地所有的镜像,相当于 docker image ls 或 docker images:

package main import (  "context"  "fmt"  "github.com/docker/docker/api/types"  "github.com/docker/docker/client" ) func main() {  ctx := context.Background()  cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())  if err != nil {   panic(err)  }  images, err := cli.ImageList(ctx, types.ImageListOptions{})  if err != nil {   panic(err)  }  for _, image := range images {   fmt.Println(image.ID)  } }

拉取镜像

拉取指定镜像,相当于 docker pull alpine:

package main import (  "context"  "io"  "os"  "github.com/docker/docker/api/types"  "github.com/docker/docker/client" ) func main() {  ctx := context.Background()  cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())  if err != nil {   panic(err)  }  out, err := cli.ImagePull(ctx, "alpine", types.ImagePullOptions{})  if err != nil {   panic(err)  }  defer out.Close()  io.Copy(os.Stdout, out) }

拉取私有镜像

除了公开的镜像,我们平时还会用到一些私有镜像,可以是 DockerHub 上私有镜像,也可以是自托管的镜像仓库,比如 harbor。这个时候,我们需要提供对应的凭证才可以拉取镜像。

值得注意的是:在使用 Docker API 的 Go SDK 时,凭证是以明文的方式进行传输的,所以如果是自建的镜像仓库,请务必使用 HTTPS!

package main import (  "context"  "encoding/base64"  "encoding/json"  "io"  "os"  "github.com/docker/docker/api/types"  "github.com/docker/docker/client" ) func main() {  ctx := context.Background()  cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())  if err != nil {   panic(err)  }  authConfig := types.AuthConfig{   Username: "username",   Password: "password",  }  encodedJSON, err := json.Marshal(authConfig)  if err != nil {   panic(err)  }  authStr := base64.URLEncoding.EncodeToString(encodedJSON)  out, err := cli.ImagePull(ctx, "alpine", types.ImagePullOptions{RegistryAuth: authStr})  if err != nil {   panic(err)  }  defer out.Close()  io.Copy(os.Stdout, out) }

保存容器成镜像

我们可以将一个已有的容器通过 commit 保存成一个镜像:

package main import (  "context"  "fmt"  "github.com/docker/docker/api/types"  "github.com/docker/docker/api/types/container"  "github.com/docker/docker/client" ) func main() {  ctx := context.Background()  cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())  if err != nil {   panic(err)  }  createResp, err := cli.ContainerCreate(ctx, &container.Config{   Image: "alpine",   Cmd: []string{"touch", "/helloworld"},  }, nil, nil, "")  if err != nil {   panic(err)  }  if err := cli.ContainerStart(ctx, createResp.ID, types.ContainerStartOptions{}); err != nil {   panic(err)  }  statusCh, errCh := cli.ContainerWait(ctx, createResp.ID, container.WaitConditionNotRunning)  select {  case err := <-errCh:   if err != nil {    panic(err)   }  case <-statusCh:  }  commitResp, err := cli.ContainerCommit(ctx, createResp.ID, types.ContainerCommitOptions{Reference: "helloworld"})  if err != nil {   panic(err)  }  fmt.Println(commitResp.ID) }

管理远程的 Docker

当然,除了可以管理本地的 Docker, 我们同样也可以通过使用 Golang + Docker API 管理远程的 Docker。

远程连接

默认 Docker 是通过非网络的 Unix 套接字运行的,只能够进行本地通信(/var/run/docker.sock),是不能够直接远程连接 Docker 的。
我们需要编辑配置文件 /etc/docker/daemon.json,并修改以下内容(把 192.168.59.3 改成你自己的 IP 地址),然后重启 Docker:

# vi /etc/docker/daemon.json {  "hosts": [  "tcp://192.168.59.3:2375",  "unix:///var/run/docker.sock"  ] } systemctl restart docker

修改 client

创建 client 的时候需要指定远程 Docker 的地址,这样就可以像管理本地 Docker 一样管理远程的 Docker 了:

cli, err = client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation(),  client.WithHost("tcp://192.168.59.3:2375"))

看完上述内容,你们掌握Docker API如何在Golang中使用的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI