Loading... # Docker 守护进程启动失败排查复盘 # 一、事件概述 ## 1. 事件背景 在主机 192.168.124.80(olab-ops-app)上执行 docker ps 时出现无法连接 Docker 守护进程的报错,需排查根因并恢复服务。 ## 2. 影响范围 ### A. 影响用户数 使用该节点上的 Docker 服务的用户或应用。 ### B. 影响时长 从服务异常到完成修复的窗口期。 ### C. 影响功能 - 无法执行 docker ps、docker run 等所有 Docker 客户端命令 - 依赖该机 Docker 的容器化应用无法启动或管理 ## 3. 严重程度 该节点上 Docker 不可用,属单机级故障;若为生产节点则严重程度高。 # 二、事件时间线 ## 1. 故障现象 ### A. 现象描述 在 192.168.124.80 上执行: ```bash docker ps ``` 报错: ``` Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running? ``` ### B. 初步判断 客户端无法连接到 Docker 守护进程,通常表示 dockerd 未正常启动或 socket 不可用。 ## 2. 问题发现与诊断 ### A. 检查服务状态 执行 systemctl status docker,得到: - Active: failed (Result: exit-code) - Process: ExecStart=/usr/sbin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock(code=exited, status=203/EXEC) status=203/EXEC 表示 systemd 无法执行所配置的二进制(如路径错误或无可执行权限)。 ### B. 核对可执行文件路径 - which dockerd 显示实际路径为:/usr/bin/dockerd - docker.service 中 ExecStart 配置为:/usr/sbin/dockerd 结论:配置路径与真实路径不一致,导致 203/EXEC,Docker 服务无法启动。 ## 3. 根本解决 ### A. 解决方案 将 /etc/systemd/system/docker.service 中的 ExecStart 由 /usr/sbin/dockerd 修改为 /usr/bin/dockerd,执行 daemon-reload 后启动 docker 服务。 ### B. 验证结果 - systemctl start docker 成功,docker.service 为 active (running) - docker ps 可正常执行(当前无运行中容器时列表为空) ```mermaid flowchart LR A[docker ps 报错] --> B[查看 systemctl status] B --> C[发现 203/EXEC] C --> D[核对 which dockerd] D --> E[修正 service 中路径] E --> F[daemon-reload 并 start] F --> G[恢复正常] ```  # 三、问题分析 ## 1. 直接原因 docker.service 中 ExecStart 指向 /usr/sbin/dockerd,而本机 dockerd 实际安装在 /usr/bin/dockerd,systemd 执行失败并报 203/EXEC,Docker 守护进程从未成功启动。 ## 2. 根本原因(简要 5 Whys) ### A. 为什么会出现路径不一致? 可能原因包括:通过包管理器安装的 Docker 将 unit 文件放在 /etc/systemd/system/ 并写死为 /usr/sbin/dockerd,而后续用二进制或其它方式安装的 dockerd 放在 /usr/bin/;或不同发行版/安装方式对 FHS 的约定不同。 ### B. 为什么没有更早发现? 日常若仅使用 docker 命令且未重启或未主动检查 docker.service 状态,问题会一直潜伏直到需要连接 daemon 时暴露。 ### C. 为什么没有自动恢复? 服务因 203/EXEC 启动失败,systemd 不会自动修正 unit 中的路径,需人工修改配置并重新加载。 ## 3. 深层反思 - 自定义或覆盖安装的 unit 文件应使用可执行文件的实际路径(或 PATH 中的命令名),避免写死 /usr/sbin。 - 关键节点在变更(如升级、重装 Docker)后应做一次 systemctl status docker 与 docker ps 的简单验证。 # 四、解决方案 ## 1. 临时方案 ### A. 实施措施 修改 docker.service 中 ExecStart 为 /usr/bin/dockerd,执行: ```bash sed -i 's|ExecStart=/usr/sbin/dockerd|ExecStart=/usr/bin/dockerd|' /etc/systemd/system/docker.service systemctl daemon-reload systemctl start docker ``` ### B. 效果评估 Docker 服务立即恢复,docker ps 等命令恢复正常。 ## 2. 永久方案 ### A. 改进措施 - 保持 ExecStart 使用实际路径 /usr/bin/dockerd(或使用 which dockerd 的结果),避免依赖 /usr/sbin。 - 若使用 Ansible/Puppet 等自动化管理,将 dockerd 路径作为变量或事实写入 unit 模板,避免硬编码。 ### B. 实施计划 已在 192.168.124.80 完成修改并验证;其它使用相同 unit 的节点可一并检查并统一为实际路径。 ## 3. 预防措施 - 部署或升级 Docker 后,将「systemctl status docker」与「docker ps」纳入发布检查清单。 - 对自定义 unit 做代码审查,确保 ExecStart 与当前安装路径一致。 # 五、经验总结 ## 1. 做得好的地方 - 从报错信息快速定位到「daemon 未运行」,再通过 systemd 状态和 203/EXEC 缩小到「可执行文件执行失败」。 - 通过 which dockerd 与 unit 内容对比,快速确认路径不一致并一次性修复。 ## 2. 需要改进的地方 - 若有多台同架构节点,可增加批量检查脚本,避免同类问题重复出现。 ## 3. 流程优化建议 - 将「Docker 安装/升级后验证」写入运维手册或 Runbook,便于复现与交接。 *** ## 参考资料 本文为实战排查记录,无外部引用链接。 最后修改:2026 年 03 月 04 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏