如何解决“无法连接到 Docker 守护程序”错误

已发表: 2022-08-14

显示 Docker 徽标的图形

Docker 是构建和运行软件容器的领先平台之一。 它提供了在 Swarm 模式下在单个主机或多个分布式节点上使用容器所需的一切。

Docker 有一个基于守护进程的架构。 负责创建和启动容器的软件独立于接受您的命令的 CLI 进程。 这意味着如果您尝试在没有活动守护程序连接的情况下运行命令,您将在 CLI 中看到错误。 在本文中,我们将分享一些解决这些令人沮丧的消息的方法。

问题症状

Docker CLI 依赖于可用的守护程序连接。 它使用 API 调用与守护进程交互。 当配置的守护进程无法访问时,像docker psdocker rundocker build这样的docker命令将显示类似于以下的错误消息:

 $ docker run hello-world:latest
无法连接到 unix:///var/run/docker.sock 上的 Docker 守护程序
docker 守护进程是否正在运行?

这表明 CLI 尝试使用/var/run/docker.sock Unix 套接字与 Docker 守护进程通信。 套接字未打开,因此连接失败。

1. 检查 Docker 守护程序服务是否正在运行

Docker 守护进程通常由 systemd 服务管理,该服务会在主机重启后自动启动 Docker。 您可以通过检查此服务是否正在运行来开始故障排除:

 $ sudo systemctl 状态泊坞窗
docker.service - Docker 应用程序容器引擎
     已加载:已加载(/lib/systemd/system/docker.service;已启用;供应商预设:已启用)
     活跃:不活跃(死)

如果守护程序正在运行,服务应该报告Active: active (running) 。 上面的示例显示了inactive (dead) ,这意味着守护程序已停止。

使用以下命令启动 Docker:

 $ sudo systemctl 启动泊坞窗

现在您应该能够成功运行docker CLI 命令。

重新启动机器后,您可能会发现 Docker 仍处于停止状态。 您可以通过启用该服务来解决此问题,允许 systemd 自动启动它:

 $ sudo systemctl 启用泊坞窗
$ sudo systemctl 守护进程重载

daemon-reload命令指示 systemd 重新加载其配置以应用更改。

2. 手动启动守护进程

您有时可能会使用未安装 Docker 服务的系统。 您可以使用dockerd命令手动启动 Docker 守护程序。 这通常需要以root身份运行。

 $ sudo dockerd
信息[2022-06-29T15:12:49.303428726+01:00] 启动

只要命令正在运行,Docker 将保持可访问性。 使用 Ctrl+C 停止守护程序。

3. 检查 CLI 是否针对正确的守护进程

当 CLI 尝试连接到远程 Docker 守护程序实例时,可能会出现问题。 这通常是错误消息显示 TCP 地址的原因:

 $ docker run hello-world:latest
无法在 tcp:///0.0.0.0:2375 连接到 Docker 守护进程

在此示例中, docker CLI 尝试使用 TCP 而不是本地 Unix Docker 套接字在0.0.0.0:2375联系 Docker 守护程序。 如果 Docker 守护进程的 TCP 支持被禁用或指定的主机在网络上不可访问,这将失败。

您通常可以通过切换到要使用的守护程序连接的正确 Docker CLI 上下文来解决此问题:

 $ docker 上下文使用默认值

您可以使用context ls命令列出所有可用的上下文和它们连接的守护程序端点:

 $ docker 上下文 ls
名称 描述 Docker 端点             
默认 * 当前基于 DOCKER_HOST 的配置 unix:///var/run/docker.sock

当前选定的上下文以星号突出显示。

DOCKER ENDPOINT列中的意外值通常是由设置的DOCKER_HOST环境变量引起的。 在这种情况下,您会看到警告:

 $ 出口 DOCKER_HOST=1.2.3.4
$ 码头工人上下文 ls
名称 描述 Docker 端点
默认 * 当前基于 DOCKER_HOST 的配置 tcp://1.2.3.4:2375
警告:DOCKER_HOST 环境变量会覆盖活动上下文。 要使用上下文,请设置全局 --context 标志,或取消设置 DOCKER_HOST 环境变量。

您的 shell 中存在的DOCKER_HOST环境变量会覆盖由您选择的上下文定义的端点。 在此示例中, docker命令将始终以tcp://1.2.3.4:2375的守护程序实例为目标。

这个问题可以通过清除DOCKER_HOST变量来解决:

 $ 出口 DOCKER_HOST=

Docker 现在将使用您的活动上下文配置的端点。 这将是/var/run/docker.sock中的默认本地 Unix 套接字,除非您手动设置了自定义上下文。

 $ 码头工人上下文 ls
名称 描述 Docker 端点             
默认 * 当前基于 DOCKER_HOST 的配置 unix:///var/run/docker.sock

4.权限问题

Docker 套接字上的用户权限不正确是守护程序连接问题的另一个常见原因。 这类问题通常会显示稍有不同的错误信息:

 $ docker run hello-world:latest
尝试在 unix:///var/run/docker.sock 连接到 Docker 守护进程套接字时获得权限被拒绝

当您的 Unix 用户帐户缺乏与公开 Docker API 的套接字交互的权限时,就会发生这种情况。 将自己添加到docker组是解决此问题的最佳实践方法:

 $ sudo usermod -aG docker $USER

您需要打开一个新的 shell 窗口或注销并重新登录才能使此更改生效。 您现在应该能够运行docker命令而不会遇到权限问题。

概括

当 Docker CLI 无法使用当前配置与 Docker 守护程序实例通信时,会出现“无法连接到 Docker 守护程序”。 这通常是因为 Docker 守护程序服务已停止或禁用。 您还可能尝试连接到离线的远程 Docker 主机。

您现在应该了解此问题的可能原因以及解决此问题的常用方法。 通过检查您的 Docker 守护程序设置、重新启动 Docker 服务并确保您的用户帐户有权与 Docker 的套接字交互来解决错误。