docker exec 排查容器问题:从日志到进程

背景

服务器上跑着 5 个容器。有天大屏打不开,Nginx 报 502。

第一反应:哪个容器挂了?为什么挂?

docker ps 只能看到"容器活着",看不到"里面发生了什么"。

原因

容器是一层封装。默认只能看到它的"外壳状态"(Up / Exited),要看内部,得用 docker logs、docker exec、docker inspect 这些工具"进到里面看"。

排查顺序应该是:

复制代码
1. 看容器状态     → docker ps
2. 看容器日志     → docker logs
3. 进容器内部看   → docker exec
4. 看容器配置     → docker inspect
5. 看资源占用     → docker stats

解决

第一步:看容器状态

bash 复制代码
docker ps -a

关键看两列:

STATUS:是 Up 还是 Exited?有没有 (unhealthy)?

PORTS:端口映射对不对?

bash 复制代码
docker compose ps

如果容器在反复重启(Restarting),说明启动时就失败了------直接看日志。

第二步:看容器日志(最常用)

bash 复制代码
# 最后 100 行
docker logs --tail 100 dashboard-dashboard_a-1

# 实时跟踪(类似 tail -f)
docker logs -f dashboard-dashboard_a-1

# 带时间戳
docker logs -t dashboard-dashboard_a-1

# 看最近 10 分钟的
docker logs --since 10m dashboard-dashboard_a-1

日志里重点找:

Error、Exception、Traceback

Connection refused、Access denied

OOMKilled(内存被打爆了)

第三步:进容器内部看

容器能起来但行为不对------进去看:

bash 复制代码
docker exec -it dashboard-dashboard_a-1 /bin/bash

如果容器很精简(没有 bash):

bash 复制代码
docker exec -it dashboard-dashboard_a-1 /bin/sh

进去后能做的事:

bash 复制代码
# 看进程
ps aux

# 看端口
netstat -tlnp
# 或
ss -tlnp

# 看环境变量
env

# 看文件
ls -la /app

# 看网络通不通
curl -v http://db:3306

第四步:看容器配置

想确认环境变量、挂载、健康检查:

bash 复制代码
# 完整配置
docker inspect dashboard-dashboard_a-1

# 只看环境变量
docker inspect dashboard-dashboard_a-1 --format '{{json .Config.Env}}' | jq

# 只看挂载
docker inspect dashboard-dashboard_a-1 --format '{{json .Mounts}}' | jq

# 只看端口映射
docker inspect dashboard-dashboard_a-1 --format '{{json .NetworkSettings.Ports}}' | jq

# 只看健康检查
docker inspect dashboard-dashboard_a-1 --format '{{json .Config.Healthcheck}}' | jq

第五步:看资源占用

容器"慢"或"卡":

bash 复制代码
# 实时资源占用
docker stats

# 只跑一次(不持续刷新)
docker stats --no-stream

关键看:

MEM USAGE / LIMIT:内存用了多少,接近上限就是快 OOM 了

CPU %:CPU 占用

NET I/O:网络流量

实战案例

大屏 502 的排查过程:

bash 复制代码
# 1. 看状态
docker ps -a | grep dashboard
# 输出:dashboard_a  Up 2 minutes (unhealthy)

# 2. 看日志
docker logs --tail 50 dashboard-dashboard_a-1
# 输出:Can't connect to MySQL server on 'db'

# 3. 看数据库容器
docker ps | grep mariadb
# 输出:my-mariadb  Up 5 seconds (health: starting)

# 4. 看数据库日志
docker logs --tail 30 my-mariadb
# 输出:InnoDB initialization... (还在启动)

# 5. 结论:数据库刚重启,Flask 太快连了

解决方案:给数据库加 healthcheck,让 Flask 等它健康再启动。

三个坑

坑 1:只看 docker ps,不看 -a

docker ps 只显示正在运行的容器。挂掉的容器要 docker ps -a 才看得到。

排查第一步永远是 docker ps -a------先确认容器是死是活。

坑 2:docker logs 默认只显示全部

有的容器日志几万行,docker logs xxx 会刷屏。加 --tail 100 只看最近 100 行。

而且 docker logs 看不到进程内部状态------要看进程,必须 docker exec 进去。

坑 3:docker exec 进不去,报 exec: "bash": not found

精简镜像(Alpine、Distroless)没有 bash。改用 /bin/sh:

bash 复制代码
docker exec -it my-container /bin/sh

如果连 sh 都没有,用 docker inspect 看配置,或者在 Dockerfile 里加一个调试用的 shell。

相关推荐
qq_543447822 小时前
DNS解析怎么排查?故障处理与运维实用手册
运维·服务器·网络·php
DeviceHub2 小时前
AI服务器电源设计进阶:TLVR电感的应用解析与选型验证指南
运维·服务器·人工智能
Apipi*2 小时前
30天速通Linux 第七章进程间通信
linux·运维·服务器
狗凯之家源码网2 小时前
AI 步数修改提交系统源码应用场景与落地指南
android·数据库·人工智能·运动步数
迪康软件zz2 小时前
终端审批体系怎么搭?从模板配置到业务连续性
运维·安全·自动化运维
科技研学社2 小时前
中小服装工装厂自动化改造:产线节拍平衡与工位减负实施方案
运维·自动化
极光通讯2 小时前
服务器内存替代料选型方法论:主料号缺货时如何找到Pin-to-Pin兼容型号
运维·服务器
草根大哥2 小时前
08-横向扩容与突发高并发:加机器到底买到了什么
运维·webrtc·srt·横向扩容·whip·自建cdn
北风toto2 小时前
数据库笔记:Armstrong 公理系统与集合论的深度辨析
数据库·笔记