容器反复重启是什么
容器反复重启是排障里最常见的一类问题,表现为状态在运行与重启之间反复切换,或者启动几秒就挂掉。排查顺序是先止损再复现:先把重启策略改成不自动拉起,让容器稳定停在失败态,然后看日志与退出码,再以前台方式进入容器手动执行原来的启动命令复现问题。高频原因包括启动命令秒退、配置或密钥缺失、依赖不可达、入口脚本权限不对。
基本信息
| 止损 | docker update --restart=no <容器> 或 docker stop,让状态停止跳动 |
|---|---|
| 看现场 | docker logs --tail=200 看最后输出;docker inspect 读 RestartCount 与 ExitCode |
| 复现 | docker run -it --rm --entrypoint sh <镜像> 手动执行原启动命令 |
| 高频原因 | PID 1 秒退、配置或密钥缺失、连不上数据库、文件权限不足、内存超限被杀 |
| 修复 | 改配置或启动命令后重建容器,再恢复原先设置的重启策略 |
典型使用场景
- 发布后服务起不来,需要快速区分是配置问题、依赖问题还是代码问题
- 容器启动几秒就退出,日志只有开头几行,看不出完整堆栈
- 宿主机升级或内核参数调整后,原本正常的容器集体异常
- 内存超限导致进程被杀,日志没有明显报错但容器持续重启
- Kubernetes 里出现 CrashLoopBackOff 时,在 Docker 侧做同等排查定位根因
排查命令
排查命令
docker inspect myapp -f 'Restarts={{.RestartCount}} Status={{.State.Status}}'
docker logs myapp --tail=200 # 先看最后 200 行输出
docker inspect myapp -f 'ExitCode={{.State.ExitCode}} OOMKilled={{.State.OOMKilled}}'
docker run --rm -it --entrypoint sh myapp:1.2.3 # 手动执行原启动命令,观察报错
# 退出码 137 常见于被强制杀死或内存超限,先看 OOMKilled 再怀疑代码退出码线索
| 退出码 | 常见含义 | 下一步 |
|---|---|---|
| 0 | 进程正常结束 | 检查启动命令是否写错、是否为一次性任务 |
| 1 | 应用自身报错退出 | 看日志首个报错,通常是配置或依赖问题 |
| 126 / 127 | 权限不足或找不到命令 | 检查入口脚本权限、路径与解释器 |
| 137 | 被强制杀死或内存超限 | 检查 OOMKilled 字段与内存限制设置 |
| 143 | 收到终止信号正常停止 | 确认是否被外部停止或健康检查触发 |
『容器在重启但用户请求全报错』这类情况常见于入口脚本执行到第二行就退出:日志往往只有第一行输出,看到日志异常短就要留意这一点。
不要为了方便长期使用自动重启策略兜底:重启循环会把日志刷爆,原始报错被滚动冲掉,等真正需要定位时现场已经不在。