文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Docker API如何在Golang中使用

2023-06-14 10:46

关注

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 mainimport ( "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 mainimport ( "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 mainimport ( "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 mainimport ( "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 mainimport ( "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 mainimport ( "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 mainimport ( "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 mainimport ( "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 mainimport ( "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中使用的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注编程网行业资讯频道,感谢各位的阅读!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯