使用Golang玩转DockerAPI的实践
目录
站在用户的角度思考问题,与客户深入沟通,找到丹徒网站设计与丹徒网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:成都做网站、成都网站设计、企业官网、英文网站、手机端网站、网站推广、国际域名空间、虚拟空间、企业邮箱。业务覆盖丹徒地区。
Docker 提供了一个与 Docker 守护进程交互的 API (称为Docker Engine API),我们可以使用官方提供的 Go 语言的 SDK 进行构建和扩展 Docker 应用程序和解决方案。安装 SDK
go get github.com/docker/docker/client管理本地的 Docker
运行容器
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)}后台运行容器
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)}查看容器列表
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) }}
// 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") }}获取指定容器的日志
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)}查看镜像列表
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) }}拉取镜像
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 上私有镜像,也可以是自托管的镜像仓库,比如 。这个时候,我们需要提供对应的凭证才可以拉取镜像。
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)}保存容器成镜像
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 是通过非网络的 Unix 套接字运行的,只能够进行本地通信(/var/run/docker.sock),是不能够直接远程连接 Docker 的。
# vi /etc/docker/daemon.json{ "hosts": [ "tcp://192.168.59.3:2375", "unix:///var/run/docker.sock" ]}systemctl restart docker修改 client
cli, err = client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation(), client.WithHost("tcp://192.168.59.3:2375"))总结
现在已经有很多可以管理 Docker 的产品,它们便是这样进行实现的,比如:。
到此这篇关于使用Golang玩转Docker API的实践的文章就介绍到这了,更多相关Golang运行Docker API内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
网站栏目:使用Golang玩转DockerAPI的实践
网站链接:http://scyanting.com/article/ejsgso.html