go通过API的方式操作docker

配置docker支持远程操作API

下面是不配置证书的访问方式

如果需要添加TLS证书认证的,请往这边 https://www.cnblogs.com/guangdelw/p/17565051.html

在Linux系统上启用Docker远程使用Docker API的步骤

方法1

1、编辑Docker配置文件

打开Docker配置文件,通常位于/etc/docker/daemon.json。如果该文件不存在,则创建它。

vim /etc/docker/daemon.json
{
  "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2375"]
}

上面的配置将允许Docker API通过UNIX套接字(默认的/var/run/docker.sock)和TCP端口(2375)进行远程访问。

请注意,这将监听所有可用的网络接口(0.0.0.0)上的2375端口。如果您希望限制特定IP地址访问,请将其替换为相应的IP。

2、修改docker.service文件

如果我们单纯这样修改了,再重启服务,一般是无法重启docker的、

查看日志可以发现

dockerd: unable to configure the Docker daemon with file /etc/docker/daemon.json: the following directives are specified both as a flag and in the configuration file: hosts: (from flag: [fd://], from file: [tcp://0.0.0.0:2375 unix:///var/run/docker.sock])

这个错误提示表明您在Docker配置文件/etc/docker/daemon.json中同时指定了hosts选项,同时在Docker启动命令中也使用了-H或--host选项,这导致了冲突。

解决这个问题的方法是去掉其中一个选项,保持只使用一种方式来配置Docker的监听地址。

要么不配置hosts

要么就不要加-H选项

那么这里就需要修改docker.service文件

vim /usr/lib/systemd/system/docker.service

[Service]
....
# 将这一行中的 -H fd:// 去掉
#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecStart=/usr/bin/dockerd --containerd=/run/containerd/containerd.sock

最后重载

systemctl daemon-reload

3、重启docker服务

systemctl restart docker

方法2

只修改docker.service文件

修改docker.service文件

vim /lib/systemd/system/docker.service

[Service]
....
# 在这一行中的添加
#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0:2376 -H unix:///var/run/docker.sock
....

重载服务

systemctl daemon-reload
systemctl restart docker

获取远程容器的ID

package main

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
)

type ContainerInfo struct {
	ID    string `json:"Id"`
	Names []string
}

func getContainerID(containerName string) (string, error) {
	url := "http://10.0.0.12:12375/containers/json"
	resp, err := http.Get(url)
	if err != nil {
		return "", err
	}
	defer resp.Body.Close()

	body, err := io.ReadAll(resp.Body)
	if err != nil {
		return "", err
	}

	var containers []ContainerInfo
	if err := json.Unmarshal(body, &containers); err != nil {
		return "", err
	}

	for _, container := range containers {
		for _, name := range container.Names {
			if name == "/"+containerName {
				return container.ID, nil
			}
		}
	}

	return "", fmt.Errorf("container not found: %s", containerName)
}

func main() {
	containerName := "httpbin" // 将此处替换为要查询的容器名称
	containerID, err := getContainerID(containerName)
	if err != nil {
		fmt.Println(err)
		return
	}

	fmt.Println("Container ID:", containerID)
}

查看容器列表

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/docker/docker/api/types"
	"github.com/docker/docker/client"
)

func main() {
	// 设置远程Docker守护进程的地址
	remoteDockerURL := "tcp://10.0.0.12:2375" // 将remote-docker-host替换为远程Docker守护进程的IP地址或域名

	// 创建Docker客户端,并指定远程Docker守护进程地址
	cli, err := client.NewClientWithOpts(client.WithHost(remoteDockerURL), client.WithVersion("1.41"))
	if err != nil {
		fmt.Println("Failed to create Docker client:", err)
		os.Exit(1)
	}

	// 使用Docker客户端与远程Docker守护进程进行通信
	ctx := context.Background()

	// 列出容器列表
	containers, err := cli.ContainerList(ctx, types.ContainerListOptions{
        All:     true,       // 设置为true以包括停止的容器,false只列出正在运行的容器
    })
	if err != nil {
		fmt.Println("Failed to list containers:", err)
		os.Exit(1)
	}

	fmt.Println("Containers:")
	for _, container := range containers {
		fmt.Printf("Container ID: %s\n", container.ID)
		fmt.Printf("Container Name: %s\n", container.Names[0])
		fmt.Printf("Container Status: %s\n", container.Status)
		fmt.Printf("Container Image: %s\n", container.Image)
		fmt.Println("------------------------")
	}

	// 可以执行其他Docker操作,例如拉取镜像、创建容器、启动容器等
	// 请参考Docker SDK文档以了解更多操作方法
}

查看容器的Inspect信息

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"os"

	"github.com/docker/docker/client"
)

func main() {
	// 设置远程Docker守护进程的地址
	remoteDockerURL := "tcp://10.0.0.12:2375" // 将remote-docker-host替换为远程Docker守护进程的IP地址或域名

	// 创建Docker客户端,并指定远程Docker守护进程地址
	cli, err := client.NewClientWithOpts(client.WithHost(remoteDockerURL), client.WithVersion("1.41"))
	if err != nil {
		fmt.Println("Failed to create Docker client:", err)
		os.Exit(1)
	}

	// 获取容器的Inspect信息
	containerID := "a8fec47ff5cf959690832a1065253c8e7242426ffa392bffe288d951d41fa604" // 将此处替换为要查看Inspect信息的容器ID
	ctx := context.Background()
	containerInfo, err := cli.ContainerInspect(ctx, containerID)
	if err != nil {
		fmt.Println("Failed to inspect container:", err)
		os.Exit(1)
	}

	// 将Inspect信息转换为JSON格式并打印到控制台
	inspectJSON, err := json.MarshalIndent(containerInfo, "", "    ")
	if err != nil {
		fmt.Println("Failed to convert to JSON:", err)
		os.Exit(1)
	}

	fmt.Println("Container Inspect Info:")
	fmt.Println(string(inspectJSON))
}

查看docker info

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"os"

	"github.com/docker/docker/client"
)

func main() {
	// 设置远程Docker守护进程的地址
	remoteDockerURL := "tcp://10.0.0.12:12375" // 将remote-docker-host替换为远程Docker守护进程的IP地址或域名

	// 创建Docker客户端,并指定远程Docker守护进程地址
	cli, err := client.NewClientWithOpts(client.WithHost(remoteDockerURL), client.WithVersion("1.41"))
	if err != nil {
		fmt.Println("Failed to create Docker client:", err)
		os.Exit(1)
	}

	ctx := context.Background()
	dockerInfo, err := cli.Info(ctx)
	if err != nil {
		fmt.Println("Failed to get Docker info:", err)
		os.Exit(1)
	}

	// 将Info信息转换为JSON格式并打印到控制台
	infoJSON, err := json.MarshalIndent(dockerInfo, "", "    ")
	if err != nil {
		fmt.Println("Failed to convert to JSON:", err)
		os.Exit(1)
	}

	fmt.Println("Docker Info:")
	fmt.Println(string(infoJSON))
}
posted @ 2023-07-18 11:53  厚礼蝎  阅读(236)  评论(0编辑  收藏  举报