Administrator
Administrator
发布于 2026-10-28 / 1 阅读
0
0

Docker 故障排查(01):Cannot connect to the Docker daemon:先确认你连的是谁

适用:使用 systemd 的 Linux 服务器、常规 rootful Docker Engine;Compose 示例使用 docker compose V2。本文为教学故障场景,错误文本和结果为示意,具体输出以现场为准。

一、遭遇情况:docker 命令存在,却查不到容器

刚登录服务器,执行 docker ps,终端出现:

Cannot connect to the Docker daemon at unix:///var/run/docker.sock.
Is the docker daemon running?

第一反应可能是“Docker 没安装好”。但 docker --version 能显示版本,只证明客户端存在;容器由后台的 dockerd 管理,客户端还要连接到正确的后台服务。

本篇案例设定为:一台 Linux 测试服务器重启后,Docker 服务未启动。排查时仍然要先排除另一种常见情况:你正在 SSH 到服务器 A,却把 Docker 命令发给了服务器 B。

二、原因分析:先分清三个角色

Docker CLI 是客户端,Docker daemon 是负责镜像和容器的服务,Unix socket 是本机通信入口。连接不到入口,可能是服务没运行、入口选错,或服务启动失败。若明确报 permission denied,优先看本系列第 3 篇。

无法连接 Docker 时的排查路径

context 可以保存不同服务端连接信息;DOCKER_HOST、DOCKER_CONTEXT 以及显式命令选项也可能影响目标。不要仅看当前 SSH 的主机名就认定 Docker 操作一定发生在本机。

三、排查思路:先定位目标,再检查服务

1. 确认客户端配置

以下命令在服务器 Bash 终端执行,属于读取信息:

hostname
docker context show
docker context ls
docker context inspect
env | grep -E '^DOCKER_(HOST|CONTEXT|TLS_VERIFY|CERT_PATH)='
docker version

没有相关环境变量时,grep 无输出是正常情况。检查 context 的 Docker endpoint 是否是预期地址。docker version 如果只有 Client 而没有可用 Server 信息,说明客户端尚未成功与服务端通信,不能把 Client 版本当作服务端版本。

如果 context 或环境变量指向远程服务,本机 systemctl start docker 无法修复远端故障。应先确认操作目标和变更范围,再连接相应服务器处理。

2. 确认本机服务状态

确定目标是本机的常规 Docker Engine 后:

sudo systemctl is-active docker
sudo systemctl status docker --no-pager -l
sudo journalctl -u docker -b -n 100 --no-pager
sudo ls -l /var/run/docker.sock
结果 说明与下一步
inactive,没有启动失败日志 可能只是尚未启动,核对后启动服务
failed,日志指向 daemon.json 转到第 2 篇,先修复配置
active,但 endpoint 不是本机 socket 回到客户端目标检查
Unit docker.service could not be found 检查安装方式、是否为 rootless,不能直接断定 Docker 未安装

Rootless Docker 的服务与 socket 通常位于当前用户范围,检查方式可能是 systemctl --user。Docker Desktop、Snap 或其他托管安装也不一定使用本篇路径。先识别安装方式,再套命令。

四、修复实践:只启动确认未运行的服务

如果证据表明本机 Docker 已安装、配置没有报错,只是处于停止状态:

sudo systemctl start docker
sudo systemctl is-active docker
sudo docker version

这里用 start,因为目标是启动已停止服务。对正在承载业务的 Docker 随手执行 restart,可能影响现有容器,不是必要的诊断步骤。

如果这台服务器明确要求 Docker 随开机启动,再配置:

sudo systemctl enable docker
sudo systemctl is-enabled docker

启用 Docker 自启动不等于所有业务容器都会自动恢复,容器自己的重启策略和应用依赖仍要检查。

如果是当前终端误设了本应不用的远程环境变量,可在确认后用 unset DOCKER_HOST DOCKER_CONTEXT 清除本次会话设置,再选择已有且确认正确的 context。不要为了“恢复默认”删除团队维护的远程 context。

五、验证与失败后的下一步

sudo docker info --format 'Name={{.Name}} Root={{.DockerRootDir}}'
sudo docker ps -a

确认返回的是预期服务器名称和数据目录,再核对原业务容器是否存在。如果列表突然空了,先检查是不是换了 daemon、context 或数据目录,不要马上重建全部业务。

如果 start 失败,应返回日志里的第一条具体错误继续处理,而不是反复启动。保留失败时间、服务日志和最近变更,便于判断配置、磁盘或依赖问题。

六、总结:客户端存在,不代表服务端可用

这类故障最有效的顺序是:确认目标 → 检查服务状态 → 读取启动日志 → 修复明确原因 → 核对服务器身份与业务容器。重装 Docker 通常不是第一步,启动服务也不等于业务已经恢复。

可以用一句值班记录收尾:“因服务器重启后 Docker 未启动导致本机 socket 不可用;启动服务后 Server 信息及原容器恢复可见;已核对开机启动策略。”只有真正观察到这些结果时,才把它们写入真实事故记录。

参考资料

系列目录

  1. Cannot connect to the Docker daemon:先确认你连的是谁
  2. 修改 daemon.json 后 Docker 启动失败:配置校验比反复重启更有效
  3. docker.sock Permission denied:为什么 sudo 能用,普通用户不能用
  4. docker pull 超时:区分 DNS、代理、证书和仓库限流
  5. port is already allocated:容器端口冲突该查谁
  6. 容器显示 Up,网站却访问不了:沿请求路径逐层检查
  7. 容器之间报 Name or service not known:从网络归属查 Docker DNS
  8. 容器启动后立刻 Exited (0):退出成功不代表服务正确运行
  9. 容器反复 Restarting:重启策略掩盖了应用配置错误
  10. Exited (137) 就是内存不足吗?用 OOM 证据判断
  11. no space left on device:先查空间、inode 和日志,别急着 prune
  12. 挂载目录 Permission denied:查 UID、只读属性和 SELinux
  13. not a directory:挂载配置文件时,为什么源路径变成了目录
  14. Compose 中数据库已启动,应用却 connection refused:启动顺序不等于就绪
  15. exec format error:先核对 CPU 架构,再检查入口脚本

系列目录 · 下一篇


评论