李涛自留地
回到顶部
首页 > 应用 > docker打开报错无法启动:从日志到守护进程的排查顺序

docker打开报错无法启动:从日志到守护进程的排查顺序

文章目录

docker打开报错无法启动这类反馈,问题常常压在两层:一层是客户端连不上 unix socket,另一层是 dockerd 自己没起来。混在一起看,容易在错误的方向上反复折腾。把顺序定成日志、磁盘与权限、配置、链路,先看日志再动配置,这个次序能挡住大半误操作。排查的目标始终是那一条最早的失败记录。

先分清客户端连不上,还是守护进程没起来

遇到 docker打开报错无法启动时,终端里那句 Cannot connect to the Docker daemon at unix:///var/run/docker.sock 只说明 CLI 找不到可用的 socket,并不等于 dockerd 已经崩溃。服务没启动、socket 权限不对、DOCKER_HOST 指到了别处,都可能给出同一句话。

机箱内插在硬盘托架上的固态盘与数据线,docker打开报错无法启动

另一种表现是 systemctl start docker 直接返回 Job for docker.service failed,问题就落在守护进程侧,容器还没轮到启动。先确认属于哪一种,后面的命令才不会白跑。

桌面端走的是另一条路。Windows 与 macOS 上双击 Docker Desktop 没反应,先看它的日志:Windows 在 %LOCALAPPDATA%\Docker\log.txt,macOS 在 ~/Library/Containers/com.docker.docker/Data/log 下。

再看 wsl -l -v 里 WSL2 发行版是否处于 Running,WSL 挂掉时 Docker Desktop 只会转圈。都正常才考虑设置里的 Reset to factory defaults,重置前先把需要的镜像导出。

还有一类容易看错:docker打开报错无法启动的现象里,容器其实起来过又立刻退出,循环重启,桌面上的提示只是表象。查 docker ps -a 的 STATUS 列,退出码 137 之类只作线索,含义具体以官方文档与发行版说明为准。

daemon 日志定位:从 journalctl 抓第一条失败

排查 docker打开报错无法启动,日志是第一现场。systemd 托管的发行版里,dockerd 的输出默认进 journald,单元名一般是 docker.service。加 -b 限定本次启动,加 -n 限制行数,一屏能看完关键段。

systemctl status docker.service --no-pager -l
journalctl -u docker.service -b --no-pager -n 200
journalctl -u docker.service --since "15 min ago" --no-pager

读的顺序是从下往上找第一条 error 或 failed,不必从头逐行扫。前面多是信息级输出,真正的原因通常出现在最后一次重试之前的那几行。

用 snap 装的 Docker,单元名是 snap.docker.dockerd;有的环境还把日志写进 /var/log/docker.log,轮转后的旧内容在 .1 一类归档里。名字与路径以官方文档与发行版说明为准。

日志里出现 unable to configure the Docker daemon with file /etc/docker/daemon.json,基本可以断定是配置解析失败,先跳到配置那一节,别在权限上空耗时间。

磁盘与权限检查:空间、inode 与 socket 归属

docker打开报错无法启动落到存储层时,日志里常出现 no space left on device。此时先别急着删镜像,df -h 看容量,df -i 看 inode,两项都正常,再往 /var/lib/docker 里找是哪个子目录在膨胀。

df -h /var/lib/docker
df -i /var/lib/docker
sudo du -sh /var/lib/docker/* 2>/dev/null | sort -h
ls -l /var/run/docker.sock

overlay2 与 containers 下的日志文件是最常见的两个增长点。清理容器日志要按项目约定来做,直接 rm 掉正在写入的文件,磁盘空间不会立刻回收。

docker system df 能列出镜像、容器、卷各占多少,和 du 的结果对照着看,判断哪一块该清会快一些。

用分层几何与节点连线表示启动链路的层级,docker打开报错无法启动

socket 的属主应是 root、属组是 docker。普通用户不在 docker 组里,就只能靠 sudo,或者一直看到那句连接失败。权限引起的 docker打开报错无法启动不在少数,但优先级排在磁盘之后,加组之后要重新登录或执行 newgrp 才生效。

磁盘写满还有一层原因:容器日志用了默认的 json-file,没有上限。给 daemon.json 配上 log-opts 的 max-size 与 max-file,能挡住后续复发。

启用 SELinux 的发行版上,卷标签不匹配同样会让容器起不来。先用 ls -Zd /var/lib/docker 看上下文,需要修复时执行 sudo chcon -Rt container_var_lib_t /var/lib/docker;挂载宿主目录用 -v /data:/data:z 让 SELinux 重新打标,别为了省事关掉整机策略。

daemon.json 与启动参数:先校验 JSON,再谈字段

被问得最多的 docker打开报错无法启动场景,是改完 /etc/docker/daemon.json 之后服务不动了。格式坏掉是头号原因:多一个逗号、少一个引号,dockerd 会拒绝读取整份配置。

sudo python3 -m json.tool /etc/docker/daemon.json
sudo systemctl restart docker.service

第一条命令通过,说明 JSON 合法;失败会指出行号列号。修好 JSON 再重启,比在日志里猜字段名快得多。只有改过 docker.service 的 ExecStart 才需要 systemctl daemon-reload,daemon.json 不经过它。

字段层面,data-root 指到新盘时要把旧数据迁过去,只改配置会让已有镜像看起来“消失”。log-driver 与 log-opts 的值类型写错,同样会拦住启动。字段之间没有依赖,一次只改一项,出问题时最容易回退。

storage-driver 在已有数据上切换风险更高,镜像层并不通用。真要换,先把 /var/lib/docker 整个目录备份一份再重建,具体以官方文档与发行版说明为准。

从 CLI 到 runc:一次启动要经过哪几层

把 dockerd 想成一条链:CLI 连 socket,dockerd 读配置、初始化存储驱动与网络,再把活交给 containerd,最后落到 runc。任何一环失败,报错都堆在同一份日志里。

分辨层次有个笨办法但有效:看失败行前面的动词。提到 socket、permission 的多在客户端与权限层;提到 graphdriver、overlay2 的在存储层;提到 iptables 或 bridge 的在网络层。

机架上交换机网口与亮起的链路指示灯,docker打开报错无法启动

层次分清之后,docker打开报错无法启动这句描述就能落到某一环,而不是笼统的一句“起不来”。它也决定了接下来该看日志、看磁盘,还是看防火墙规则。

网络层的典型冲突是宿主机防火墙与 Docker 自己维护的链打架,报错里常带 iptables 字样。改动之前先确认,同一台机器上是否还有别的服务依赖现有规则。

改完规则只重启 docker 服务,别顺手重启整机,失败再现时现场还在,比事后回忆强。

重启之后:用状态与自检确认修好

改完配置与权限,重启一次服务,看 systemctl is-active docker 是否返回 active,再看 docker info 里的 Storage Driver 与 Docker Root Dir 是否指向预期位置。

这两项对上了,跑一次 docker run --rm hello-world 验证镜像拉取、runc 启动与出站网络。能跑通,说明这次 docker打开报错无法启动的根因已经处理掉,剩下只是清理旧数据。

把失败行、改过的字段、验证命令记进运维笔记,下次遇到同类问题可以直接跳到对应小节,不用再从现象猜起。

需要开机自启的环境,顺手确认 systemctl is-enabled docker 返回 enabled,别等服务重启后才想起这一项。

命令与路径在不同发行版上略有差异,以官方文档与发行版说明为准。改配置前留一份副本,回滚时比重装省事。

若非作者标注皆为李涛自留地原创文章,转载或复制请以超链接形式并注明出处。