如何解决“无法连接到 Docker 守护进程”错误
Docker 是构建和运行软件容器的领先平台之一。它附带了在 Swarm 模式下在单个主机或多个分布式节点上使用容器所需的一切。
Docker 有一个基于守护进程的架构。负责创建和启动容器的软件独立于接受命令的 CLI 进程。这意味着如果您尝试在没有活动守护程序连接的情况下运行命令,您将在 CLI 中看到错误。在本文中,我们将分享一些对这些令人沮丧的消息进行故障排除的方法。
问题症状
Docker CLI 依赖于可用的守护进程连接。它使用 API 调用与守护进程交互。当配置的守护进程无法访问时,
docker
命令如
docker ps
、
docker run
和
docker build
将显示错误与此类似的消息:
$ docker run hello-world:latest
Cannot connect to the Docker daemon at unix:///var/run/docker.sock
Is the docker daemon running?
这表明 CLI 尝试使用
/var/run/docker.sock
Unix 套接字与 Docker 守护进程通信。套接字未打开,因此连接失败。
1.检查Docker Daemon服务是否正在运行
Docker 守护进程通常由 systemd 服务管理,该服务会在主机重启后自动启动 Docker。您可以通过检查此服务是否正在运行来开始故障排除:
$ sudo systemctl status docker
docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: inactive (dead)
如果守护程序正在运行,该服务应报告
Active: active (running)
。上面的例子显示了
inactive (dead)
这意味着守护进程已经停止。
使用以下命令启动 Docker:
$ sudo systemctl start docker
现在您应该能够成功运行
docker
CLI 命令。
您可能会发现在您重新启动机器后 Docker 保持停止状态。您可以通过启用该服务来解决此问题,允许 systemd 自动启动它:
$ sudo systemctl enable docker
$ sudo systemctl daemon-reload
daemon-reload
命令指示 systemd 重新加载其配置以应用更改。
2.手动启动守护进程
有时您可能会使用未安装 Docker 服务的系统。您可以使用
dockerd
命令手动启动 Docker 守护进程。这通常需要作为
root
运行。
$ sudo dockerd
INFO[2022-06-29T15:12:49.303428726+01:00] Starting up
只要命令在运行,Docker 就可以访问。使用 Ctrl+C 停止守护进程。
3. 检查 CLI 是否以正确的守护进程为目标
当 CLI 尝试连接到远程 Docker 守护程序实例时,可能会出现问题。这通常是错误消息显示 TCP 地址时的原因:
$ docker run hello-world:latest
Cannot connect to the Docker daemon at tcp:///0.0.0.0:2375
在此示例中,
docker
CLI 尝试使用 TCP 而不是本地 Unix Docker 套接字联系位于
0.0.0.0:2375
的 Docker 守护程序。如果 Docker 守护进程的 TCP 支持被禁用或指定的主机在网络上不可访问,这将失败。
您通常可以通过为要使用的守护进程连接切换到正确的 Docker CLI 上下文来解决此问题:
$ docker context use default
您可以使用
context ls
命令列出所有可用的上下文和它们连接的守护进程端点:
$ docker context ls
NAME DESCRIPTION DOCKER ENDPOINT
default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock
当前选择的上下文用星号突出显示。
DOCKER ENDPOINT
列中的意外值通常是由设置的
DOCKER_HOST
环境变量引起的。在这种情况下,您会看到一条警告:
$ export DOCKER_HOST=1.2.3.4
$ docker context ls
NAME DESCRIPTION DOCKER ENDPOINT
default * Current DOCKER_HOST based configuration tcp://1.2.3.4:2375
Warning: DOCKER_HOST environment variable overrides the active context. To use a context, either set the global --context flag, or unset DOCKER_HOST environment variable.
DOCKER_HOST
环境变量在您的 shell 中的存在会覆盖由您选择的上下文定义的端点。在此示例中,
docker
命令将始终以位于
tcp://1.2.3.4:2375
的守护程序实例为目标。
这个问题可以通过清除
DOCKER_HOST
变量来解决:
$ export DOCKER_HOST=
Docker 现在将使用由您的活动上下文配置的端点。这将是位于
/var/run/docker.sock
的默认本地 Unix 套接字,除非您手动设置了自定义上下文。
$ docker context ls
NAME DESCRIPTION DOCKER ENDPOINT
default * Current DOCKER_HOST based configuration unix:///var/run/docker.sock
4.权限问题
Docker 套接字上的用户权限不正确是守护进程连接问题的另一个常见原因。这种问题通常会显示略有不同的错误消息:
$ docker run hello-world:latest
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock
当您的 Unix 用户帐户没有权限与公开 Docker API 的套接字进行交互时,就会发生这种情况。将自己添加到
docker
组是解决此问题的最佳实践方法:
$ sudo usermod -aG docker $USER
您需要打开一个新的 shell 窗口或注销并重新登录才能使此更改生效。您现在应该能够运行
docker
命令而不会遇到权限问题。
概括
当 Docker CLI 无法使用当前配置与 Docker 守护进程实例通信时,会出现“无法连接到 Docker 守护进程”。这通常是因为 Docker 守护进程服务已停止或禁用。您还可以尝试连接到离线的远程 Docker 主机。
您现在应该知道此问题的可能原因以及解决它的常用方法。通过检查您的 Docker 守护程序设置、重新启动 Docker 服务并确保您的用户帐户有权与 Docker 的套接字进行交互来解决错误。