使用Golang玩转Docker API的实践

论坛 期权论坛 脚本     
niminba   2021-5-23 05:21   1626   0

Docker 提供了一个与 Docker 守护进程交互的 API (称为Docker Engine API),我们可以使用官方提供的 Go 语言的 SDK 进行构建和扩展 Docker 应用程序和解决方案。

安装 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(关文章希望大家以后多多支持社区!

分享到 :
0 人收藏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

积分:1060120
帖子:212021
精华:0
期权论坛 期权论坛
发布
内容

下载期权论坛手机APP