在运维工作中,如果运行的一个容器突然挂了,如何排查?

容器突然挂掉是运维中的常见问题,以下是系统化的排查步骤和解决方案,结合关键命令和深度分析:


1. 确认容器状态与退出码

# 查看已停止的容器(重点观察退出码 Exit Code)
docker ps -a | grep -v "Up"

# 检查容器详细状态(包括退出码、时间点)
docker inspect <容器ID> --format='{{.State}}'
  • 关键退出码解析
    退出码 含义 常见原因
    0 正常退出 任务完成或主动退出
    1 应用错误 代码异常/配置错误
    137 SIGKILL (强制终止) OOM被杀/kill -9
    139 段错误 (Segfault) 内存越界/空指针
    143 SIGTERM (优雅终止) docker stop触发

2. 查看容器日志

# 获取全部日志(重点检查末尾)
docker logs --tail 100 <容器ID> 

# 持续监控日志(复现问题)
docker logs -f <容器ID> 2>&1 | grep -i -E "error|exception|fatal"
  • 日志分析要点
    • 应用崩溃栈轨迹(Java/Python 异常栈)
    • 数据库连接失败、证书过期等配置错误
    • 健康检查连续失败记录

3. 检查资源限制与 OOM

# 确认是否因OOM被杀
dmesg -T | grep -i "killed process"
# 输出示例:Jul 23 10:05:01 host kernel: Out of memory: Killed process 12345 (java)

# 检查容器资源限制
docker inspect <容器ID> --format='{{.HostConfig.Memory}} {{.HostConfig.MemorySwap}}'
  • 解决方案
    # 临时增加内存限制(测试用)
    docker run -d --memory=2g --memory-swap=3g your_image
    
    # 永久调整:在docker-compose中配置
    services:
      app:
        mem_limit: 1.5g
        memswap_limit: 2g
    

4. 分析进程崩溃原因

🔍 核心转储分析 (Core Dump)

# 启用核心转储
docker run --ulimit core=-1 -d your_image  # 允许生成core文件

# 进入容器查找core文件
docker exec -it <容器ID> find / -name core.*
  • 分析工具
    # 使用gdb分析core文件
    gdb /path/to/app /path/to/core -ex "bt full" -ex quit
    

🐞 调试运行

# 以调试模式启动容器
docker run -it --rm --cap-add=SYS_PTRACE your_image sh

# 容器内安装调试工具
apk add gdb lldb  # Alpine
apt-get install gdb lldb # Ubuntu

# 附加到进程
gdb -p <PID>

5. 检查健康检查失败

# 示例:Dockerfile中的健康检查
HEALTHCHECK --interval=30s --timeout=3s \
  CMD curl -f http://localhost:8080/health || exit 1
  • 查看健康状态
    docker inspect --format='{{json .State.Health}}' <容器ID>
    

6. 文件系统与权限问题

# 检查容器文件系统变化
docker diff <容器ID>  # 查看修改的文件(A-Add, D-Delete, C-Change)

# 以root身份进入停止的容器
docker run -it --rm --entrypoint sh --user root <镜像ID>
  • 常见故障
    • 日志文件占满磁盘:df -h 检查宿主机磁盘
    • 权限拒绝:chown/chmod 修复

7. 网络与服务依赖

# 模拟容器网络访问
docker run --rm --network container:<故障容器ID> curlimages/curl http://db:3306

# 检查DNS解析
docker run --rm busybox nslookup redis
  • 依赖问题
    • 数据库连接超时
    • 服务发现失效(Consul/Etcd)
    • 防火墙规则变更

8. 宿主机问题排查

# 检查内核日志
journalctl -k | grep -i docker

# 查看cgroup事件
sudo cat /sys/fs/cgroup/memory/docker/<容器ID>/memory.oom_control

排查流程图

graph TD A[容器退出] --> B{检查退出码} B -->|0| C[正常退出] B -->|137| D[OOM被杀] B -->|139| E[应用崩溃] B -->|其他| F[查看日志] D --> G[调整内存限制] E --> H[分析Core Dump] F --> I[检查错误日志] I --> J[配置错误] --> K[修正配置] I --> L[依赖服务故障] --> M[检查网络]

自动化运维技巧

  1. 崩溃自动重启策略

    docker run --restart=on-failure:5 --restart-window=10m your_image
    
  2. 监控告警集成

    • Prometheus + Alertmanager 监控容器状态
    • 配置规则:容器重启次数 > 3次/5分钟 触发告警
  3. 故障自愈脚本

    #!/bin/bash
    CONTAINER="your_app"
    if [ $(docker inspect -f '{{.State.Status}}' $CONTAINER) == "exited" ]; then
      docker logs $CONTAINER | mail -s "容器 $CONTAINER 崩溃" admin@example.com
      docker restart $CONTAINER
    fi
    

总结:关键命令速查表

场景 命令
查看退出原因 docker inspect -f '{{.State.Error}}' <容器ID>
实时日志 docker logs -f --tail 50 -t <容器ID>
检查OOM dmesg -T | grep -i "killed process"
分析文件变化 docker diff <容器ID>
调试启动 docker run -it --rm --entrypoint=/bin/sh <镜像>
资源使用历史 docker stats --no-stream <容器ID>

通过以上步骤,90%的容器崩溃问题可快速定位。对于复杂问题,结合 APM工具(如Datadog)分布式追踪(Jaeger) 进行深度诊断。

posted @ 2025-07-23 15:20  天道酬勤zjh  阅读(117)  评论(0)    收藏  举报