Golang

关注公众号 jb51net

关闭
首页 > 脚本专栏 > Golang > golang远程操作docker api

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/

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文