Skip to content

Docker 启用 API 服务(开放 2375 端口)

近两天的开发任务,需要使用到 Python 的 docker 库完成容器的部分基础操作(Docker Java SDK 倒是用过几次,Docker Python SDK 还是头一次)。

利用 AI 生成了下 Docker 操作部分代码(不知不觉就替代了搜索引擎的使用),脱敏后如下:

python
import docker

# 连接 Docker 客户端
client = docker.DockerClient(base_url="tcp://192.168.xx.xx:2375")

# 创建容器并运行
container = client.containers.run(
    image=docker_image,
    name=container_name,
    ports={8000: host_port},
    environment=environment,
    detach=True,
    auto_remove=False,
    restart_policy={"Name": "always"},
    command=commands
)

启动运行,刚运行到连接 Docker 就报错了:

text
Error while fetching server API version: HTTPConnectionPool(host='192.168.xx.xx', port=2375): 
Max retries exceeded with url: /version (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x000001C2C4836450>:
Failed to establish a new connection: [WinError 10061] 由于目标计算机积极拒绝,无法连接。'))

错误提示中的关键就是连接不上,顺着这方面排查下吧。

排查过程

  • 机器间通信没问题 ✅
  • 登录测试服务器:
    • Docker 运行状态正常 ✅
    • 检查 2375 端口,竟然没有被占用 ❌️

以我的第一直觉,猜测是 Docker 开放 API 服务可能需要单独配置启用,拿错误信息搜索了下(搜索引擎搜索错误信息目前还是第一顺位),果然有类似说明。以前用 Docker Java SDK 还真没遇到过,看来还是用的少,或是有人提前处理过了。

启用 API 服务

找到 Docker 的服务配置文件:

shell
vi /lib/systemd/system/docker.service

进行如下关键修改:

shell
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target nss-lookup.target docker.socket firewalld.service containerd.service time-set.target
Wants=network-online.target containerd.service
Requires=docker.socket

[Service]
Type=notify
# the default is not to use systemd for cgroups because the delegate issues still
# exists and systemd currently does not support the cgroup feature set required
# for containers run by docker
#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:2375
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutStartSec=0
RestartSec=2
Restart=always

# Note that StartLimit* options were moved from "Service" to "Unit" in systemd 229.
# Both the old, and new location are accepted by systemd 229 and up, so using the old location
# to make them work for either version of systemd.
StartLimitBurst=3
# 其他略...

重启 Docker 服务:

shell
systemctl daemon-reload
systemctl restart docker

启用了 API 服务后,想看看 docker info 会不会有什么特殊状态显示,果然在底部有几行提示,类似如下(感觉提示有些眼熟,可能以前看到过):

shell
[DEPRECATION NOTICE]: API is accessible on http://0.0.0.0:2375 without encryption.
         Access to the remote API is equivalent to root access on the host. Refer
         to the 'Docker daemon attack surface' section in the documentation for
         more information: https://docs.docker.com/go/attack-surface/
In future versions this will be a hard failure preventing the daemon from starting! Learn more at: https://docs.docker.com/go/api-security/

再次运行程序,连接成功,顺利执行。

参考资料

  1. docker 开启 tcp 端口:https://blog.csdn.net/qq_31387691/article/details/138630461