10、Docker容器故障排查

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. 容器无法启动

  • 检查

    Bash 复制代码
    docker 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等编排工具)

六、维护检查清单

  1. 日常检查

    Bash 复制代码
    # 检查异常容器
    docker ps -f "status=exited" -f "exited=1"
    
    # 检查镜像更新
    docker images --filter "dangling=true"
    
    # 检查系统资源对Docker的影响
    free -h  # 内存
    df -h /var/lib/docker  # 磁盘
  2. 每周维护

    • 清理无用资源:

      Bash 复制代码
      docker system prune -af --volumes  # 谨慎使用,会删除未使用的卷
    • 检查安全漏洞:

      Bash 复制代码
      docker scan <镜像名>  # 需要安装docker-scan插件
    • 备份重要数据卷:

      Bash 复制代码
      docker run --rm -v <卷名>:/source -v $(pwd):/backup alpine tar czvf /backup/<卷名>_backup.tar.gz -C /source .
  3. 应急工具包

    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)建立长期监控,对容器健康状态、资源使用和响应时间进行持续跟踪。

相关推荐
heRs BART2 小时前
Redis简介、常用命令及优化
数据库·redis·缓存
liuyunshengsir2 小时前
linux 下新增用户后无法使用TAB补全功能的最佳解决方法
linux·运维·服务器
书生执笔画浮沉2 小时前
rpmrebuild
linux·centos·rpm
NiKick2 小时前
MySql中的事务、MySql事务详解、MySql隔离级别
数据库·mysql·adb
gmaajt2 小时前
mysql如何检查数据库表是否存在损坏_使用CHECK TABLE命令修复
jvm·数据库·python
heRs BART2 小时前
【Flask】四、flask连接并操作数据库
数据库·python·flask
Lucifer三思而后行2 小时前
一次 Oracle RAC 归档告警排查
数据库·oracle
zhuiyisuifeng3 小时前
PostgreSQL常用时间函数与时间计算提取示例说明
数据库·postgresql
wellc3 小时前
MySQL Workbench菜单汉化为中文
android·数据库·mysql