基于本文回答

播面 播面

文解图解播客视频,多维讲透八股文
0
评论

如何排查一个状态显示为 Exited (1) 且无法正常启动的容器?

当 Docker 容器的状态显示为 Exited (1) 时,意味着容器内的主进程(PID 1)异常退出,并且返回了错误码 1(通常表示通用错误)。

要排查并解决这个问题,可以按照以下标准排查步骤进行,从最简单直接的查看日志,到深入的调试模式:


第一步:查看容器日志(最直接有效)

容器退出时,通常会在标准输出或标准错误中留下线索。

bash
docker logs <container_id_or_name>
  • 常用参数
    • docker logs --tail 100 <container_id>:只看最后 100 行。
    • docker logs -t <container_id>:带上时间戳,方便比对报错时间。

常见日志报错及原因:

  • Can't find file...No such file or directory:找不到配置文件或启动脚本。
  • Permission denied:权限不足(可能需要非 root 用户运行,但目录权限没设对)。
  • Address already in useport is already allocated:端口冲突。
  • 数据库连接超时、凭证错误等。

第二步:查看容器的详细元数据(Inspect)

如果日志里什么都没有,可以通过 docker inspect 查看容器退出的具体时间和配置。

bash
docker inspect <container_id_or_name>

重点关注以下几项:

  1. State 模块
    • ExitCode: 应该显示为 1
    • Error: 是否有 Docker 引擎级别的报错信息。
    • FinishedAt: 确认容器退出的精确时间。
  2. PathArgs
    • 看看容器启动时实际执行了什么命令,是否与你预期的一致。
  3. Mounts
    • 检查挂载的宿主机目录是否存在,权限是否正确。

第三步:尝试在前台运行(交互模式)

有时候容器一启动就挂了,导致日志没来得及写入。你可以尝试用交互模式手动运行该镜像,看看在命令行中直接启动会报什么错。

通过 docker ps -a 找到该容器使用的镜像名称(IMAGE),然后运行:

bash
docker run -it --rm <image_name> /bin/sh
# 或者如果支持 bash
docker run -it --rm <image_name> /bin/bash
  • --rm:退出后自动删除这个临时测试容器。
  • -it:开启交互式终端。

在容器内手动测试:
进入容器后,手动执行容器原本的启动命令(可以通过第二步 inspect 里的 PathArgs 找到,或者查看 Dockerfile 中的 ENTRYPOINTCMD)。
例如:

bash
# 进入容器后,手动运行你的程序
python app.py
# 或者
npm start

此时,任何报错都会直接打印在你的终端上。


第四步:覆盖 Entrypoint 强行进入容器

如果容器镜像设置了 ENTRYPOINT,导致你无法通过上面的命令进入 shell,你可以强制覆盖它:

bash
docker run -it --rm --entrypoint /bin/sh <image_name>
# 或者
docker run -it --rm --entrypoint /bin/bash <image_name>

进去之后,检查:

  1. 依赖包是否完整。
  2. 环境变量是否正确(输入 env 查看)。
  3. 配置文件路径是否正确。

第五步:排查常见诱因

如果以上方法仍未定位到问题,请检查以下几点:

  1. 配置文件/挂载问题(最常见)
    • 你是否挂载了宿主机的配置文件?如果宿主机上的文件不存在,Docker 可能会把该路径当成一个目录创建,导致容器内的程序读取失败。
    • 检查挂载目录的权限:chmod -R 755 /path/to/host/dir
  2. 端口冲突
    • 容器要绑定的宿主机端口是否已被其他程序占用?
    • netstat -tuln | grep <端口号> 检查宿主机端口。
  3. 内存不足(OOM - Out of Memory)
    • 虽然 OOM 的退出码通常是 137,但有时也会表现为 1
    • 检查宿主机内存:free -m
    • 检查系统日志:dmesg -T | grep -i oomtail -n 100 /var/log/messages
  4. 环境变量缺失
    • 某些镜像(如 MySQL, Postgres)如果启动时不提供必要的环境变量(如 MYSQL_ROOT_PASSWORD),会自动退出。

总结排查口诀:

先看日志 (logs),再看配置 (inspect);
前台交互 (run -it),覆盖入口 (entrypoint);
检查挂载与权限,端口内存扫一遍。