预约咨询 提交工单

深入解析:Docker 容器运行时故障排查

本篇文章带你走进生产环境中 Docker 容器运行时常见故障的真实场景,从症状识别、诊断命令、风险控制、回滚策略到最终验证,全面掌握 SRE 级别的排查思路。

深入解析:Docker 容器运行时故障排查
DevOps 6min 8 浏览 2026-08-09
Docker容器运行时SRE故障排查OOM

深入解析:Docker 容器运行时故障排查

场景

凌晨 2 点,你的手机响起。某生产主机上的一个关键容器化 API 已经连续重启了 20 分钟。docker ps 显示 Restartingdocker logs 为空。服务级别目标(SLO)已经濒临失守。你需要快速、有条理地行动。

这台主机上运行着多个容器,应用团队报告说某个服务不断重启,但日志里没有任何错误信息。主机负载偏高,但尚未达到阈值。你怀疑问题出在 Docker 运行时本身,而不是应用代码。

症状

常见症状帮你快速初判:

  • docker ps 显示容器处于 Restarting 状态,重启次数持续增长。
  • docker inspect 显示 ExitCode: 137OOMKilled: true,这通常代表内存溢出(OOM)。
  • journalctldmesg 中出现 Out of memory: Kill processoom-killer 相关记录。
  • df -h 显示根分区或 Docker 数据目录(/var/lib/docker)已满。
  • 容器启动时报错:failed to create shim taskrunc create failed 等。
  • 容器能启动但数分钟后自动退出,无日志输出。

诊断

按照从外到内的顺序,逐一排查。

1. 确认 Docker 守护进程状态

systemctl status docker
journalctl -u docker --since "10 minutes ago"

检查守护进程是否因资源不足或死锁而崩溃。如果服务处于 inactive (dead) 或频繁重启,问题可能出在 Docker 本身。

2. 获取容器详细信息

docker ps -a --filter "name=your-service"
docker inspect <container-id> --format '{{.State.Status}} | ExitCode={{.State.ExitCode}} | OOMKilled={{.State.OOMKilled}}'

如果 OOMKilledtrue,说明容器被内核 OOM killer 杀死。

3. 查看内核日志

dmesg -T | grep -i -E "oom|killed process" | tail -20
journalctl -k --since "10 minutes ago" | grep -i oom

这些命令能显示是哪个进程/容器触发了 OOM,以及当时主机的内存压力。

4. 检查容器日志和标准输出

docker logs --tail 50 <container-id>

注意:如果容器持续重启,你可能需要 docker logs --tail 50 --timestamps 来观察时间线。有时应用直接把错误写到 stderr,而日志驱动没有正确转发。

5. 检查主机磁盘和 Docker 磁盘占用

df -h
docker system df
du -sh /var/lib/docker/*

容器未清理的镜像、卷或日志文件可能占满磁盘,导致容器创建或写入失败。

6. 检查 cgroup 限制

cat /sys/fs/cgroup/memory/docker/<container-id>/memory.oom_control
cat /sys/fs/cgroup/memory/docker/<container-id>/memory.limit_in_bytes
cat /sys/fs/cgroup/pids/docker/<container-id>/pids.current

确认容器内存和 PID 限制是否设置过低。如果主机本身内存不足,即使容器限制正常也可能被杀。

7. 确认运行时组件(containerd/runc)

docker info | grep -i runtime
systemctl status containerd
runtime -v 2>/dev/null || true

runccontainerd 异常会导致容器启动失败。

风险控制

在动手修复之前,先降低风险:

  • 避免重启守护进程systemctl restart docker 会中断所有容器,除非你已经准备好隔离风险。
  • 优先使用只读命令inspectlogsdmesg 不会改变状态。
  • 记录现场:保存 docker inspectdmesgjournalctl 输出,便于后续分析。
  • 考虑负载均衡摘除节点:如果主机上有副本,可以让 LVS/Nginx 将该节点标记为维护,然后从容排查。

回滚策略

如果问题源于最近的变更,快速回滚是首选:

  • 切换镜像标签:如果当前镜像 latest 被更新,回滚到上一个稳定的版本标签,如 v1.0.1
  • 调整容器参数:如果是内存限制过小,启动新容器时增加 --memory--memory-swap
  • 重新创建容器:使用 docker run 替代 start,保留原有挂载和网络配置。

注意:回滚操作前先确认旧版本镜像仍存在(docker images)。

验证

修复之后,验证不能只看进程是否存活:

docker ps --filter "status=running" --filter "name=your-service"
docker inspect --format '{{.State.Status}}, RestartCount={{.RestartCount}}' <container-id>

然后验证功能:

curl -f http://localhost:8080/healthz

持续观察 15 分钟,确保没有再次 OOM 或重启。使用 docker stats 监控资源:

docker stats --no-stream <container-id>

确认内存使用率稳定在限制的 60% 以下,CPU 不超过预期。

何时提交 OpsGlobal 工单

如果遇到以下情况,请不要继续在黑暗里摸索,立即提交工单给 OpsGlobal:

  • 你已经按上述步骤排查,但问题在 1 小时内未解决。
  • 涉及内核参数调整(如 vm.overcommit_memory)或 runc/containerd 的 bug。
  • 主机上同时有多个容器异常,影响范围大。
  • 你怀疑是硬件故障或底层驱动问题,如设备映射器异常。

OpsGlobal 的 SRE 专家可以在 15 分钟内介入,提供 7x24 小时远程支持,帮助你保护 SLO 和数据安全。

适用场景

适合正在处理 DevOps、Docker, 容器运行时, SRE, 故障排查 相关问题的团队,用于快速建立排查路径和交付标准。

问题背景

本篇文章带你走进生产环境中 Docker 容器运行时常见故障的真实场景,从症状识别、诊断命令、风险控制、回滚策略到最终验证,全面掌握 SRE 级别的排查思路。

排查步骤

先确认影响范围和最近变更,再收集日志、配置、指标和链路数据,最后按风险从低到高执行修复。

命令示例

示例命令请替换为你的真实资源名,并使用环境变量保存账号、密码、token 等敏感信息。

风险说明

生产环境操作前需要确认备份、权限边界、变更窗口和回滚路径,避免扩大故障影响。

回滚方案

保留原配置和发布版本;如修复后指标异常,立即回退配置、镜像或数据库变更并复核日志。

交付清单

问题定位记录、关键命令、修复步骤、验证结果、后续优化建议。

!

遇到类似技术问题?

如果你的服务器、K8s、Docker、CI/CD、数据库或监控系统出现类似问题,可以提交日志和配置文件,我们帮你远程诊断。

工单 WhatsApp 联系 咨询