Docker 容器故障排查详细步骤
一、基础检查流程
1. 服务状态检查
Bash
# 检查Docker服务运行状态
systemctl status docker
service docker status # 适用于旧版本系统
# 检查Docker守护进程健康状态
docker info # 若正常会返回系统信息,异常则显示错误
# 查看容器状态摘要
docker ps -a # 所有容器(包括停止的)
docker stats --no-stream # 容器资源使用情况
# 检查Docker日志
journalctl -u docker --no-pager -n 50 # 系统日志
tail -n 100 /var/log/docker.log # Docker日志文件
2. 容器基础信息检查
Bash
# 查看容器详细配置
docker inspect <容器ID/名称>
# 查看容器日志
docker logs <容器ID/名称> # 基础日志
docker logs -f --tail 100 <容器ID/名称> # 实时跟踪最新100行
docker logs --since 30m <容器ID/名称> # 查看最近30分钟日志
# 检查容器进程
docker top <容器ID/名称>
3. 网络连通性测试
Bash
# 检查容器端口映射
docker port <容器ID/名称>
# 测试容器内部网络
docker exec <容器ID/名称> ping -c 3 8.8.8.8
docker exec <容器ID/名称> curl -I www.baidu.com
# 测试主机到容器的连接
telnet <容器IP> <端口>
nc -zv <容器IP> <端口>
# 检查网络模式
docker network inspect bridge # 检查默认桥接网络
二、配置验证
1. 配置文件检查
Bash
# 检查Docker守护进程配置
cat /etc/docker/daemon.json
docker info | grep -i config # 验证配置是否生效
# 检查容器启动命令
docker inspect --format '{{.Config.Cmd}}' <容器ID/名称>
# 验证Dockerfile语法(需在Dockerfile目录)
docker build --no-cache --progress=plain -t test:tmp .
# 验证docker-compose配置
docker-compose config # 检查语法并显示配置
2. 常见配置问题点
- 检查容器资源限制:
- 内存限制是否合理(
--memory/--memory-swap) - CPU限制是否过度(
--cpus/--cpu-shares)
- 内存限制是否合理(
- 检查卷挂载:
- 宿主路径是否存在且有正确权限
- 挂载模式(读写/只读)是否正确
- 检查网络配置:
- 端口映射是否冲突
- 网络模式与应用需求是否匹配
- 环境变量配置:
- 敏感信息是否正确注入
- 必要变量是否遗漏
三、详细诊断方法
1. 调试模式操作
Bash
# 以交互模式启动容器(用于调试启动问题)
docker run -it --rm --entrypoint /bin/sh <镜像名>
# 为运行中容器添加调试工具
docker exec -it <容器ID/名称> apt update && apt install -y net-tools # Debian/Ubuntu
docker exec -it <容器ID/名称> yum install -y net-tools # CentOS
# 启用Docker守护进程调试模式(需重启服务)
echo '{"debug": true}' >> /etc/docker/daemon.json
systemctl restart docker
2. 容器健康检查矩阵
| 测试类型 | 命令示例 | 预期结果 |
|---|---|---|
| 基础连接测试 | docker exec <容器> curl localhost:端口 |
返回200状态码 |
| 卷读写测试 | docker exec <容器> touch /挂载点/test && rm -f /挂载点/test |
无错误输出 |
| 环境变量验证 | `docker exec <容器> env | grep 关键变量` |
| 健康检查状态 | docker inspect --format '{``{.State.Health.Status}}' <容器> |
返回healthy |
| 重启策略验证 | docker inspect --format '{``{.HostConfig.RestartPolicy.Name}}' <容器> |
符合预期策略(always/on-failure等) |
| 镜像完整性检查 | docker image inspect --format '{``{.Id}}' <镜像名> |
与仓库镜像ID一致 |
3. 常见错误代码分析
| 错误代码/信息 | 含义说明 | 解决方案 |
|---|---|---|
port is already allocated |
端口已被占用 | 更换映射端口或停止占用端口的进程 |
no space left on device |
磁盘空间不足 | 清理无用镜像和容器:docker system prune -a |
permission denied |
权限不足 | 检查挂载目录权限或使用--user指定正确用户 |
unauthorized: authentication required |
镜像仓库认证失败 | 执行docker login重新认证 |
container <ID> is not running |
容器未运行 | 检查启动日志:docker logs <ID> |
context deadline exceeded |
操作超时 | 检查网络连接或增加超时时间:export DOCKER_CLIENT_TIMEOUT=120 |
四、高级诊断工具
1. 容器监控工具
Bash
# 实时监控容器资源
ctop # 需单独安装的可视化工具
# 查看容器详细资源使用历史
docker stats --no-stream --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}\t{{.BlockIO}}"
# 检查容器文件系统使用
docker system df # 整体存储使用
du -sh /var/lib/docker/volumes/ # 卷存储占用
2. 网络诊断工具
Bash
# 容器网络抓包
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock nicolaka/netshoot tcpdump -i any port 80
# 查看容器网络命名空间
nsenter -t $(docker inspect -f '{{.State.Pid}}' <容器ID>) -n netstat -tulnp
# DNS解析测试
docker run --rm --net container:<容器ID> nicolaka/netshoot nslookup www.baidu.com
3. 深入容器内部诊断
Bash
# 查看容器文件系统变化
docker diff <容器ID/名称>
# 导出容器文件系统用于分析
docker export <容器ID> | tar -xf - -C /tmp/container-fs
# 检查容器系统调用(需容器PID)
pid=$(docker inspect -f '{{.State.Pid}}' <容器ID>)
strace -p $pid -e trace=network # 跟踪网络系统调用
五、常见问题解决方案
1. 容器无法启动
-
检查:
Bashdocker inspect --format '{{.State.Status}} {{.State.Error}}' <容器ID> docker logs <容器ID> -
可能原因:
-
启动命令错误
-
依赖服务未就绪
-
资源限制不足
-
卷挂载失败
-
-
解决:
Bash# 尝试手动执行启动命令调试 docker run --rm -it --entrypoint /bin/sh <镜像名> -c "<原启动命令>" # 检查卷权限 chown -R 1000:1000 /宿主卷路径 # 根据容器内用户ID调整 # 临时去除资源限制测试 docker update --memory-remove <容器ID>
2. 容器网络不通
-
检查:
Bash# 检查DNS配置 docker exec <容器ID> cat /etc/resolv.conf # 检查防火墙规则 iptables -L DOCKER-USER # 检查网络连通性链条 ping <宿主机IP> → docker exec <容器> ping <网关IP> → docker exec <容器> ping 8.8.8.8 -
解决:
-
重启Docker网络:
systemctl restart docker -
重建网络:
docker network rm <网络名> && docker network create <网络名> -
检查并关闭SELinux/AppArmor限制
-
3. 卷挂载问题
-
检查:
Bash# 验证卷存在性 docker volume inspect <卷名> # 检查挂载点权限 ls -ld /宿主挂载路径 docker exec <容器ID> ls -ld /容器挂载点 # 检查挂载模式 docker inspect --format '{{range .Mounts}}{{.Source}}:{{.Destination}} ({{.Mode}}){{end}}' <容器ID> -
解决:
-
修复权限:
chmod 777 /宿主挂载路径(临时测试用) -
使用命名卷替代绑定挂载:
docker volume create myvol -
检查挂载路径是否包含特殊字符或软链接
-
4. 容器资源耗尽
-
检查:
Bash# 查看OOM事件 dmesg | grep -i 'out of memory' # 检查容器资源限制 docker inspect --format '{{.HostConfig.Memory}} {{.HostConfig.CpuShares}}' <容器ID> # 查看容器内存使用详情 docker stats --no-stream <容器ID> -
解决:
-
调整资源限制:
docker update --memory 2g --cpus 1 <容器ID> -
优化应用内存使用
-
配置自动扩缩容(结合K8s等编排工具)
-
六、维护检查清单
-
日常检查:
Bash# 检查异常容器 docker ps -f "status=exited" -f "exited=1" # 检查镜像更新 docker images --filter "dangling=true" # 检查系统资源对Docker的影响 free -h # 内存 df -h /var/lib/docker # 磁盘 -
每周维护:
-
清理无用资源:
Bashdocker system prune -af --volumes # 谨慎使用,会删除未使用的卷 -
检查安全漏洞:
Bashdocker scan <镜像名> # 需要安装docker-scan插件 -
备份重要数据卷:
Bashdocker run --rm -v <卷名>:/source -v $(pwd):/backup alpine tar czvf /backup/<卷名>_backup.tar.gz -C /source .
-
-
应急工具包:
Bash# 导出容器配置 docker inspect <容器ID> > <容器名>_config_backup.json # 保存容器状态(创建新镜像) docker commit <容器ID> <镜像名>:emergency-backup # 快速恢复容器(基于备份配置) docker run --name <新容器名> $(jq -r '.HostConfig | "--memory \(.Memory) --cpus \(.Cpus) -v \(.Mounts[] | .Source):\(.Destination):\(.Mode)"' <容器名>_config_backup.json) <镜像名>
通过以上系统化的排查步骤,可有效定位和解决Docker容器的常见问题。建议结合监控工具(如Prometheus+Grafana)建立长期监控,对容器健康状态、资源使用和响应时间进行持续跟踪。