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。

相关推荐
小徐不徐说12 小时前
C++ 接口与插件设计:从工厂注册到 Qt 动态插件
数据库·c++·qt·系统架构·程序设计
Ruiery12 小时前
Linux 6.6内核内存管理深度解析(十三):slab/slub 分配器
linux·运维·服务器
论文复现现场12 小时前
WRF、FEA 能用 L40S 加速吗?求解器检查、断点恢复与长期运行
java·数据库·算法·wrf·有限元分析·gpu计算·断点续算
taktok_ai12 小时前
用 cc-switch 连接 Taktok
网络
Decay__13 小时前
04_MySQL DBA 日常运维手册 —— 会话管理、锁与阻塞、事务监控、慢查询与日志巡检
运维·数据库·sql·mysql·架构
小嘉丶学长14 小时前
Day14 · 字典与集合
java·开发语言·网络·python·学习·1024程序员节
江华森14 小时前
数据中心基础设施运维实战:概述与实验环境搭建
运维
心梦缘-雪雁15 小时前
SQL Server 查询数据存在哪个表里
数据库
迪菲赫尔曼15 小时前
【基础篇 11】把官方源码放到服务器:版本、解压层级和安装位置,一次弄清楚
运维·服务器·开发语言·人工智能·python·yolo·目标检测
lusklusklusk15 小时前
Python 巡检脚本:进程运行状态、数据库写入时效检查及邮件通知与告警
数据库·python·oracle