golang远程操作docker api方式
作者:野猪佩挤
文章介绍了Docker监听并处理三种socket形式的API请求:unix、tcp和fd,默认情况下,Docker已经开启了unix socket,并且只有root用户或docker用户组成员才有权限访问,用户可以通过编辑docker守护进程的配置文件,添加tcp参数来开放远程API访问
golang远程操作docker api
Docker 可以监听并处理 3 种 socket 形式的 API 请求,分别是unix(unix 域协议)、tcp(tcp 协议)和fd。
一般来说,在安装好 docker 后,默认就已经开启了unix socket,并且我们在执行需要有root权限或者docker用户组成员才有权限访问。例如:
curl --unix-socket /var/run/docker.sock http://docker/version
添加远程 API 访问接口
编辑 docker 守护进程的配置文件/lib/systemd/system/docker.service,找到运行主命令的那一行,其内容大致为"ExecStart=/usr/bin/dockerd -H fd:// … "的那一行,给dockerd命令加参数-H tcp://0.0.0.0:2375,意思是在 2375 端口开放 API 访问。
例如在我的设备上,配置文件相应的那一行原本为
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
添加参数后变为
ExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2375 --containerd=/run/containerd/containerd.sock
重新加载
systemctl daemon-reload # 重新加载守护进程配置 systemctl restart docker.service # 重启 docker 服务
测试
comp@Linux system % docker -H tcp://192.168.64.7:2375 version Client: Cloud integration: v1.0.22 Version: 20.10.11 API version: 1.41 Go version: go1.16.10 Git commit: dea9396 Built: Thu Nov 18 00:36:09 2021 OS/Arch: darwin/arm64 Context: default Experimental: true
测试可以访问
comp@Linux system % docker -H tcp://192.168.64.7:2375 images REPOSITORY TAG IMAGE ID CREATED SIZE gossh v01 fa111aaaec47 8 days ago 35.6MB <none> <none> 670ae487e585 8 days ago 35.6MB nginx latest eeb9db34b331 8 days ago 134MB httpd latest 1c2ff9e4eb7d 2 weeks ago 136MB arm64v8/alpine latest 8e1d7573f448 6 weeks ago 5.33MB alpine latest 8e1d7573f448 6 weeks ago 5.33MB
go 获取启动的容器
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())
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation(),
client.WithHost("tcp://192.168.64.7:2375"))
if err != nil {
panic(err)
}
containers, err := cli.ContainerList(ctx, types.ContainerListOptions{})
if err != nil {
panic(err)
}
for _, container := range containers {
fmt.Println(container.Names, container.Image, container.Ports, container.Status,
container.ImageID)
}
}

启动一个容器
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(),
client.WithHost("tcp://192.168.64.7:2375"))
//cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
panic(err)
}
imageName := "httpd:latest"
out, err := cli.ImagePull(ctx, imageName, types.ImagePullOptions{})
if err != nil {
panic(err)
}
defer out.Close()
io.Copy(os.Stdout, out)
resp, err := cli.ContainerCreate(ctx, &container.Config{
Image: imageName,
}, nil, 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 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(),
client.WithHost("tcp://192.168.64.7:2375"))
//cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil {
panic(err)
}
out, err := cli.ImagePull(ctx, "httpd:latest", types.ImagePullOptions{})
if err != nil {
panic(err)
}
defer out.Close()
io.Copy(os.Stdout, out)
}

官网参考
https://docs.docker.com/engine/api/sdk/examples/
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
