go通过API的方式操作docker

发布时间 2023-07-18 12:01:59作者: 厚礼蝎

配置docker支持远程操作API

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

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

获取远程容器的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)
}