
容器莫名重启、docker ps 里 STATUS 总是 Restarting,是线上最常见的问题之一。本文按「先看退出原因,再看资源,最后看应用」的顺序,整理一套可复现的排查流程。
docker ps -a --filter name=myapp
docker inspect myapp --format '{{.State.ExitCode}} {{.State.OOMKilled}} {{.State.Error}}'
docker inspect myapp --format '{{.RestartCount}} {{.HostConfig.RestartPolicy.Name}}'OOMKilled=true:容器内存超过限制,被内核 OOM killer 杀掉。ExitCode=137:128+9,收到 SIGKILL,常见于 OOM 或被 docker kill。ExitCode=143:128+15,收到 SIGTERM,通常是正常停止,应用没在超时内退出时会被升级为 137。ExitCode=1 / 2:应用自身报错退出,去看日志。ExitCode=126/127:命令无执行权限或找不到,多为 ENTRYPOINT / CMD 写错。docker logs --tail 200 -t myapp
docker events --since 30m --filter container=myapp
dmesg -T | grep -i -E "killed process|out of memory"dmesg 中出现 Memory cgroup out of memory 即可确认是 cgroup 内存限制触发。注意:重启后的新容器会覆盖部分现场,所以要尽早采集。
docker stats --no-stream myapp
docker inspect myapp --format '{{.HostConfig.Memory}} {{.HostConfig.MemorySwap}} {{.HostConfig.NanoCpus}}'Memory 为 0 表示未限制。若设置了 -m 512m 而应用堆很大,就会反复 OOM。典型例子是 JVM:
-XX:MaxRAMPercentage=70,给堆外内存、线程栈、元空间留出余量。--max-old-space-size 限制老生代,避免超出容器上限。docker update --memory 1g --memory-swap 1g myapp
docker run -d --name myapp --memory 1g --restart on-failure:5 myimage:tag--restart always 会掩盖问题并无限重启;排查期建议用 on-failure:N,让故障尽早暴露。deploy.resources.limits(Swarm)或 mem_limit,不同 Compose 版本写法有差异,以官方文档为准。容器「起来了但服务不可用」会被编排系统反复拉起。给镜像加健康检查:
HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
CMD curl -fsS http://127.0.0.1:8080/health || exit 1--start-period 要覆盖应用冷启动时间,否则启动慢的服务会被误判不健康。依赖数据库、缓存的服务,应用内要有连接重试,而不是启动即退出。
docker system df 检查镜像、容器、卷占用,必要时 docker image prune。ss -lntp | grep 8080,日志出现 address already in use。docker inspect 看 ExitCode 与 OOMKilled。docker logs + dmesg 确认直接原因。docker stats 对比用量与限制,调整应用内存参数而不是只加大限制。把退出码、OOM 标记和 cgroup 限制三件事先查清,大多数重启问题几分钟内就能定位。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。