系统化排查流程:
┌─────────────────────────────────────────┐
│ 故障排查流程 │
├─────────────────────────────────────────┤
│ │
│ 1. 问题识别 │
│ ├─ 收集故障信息 │
│ ├─ 确认故障现象 │
│ └─ 评估影响范围 │
│ │
│ 2. 问题分析 │
│ ├─ 查看日志 │
│ ├─ 检查配置 │
│ ├─ 检查资源 │
│ └─ 检查网络 │
│ │
│ 3. 问题定位 │
│ ├─ 分析根本原因 │
│ ├─ 确认故障点 │
│ └─ 制定解决方案 │
│ │
│ 4. 问题解决 │
│ ├─ 实施解决方案 │
│ ├─ 验证修复效果 │
│ └─ 监控系统状态 │
│ │
│ 5. 问题总结 │
│ ├─ 记录故障原因 │
│ ├─ 总结经验教训 │
│ └─ 制定预防措施 │
└─────────────────────────────────────────┘
东巴文理解:
故障排查思维:
┌──────────────────┬──────────────┬──────────────┐
│ 排查阶段 │ 关键动作 │ 常用工具 │
├──────────────────┼──────────────┼──────────────┤
│ 问题识别 │ 收集信息 │ docker ps │
│ 问题分析 │ 查看日志 │ docker logs │
│ 问题定位 │ 检查配置 │ docker inspect│
│ 问题解决 │ 实施修复 │ docker exec │
│ 问题总结 │ 文档记录 │ 文档系统 │
└──────────────────┴──────────────┴──────────────┘
故障排查原则:
├─ 由简到繁: 先检查简单问题
├─ 由外到内: 先检查外部因素
├─ 分层排查: 网络→存储→应用
├─ 对比验证: 对比正常与异常
└─ 文档记录: 记录排查过程
常见故障类型:
容器故障:
├─ 容器无法启动
├─ 容器频繁重启
├─ 容器运行异常
└─ 容器无法停止
镜像故障:
├─ 镜像拉取失败
├─ 镜像构建失败
├─ 镜像过大
└─ 镜像损坏
网络故障:
├─ 容器无法访问
├─ 网络连接超时
├─ DNS解析失败
└─ 端口冲突
存储故障:
├─ 数据卷挂载失败
├─ 磁盘空间不足
├─ IO性能问题
└─ 数据丢失
资源故障:
├─ CPU使用过高
├─ 内存不足
├─ 磁盘IO瓶颈
└─ 网络带宽不足
守护进程故障:
├─ Docker服务无法启动
├─ Docker命令无响应
├─ 权限问题
└─ 配置错误
基本排查命令:
# 查看容器状态
docker ps -a
# 输出
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1b2c3d4e5f6 nginx "nginx" 2 hours ago Exited (1) 5 minutes ago nginx
# 查看容器日志
docker logs nginx
# 查看容器详情
docker inspect nginx
# 查看容器资源使用
docker stats nginx
# 查看容器进程
docker top nginx
# 查看容器端口映射
docker port nginx
# 查看容器网络
docker network ls
docker network inspect bridge
# 查看容器存储
docker volume ls
docker volume inspect mydata
# 查看Docker系统信息
docker info
# 查看Docker版本
docker version
# 查看Docker事件
docker events
日志查看技巧:
# 查看最近100行日志
docker logs --tail 100 nginx
# 实时查看日志
docker logs -f nginx
# 查看指定时间段的日志
docker logs --since 2024-01-01T00:00:00 nginx
docker logs --until 2024-01-01T12:00:00 nginx
# 查看最近1小时的日志
docker logs --since 1h nginx
# 查看带时间戳的日志
docker logs -t nginx
# 导出日志到文件
docker logs nginx > /tmp/nginx.log 2>&1
系统排查工具:
# 查看系统资源
top
htop
free -h
df -h
# 查看网络连接
netstat -tulnp
ss -tulnp
# 查看进程
ps aux | grep docker
# 查看系统日志
journalctl -u docker
# 查看内核日志
dmesg | grep docker
# 查看系统负载
uptime
# 查看IO状态
iostat -x 1
# 查看网络流量
iftop
nethogs
# 查看文件描述符
lsof -p <pid>
# 查看系统调用
strace -p <pid>
# 查看网络包
tcpdump -i docker0 -nn
启动失败原因分析:
容器启动失败常见原因:
┌──────────────────┬──────────────┬──────────────┐
│ 原因类型 │ 现象 │ 解决方法 │
├──────────────────┼──────────────┼──────────────┤
│ 镜像不存在 │ 镜像拉取失败 │ 拉取或构建镜像│
│ 配置错误 │ 参数错误 │ 检查配置 │
│ 端口冲突 │ 端口被占用 │ 更换端口 │
│ 资源不足 │ OOM │ 增加资源 │
│ 权限问题 │ 权限拒绝 │ 调整权限 │
│ 依赖服务 │ 依赖未启动 │ 启动依赖 │
│ 存储问题 │ 挂载失败 │ 检查存储 │
│ 网络问题 │ 网络配置错误 │ 检查网络 │
└──────────────────┴──────────────┴──────────────┘
排查步骤:
# 1. 查看容器状态
docker ps -a | grep nginx
# 输出
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1b2c3d4e5f6 nginx "nginx" 2 hours ago Exited (1) 5 minutes ago nginx
# 2. 查看容器日志
docker logs nginx
# 输出
2024-01-01T00:00:00.000000000Z nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
# 3. 查看容器详情
docker inspect nginx
# 输出
[
{
"Id": "a1b2c3d4e5f6...",
"State": {
"Status": "exited",
"ExitCode": 1,
"Error": "",
"StartedAt": "2024-01-01T00:00:00.000000000Z",
"FinishedAt": "2024-01-01T00:00:05.000000000Z"
}
}
]
# 4. 检查镜像
docker images nginx
# 5. 检查端口占用
netstat -tulnp | grep :80
# 输出
tcp6 0 0 :::80 :::* LISTEN 1234/docker-proxy
镜像问题:
# 镜像不存在
docker pull nginx:latest
# 镜像损坏
docker rmi nginx:latest
docker pull nginx:latest
# 镜像标签错误
docker pull nginx:1.21.0
# 镜像仓库访问失败
# 配置镜像加速器
# /etc/docker/daemon.json
{
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com"
]
}
# 重启Docker
systemctl restart docker
配置问题:
# 参数错误
# 检查启动参数
docker inspect --format '{{.Config.Cmd}}' nginx
# 环境变量错误
docker inspect --format '{{.Config.Env}}' nginx
# 工作目录错误
docker inspect --format '{{.Config.WorkingDir}}' nginx
# 用户错误
docker inspect --format '{{.Config.User}}' nginx
# 重新启动容器
docker rm nginx
docker run -d --name nginx nginx:latest
端口冲突:
# 查看端口占用
netstat -tulnp | grep :80
# 停止占用端口的容器
docker stop <container_id>
# 更换端口
docker run -d --name nginx -p 8080:80 nginx:latest
# 查看端口映射
docker port nginx
资源不足:
# 查看系统资源
free -h
df -h
# 查看容器资源限制
docker inspect --format '{{.HostConfig.Memory}}' nginx
# 增加资源限制
docker update --memory="1g" nginx
# 清理无用资源
docker system prune -a
排查容器重启原因:
# 查看容器重启次数
docker inspect --format '{{.RestartCount}}' nginx
# 查看重启策略
docker inspect --format '{{.HostConfig.RestartPolicy.Name}}' nginx
# 查看容器退出码
docker inspect --format '{{.State.ExitCode}}' nginx
# 查看容器日志
docker logs --tail 100 nginx
# 查看系统日志
journalctl -u docker | grep nginx
# 查看OOM事件
dmesg | grep -i "Out of memory"
常见重启原因:
容器重启原因:
┌──────────────────┬──────────────┬──────────────┐
│ 退出码 │ 含义 │ 解决方法 │
├──────────────────┼──────────────┼──────────────┤
│ 0 │ 正常退出 │ 检查应用逻辑 │
│ 1 │ 应用错误 │ 查看应用日志 │
│ 137 │ OOM Killed │ 增加内存 │
│ 139 │ 段错误 │ 检查应用代码 │
│ 143 │ SIGTERM │ 正常停止 │
│ 255 │ 退出码超范围 │ 检查应用代码 │
└──────────────────┴──────────────┴──────────────┘
重启策略:
├─ no: 不自动重启
├─ on-failure: 失败时重启
├─ always: 总是重启
└─ unless-stopped: 除非手动停止
解决方案:
# OOM问题
# 增加内存限制
docker update --memory="2g" nginx
# 应用错误
# 查看应用日志
docker logs -f nginx
# 进入容器调试
docker exec -it nginx sh
# 健康检查失败
# 检查健康检查配置
docker inspect --format '{{.Config.Healthcheck}}' nginx
# 手动执行健康检查
docker exec nginx curl -f http://localhost/ || exit 1
# 调整重启策略
docker update --restart=on-failure:5 nginx
性能问题排查:
# 查看容器资源使用
docker stats nginx
# 输出
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
a1b2c3d4e5f6 nginx 85.50% 512.5MiB / 1GiB 50.05% 15.2MB / 8.5MB 100MB / 50MB 5
# 查看容器进程
docker top nginx
# 输出
UID PID PPID C STIME TTY TIME CMD
root 12345 12340 0 00:00 ? 00:00:00 nginx: master process
101 12346 12345 85 00:00 ? 00:05:00 nginx: worker process
# 查看容器内进程详情
docker exec nginx ps aux
# 查看系统调用
strace -p 12346
# 查看网络连接
docker exec nginx netstat -tulnp
# 查看文件描述符
docker exec nginx lsof -p 1
性能优化:
# CPU性能优化
docker update --cpus="2.0" nginx
# 内存性能优化
docker update --memory="2g" nginx
# IO性能优化
docker update --blkio-weight=700 nginx
# 网络性能优化
docker network create --driver bridge --opt com.docker.network.driver.mtu=1500 mynetwork
docker network connect mynetwork nginx
排查停止问题:
# 尝试停止容器
docker stop nginx
# 超时后强制停止
docker stop -t 10 nginx
# 强制停止容器
docker kill nginx
# 查看容器状态
docker inspect --format '{{.State.Status}}' nginx
# 查看容器进程
docker top nginx
# 查看容器PID
docker inspect --format '{{.State.Pid}}' nginx
# 查看进程状态
ps -p <pid> -o pid,ppid,stat,cmd
# 查看进程状态码
# D: 不可中断睡眠
# S: 睡眠
# R: 运行
# Z: 僵尸进程
解决方案:
# 1. 正常停止
docker stop nginx
# 2. 强制停止
docker kill nginx
# 3. 发送SIGTERM信号
kill -TERM <pid>
# 4. 发送SIGKILL信号
kill -KILL <pid>
# 5. 重启Docker服务
systemctl restart docker
# 6. 删除容器
docker rm -f nginx
# 7. 查看僵尸进程
ps aux | grep Z
# 8. 清理僵尸进程
# 需要重启主机
常见拉取失败原因:
镜像拉取失败原因:
┌──────────────────┬──────────────┬──────────────┐
│ 原因类型 │ 现象 │ 解决方法 │
├──────────────────┼──────────────┼──────────────┤
│ 网络问题 │ 连接超时 │ 检查网络 │
│ 认证问题 │ 权限拒绝 │ 登录认证 │
│ 镜像不存在 │ 镜像未找到 │ 检查镜像名 │
│ 磁盘空间不足 │ 空间不足 │ 清理空间 │
│ 仓库访问限制 │ 访问受限 │ 使用镜像加速 │
│ DNS解析失败 │ 域名解析失败 │ 配置DNS │
└──────────────────┴──────────────┴──────────────┘
排查步骤:
# 1. 尝试拉取镜像
docker pull nginx:latest
# 错误信息
Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
# 2. 检查网络连接
ping -c 4 registry-1.docker.io
# 3. 检查DNS解析
nslookup registry-1.docker.io
# 4. 检查磁盘空间
df -h
# 5. 检查Docker配置
cat /etc/docker/daemon.json
# 6. 查看Docker日志
journalctl -u docker | grep pull
网络问题:
# 配置镜像加速器
# /etc/docker/daemon.json
{
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com",
"https://docker.mirrors.ustc.edu.cn",
"https://hub-mirror.c.163.com"
]
}
# 重启Docker
systemctl restart docker
# 验证配置
docker info | grep "Registry Mirrors" -A 5
# 使用代理
# /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTP_PROXY=http://proxy.example.com:8080"
Environment="HTTPS_PROXY=http://proxy.example.com:8080"
Environment="NO_PROXY=localhost,127.0.0.1"
# 重启Docker
systemctl daemon-reload
systemctl restart docker
认证问题:
# 登录Docker Hub
docker login
# 输出
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: yourusername
Password:
Login Succeeded
# 登录私有仓库
docker login registry.example.com
# 查看认证信息
cat ~/.docker/config.json
# 退出登录
docker logout
磁盘空间问题:
# 查看磁盘使用
df -h
# 查看Docker磁盘使用
docker system df
# 输出
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 15 10 5.5GB 2.5GB (45%)
Containers 20 15 1.2GB 500MB (41%)
Local Volumes 10 8 800MB 300MB (37%)
Build Cache 50 0 2.1GB 2.1GB (100%)
# 清理无用资源
docker system prune -a
# 清理所有未使用的镜像
docker image prune -a
# 清理所有未使用的容器
docker container prune
# 清理所有未使用的卷
docker volume prune
常见构建失败原因:
镜像构建失败原因:
┌──────────────────┬──────────────┬──────────────┐
│ 原因类型 │ 现象 │ 解决方法 │
├──────────────────┼──────────────┼──────────────┤
│ Dockerfile错误 │ 语法错误 │ 检查Dockerfile│
│ 基础镜像问题 │ 镜像不存在 │ 更换基础镜像 │
│ 网络问题 │ 下载失败 │ 检查网络 │
│ 文件不存在 │ 文件未找到 │ 检查文件路径 │
│ 权限问题 │ 权限拒绝 │ 调整权限 │
│ 磁盘空间不足 │ 空间不足 │ 清理空间 │
└──────────────────┴──────────────┴──────────────┘
排查步骤:
# 1. 查看Dockerfile
cat Dockerfile
# 2. 构建镜像
docker build -t myapp:v1.0 .
# 错误信息
Step 3/10 : RUN apt-get update
---> Running in a1b2c3d4e5f6
Err:1 http://archive.ubuntu.com/ubuntu bionic InRelease
Could not connect to archive.ubuntu.com:80 (91.189.88.142).
connect (111: Connection refused)
# 3. 使用--no-cache重新构建
docker build --no-cache -t myapp:v1.0 .
# 4. 使用--progress=plain查看详细输出
docker build --progress=plain -t myapp:v1.0 .
# 5. 检查构建缓存
docker builder prune
Dockerfile错误:
# 错误示例
FROM ubuntu:18.04
RUN apt-get update
RUN apt-get install -y nginx
COPY app /app
CMD ["nginx"]
# 正确示例
FROM ubuntu:18.04
# 更新软件源
RUN apt-get update && \
apt-get install -y nginx && \
rm -rf /var/lib/apt/lists/*
# 复制应用文件
COPY app /app
# 暴露端口
EXPOSE 80
# 启动命令
CMD ["nginx", "-g", "daemon off;"]
网络问题:
# 使用国内软件源
FROM ubuntu:18.04
# 更换软件源
RUN sed -i 's/archive.ubuntu.com/mirrors.aliyun.com/g' /etc/apt/sources.list && \
apt-get update && \
apt-get install -y nginx && \
rm -rf /var/lib/apt/lists/*
COPY app /app
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
权限问题:
# 使用root用户
USER root
# 或者使用sudo
RUN sudo apt-get update
# 或者修改文件权限
RUN chmod +x /app/start.sh
排查网络问题:
# 1. 查看容器网络
docker network ls
# 输出
NETWORK ID NAME DRIVER SCOPE
a1b2c3d4e5f6 bridge bridge local
b2c3d4e5f6a7 host host local
c3d4e5f6a7b8 none null local
# 2. 查看容器网络配置
docker inspect --format '{{.NetworkSettings.Networks}}' nginx
# 3. 查看容器IP地址
docker inspect --format '{{.NetworkSettings.IPAddress}}' nginx
# 4. 进入容器测试网络
docker exec -it nginx sh
# 在容器内测试
ping -c 4 8.8.8.8
ping -c 4 www.baidu.com
curl -I http://www.baidu.com
# 5. 从主机测试容器
ping -c 4 <container_ip>
curl -I http://<container_ip>:80
# 6. 查看网络接口
docker exec nginx ifconfig
# 7. 查看路由表
docker exec nginx route -n
# 8. 查看DNS配置
docker exec nginx cat /etc/resolv.conf
常见网络问题:
网络问题分类:
┌──────────────────┬──────────────┬──────────────┐
│ 问题类型 │ 现象 │ 解决方法 │
├──────────────────┼──────────────┼──────────────┤
│ 无IP地址 │ IP为空 │ 检查网络配置 │
│ DNS解析失败 │ 域名无法解析 │ 配置DNS │
│ 端口不通 │ 无法访问端口 │ 检查防火墙 │
│ 网络隔离 │ 容器间不通 │ 配置网络 │
│ MTU问题 │ 大包不通 │ 调整MTU │
└──────────────────┴──────────────┴──────────────┘
无IP地址问题:
# 查看容器网络模式
docker inspect --format '{{.HostConfig.NetworkMode}}' nginx
# 如果是none模式,连接到网络
docker network connect bridge nginx
# 如果是host模式,容器没有独立IP
# host模式使用主机网络
# 重新创建容器
docker rm -f nginx
docker run -d --name nginx --network bridge nginx:latest
# 查看网络配置
docker network inspect bridge
DNS解析问题:
# 配置DNS服务器
docker run -d \
--name nginx \
--dns 8.8.8.8 \
--dns 8.8.4.4 \
nginx:latest
# 配置DNS搜索域
docker run -d \
--name nginx \
--dns-search example.com \
nginx:latest
# 使用主机DNS
docker run -d \
--name nginx \
--network host \
nginx:latest
# 修改Docker默认DNS
# /etc/docker/daemon.json
{
"dns": ["8.8.8.8", "8.8.4.4"]
}
# 重启Docker
systemctl restart docker
端口不通问题:
# 查看端口映射
docker port nginx
# 查看容器端口
docker inspect --format '{{.NetworkSettings.Ports}}' nginx
# 查看主机端口监听
netstat -tulnp | grep :80
# 检查防火墙规则
iptables -L -n
# 开放端口
firewall-cmd --add-port=80/tcp --permanent
firewall-cmd --reload
# 或者关闭防火墙
systemctl stop firewalld
排查容器间通信:
# 1. 查看容器网络
docker network inspect bridge
# 2. 查看容器IP
docker inspect --format '{{.NetworkSettings.IPAddress}}' nginx
docker inspect --format '{{.NetworkSettings.IPAddress}}' mysql
# 3. 测试容器间连通性
docker exec nginx ping -c 4 <mysql_ip>
# 4. 测试服务端口
docker exec nginx telnet <mysql_ip> 3306
# 5. 查看容器网络模式
docker inspect --format '{{.HostConfig.NetworkMode}}' nginx
docker inspect --format '{{.HostConfig.NetworkMode}}' mysql
# 6. 查看防火墙规则
iptables -L -n | grep docker
解决方案:
# 1. 确保容器在同一网络
docker network create mynetwork
docker network connect mynetwork nginx
docker network connect mynetwork mysql
# 2. 使用容器名称通信
docker exec nginx ping -c 4 mysql
# 3. 使用--link(已废弃)
docker run -d --name nginx --link mysql:mysql nginx:latest
# 4. 检查防火墙规则
iptables -L -n | grep DROP
# 5. 重启Docker网络
systemctl restart docker
排查跨主机通信:
# 1. 查看overlay网络
docker network ls | grep overlay
# 2. 查看网络详情
docker network inspect myoverlay
# 3. 测试跨主机连通性
docker exec nginx ping -c 4 <remote_container_ip>
# 4. 查看VXLAN配置
ip link show
# 5. 查看端口开放
netstat -tulnp | grep 4789
# 6. 查看防火墙规则
iptables -L -n | grep 4789
解决方案:
# 1. 开放VXLAN端口
firewall-cmd --add-port=4789/udp --permanent
firewall-cmd --reload
# 2. 配置overlay网络
docker network create \
--driver overlay \
--subnet=10.0.0.0/24 \
myoverlay
# 3. 连接容器到overlay网络
docker network connect myoverlay nginx
# 4. 检查etcd/consul配置
# 确保服务发现正常
常见挂载失败原因:
数据卷挂载失败原因:
┌──────────────────┬──────────────┬──────────────┐
│ 原因类型 │ 现象 │ 解决方法 │
├──────────────────┼──────────────┼──────────────┤
│ 路径不存在 │ 路径未找到 │ 创建路径 │
│ 权限问题 │ 权限拒绝 │ 调整权限 │
│ 磁盘空间不足 │ 空间不足 │ 清理空间 │
│ SELinux限制 │ 访问被拒绝 │ 配置SELinux │
│ 挂载点被占用 │ 设备忙 │ 卸载后重试 │
└──────────────────┴──────────────┴──────────────┘
排查步骤:
# 1. 查看容器挂载信息
docker inspect --format '{{.Mounts}}' nginx
# 2. 查看详细挂载信息
docker inspect --format '{{json .Mounts}}' nginx | jq
# 3. 查看容器日志
docker logs nginx
# 错误信息
docker: Error response from daemon: error while creating mount source path '/host/data': mkdir /host/data: permission denied.
# 4. 检查主机路径
ls -ld /host/data
# 5. 检查磁盘空间
df -h /host/data
# 6. 检查SELinux状态
getenforce
# 7. 查看SELinux日志
ausearch -m avc -ts recent
路径不存在:
# 创建主机路径
mkdir -p /host/data
# 重新启动容器
docker run -d \
--name nginx \
-v /host/data:/data \
nginx:latest
权限问题:
# 修改目录权限
chmod 755 /host/data
# 修改目录所有者
chown -R 1000:1000 /host/data
# 使用--user参数
docker run -d \
--name nginx \
--user 1000:1000 \
-v /host/data:/data \
nginx:latest
# 使用特权模式(不推荐)
docker run -d \
--name nginx \
--privileged \
-v /host/data:/data \
nginx:latest
SELinux问题:
# 方法1: 添加SELinux标签
chcon -Rt svirt_sandbox_file_t /host/data
# 方法2: 使用:z或:Z后缀
docker run -d \
--name nginx \
-v /host/data:/data:z \
nginx:latest
# 方法3: 临时禁用SELinux(不推荐)
setenforce 0
# 方法4: 配置SELinux策略
# 创建自定义策略
查看磁盘使用:
# 查看系统磁盘使用
df -h
# 输出
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 50G 45G 5.0G 90% /
/dev/sda2 100G 80G 20G 80% /data
# 查看Docker磁盘使用
docker system df
# 输出
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 15 10 5.5GB 2.5GB (45%)
Containers 20 15 1.2GB 500MB (41%)
Local Volumes 10 8 800MB 300MB (37%)
Build Cache 50 0 2.1GB 2.1GB (100%)
# 查看Docker目录大小
du -sh /var/lib/docker/*
# 输出
1.5G /var/lib/docker/containers
3.2G /var/lib/docker/images
800M /var/lib/docker/volumes
2.1G /var/lib/docker/buildkit
# 查看容器日志大小
du -sh /var/lib/docker/containers/*/*-json.log
清理Docker资源:
# 清理所有无用资源
docker system prune -a
# 输出
WARNING! This will remove:
- all stopped containers
- all networks not used by at least one container
- all images without at least one container associated to them
- all build cache
Are you sure you want to continue? [y/N] y
# 清理镜像
docker image prune -a
# 清理容器
docker container prune
# 清理卷
docker volume prune
# 清理网络
docker network prune
# 清理构建缓存
docker builder prune -a
# 清理特定镜像
docker rmi $(docker images -f "dangling=true" -q)
# 清理停止的容器
docker rm $(docker ps -a -q)
# 清理未使用的卷
docker volume rm $(docker volume ls -qf dangling=true)
日志清理:
# 查看容器日志大小
find /var/lib/docker/containers/ -name *-json.log | xargs du -sh
# 清空容器日志
truncate -s 0 /var/lib/docker/containers/*/*-json.log
# 配置日志大小限制
# /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
# 重启Docker
systemctl restart docker
# 重启容器使配置生效
docker restart nginx
排查服务问题:
# 1. 查看Docker服务状态
systemctl status docker
# 输出
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; enabled; vendor preset: disabled)
Active: failed (Result: exit-code) since Mon 2024-01-01 00:00:00 CST; 5s ago
Docs: https://docs.docker.com
Process: 12345 ExecStart=/usr/bin/dockerd (code=exited, status=1/FAILURE)
Main PID: 12345 (code=exited, status=1/FAILURE)
# 2. 查看Docker日志
journalctl -u docker
# 3. 查看系统日志
tail -f /var/log/messages
# 4. 手动启动Docker
dockerd
# 5. 检查配置文件
cat /etc/docker/daemon.json
# 6. 验证配置文件格式
python -m json.tool /etc/docker/daemon.json
常见启动失败原因:
Docker启动失败原因:
┌──────────────────┬──────────────┬──────────────┐
│ 原因类型 │ 现象 │ 解决方法 │
├──────────────────┼──────────────┼──────────────┤
│ 配置错误 │ 配置文件错误 │ 检查配置 │
│ 端口占用 │ 端口被占用 │ 更换端口 │
│ 存储驱动错误 │ 驱动不支持 │ 更换驱动 │
│ 权限问题 │ 权限不足 │ 调整权限 │
│ 依赖缺失 │ 依赖未安装 │ 安装依赖 │
│ 内核版本低 │ 内核不支持 │ 升级内核 │
└──────────────────┴──────────────┴──────────────┘
配置错误:
# 检查配置文件语法
python -m json.tool /etc/docker/daemon.json
# 错误示例
# /etc/docker/daemon.json
{
"storage-driver": "overlay2",
"log-level": "debug",
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com"
]
} # 缺少逗号或括号
# 正确示例
{
"storage-driver": "overlay2",
"log-level": "debug",
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com"
]
}
# 备份并删除配置文件
mv /etc/docker/daemon.json /etc/docker/daemon.json.bak
# 重启Docker
systemctl restart docker
端口占用:
# 查看端口占用
netstat -tulnp | grep 2375
# 停止占用端口的进程
kill -9 <pid>
# 修改Docker端口
# /etc/docker/daemon.json
{
"hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2376"]
}
# 重启Docker
systemctl restart docker
存储驱动错误:
# 查看支持的存储驱动
docker info | grep "Storage Driver"
# 修改存储驱动
# /etc/docker/daemon.json
{
"storage-driver": "overlay2"
}
# 清理旧数据(谨慎操作)
rm -rf /var/lib/docker/*
# 重启Docker
systemctl restart docker
排查命令无响应:
# 1. 查看Docker进程
ps aux | grep docker
# 2. 查看进程状态
top -p $(pgrep dockerd)
# 3. 查看进程线程
pstree -p $(pgrep dockerd)
# 4. 查看进程栈
cat /proc/$(pgrep dockerd)/stack
# 5. 查看系统调用
strace -p $(pgrep dockerd)
# 6. 查看文件描述符
lsof -p $(pgrep dockerd)
# 7. 查看网络连接
netstat -tulnp | grep docker
解决方案:
# 1. 等待命令完成
# 某些操作可能需要较长时间
# 2. 重启Docker服务
systemctl restart docker
# 3. 查看死锁
cat /proc/$(pgrep dockerd)/stack
# 4. 强制停止Docker
systemctl kill docker
# 5. 清理残留进程
pkill -9 dockerd
pkill -9 docker-proxy
# 6. 清理残留文件
rm -f /var/run/docker.pid
rm -f /var/run/docker.sock
# 7. 重启Docker
systemctl start docker
容器故障排查:
├─ 启动失败: 检查日志、配置、资源
├─ 运行异常: 检查资源、应用、网络
├─ 无法停止: 检查进程、信号、状态
└─ 性能问题: 检查资源、配置、应用
镜像故障排查:
├─ 拉取失败: 检查网络、认证、空间
├─ 构建失败: 检查Dockerfile、网络、权限
└─ 镜像损坏: 重新拉取或构建
网络故障排查:
├─ 连接问题: 检查网络配置、防火墙
├─ DNS问题: 检查DNS配置
└─ 端口问题: 检查端口映射、占用
存储故障排查:
├─ 挂载失败: 检查路径、权限、SELinux
├─ 空间不足: 清理无用资源
└─ IO问题: 检查存储驱动、配置
守护进程故障排查:
├─ 启动失败: 检查配置、端口、驱动
├─ 命令无响应: 检查进程、资源
└─ 权限问题: 检查用户、组、权限
Docker工具:
├─ docker ps: 查看容器状态
├─ docker logs: 查看容器日志
├─ docker inspect: 查看容器详情
├─ docker stats: 查看资源使用
└─ docker events: 查看Docker事件
系统工具:
├─ journalctl: 查看系统日志
├─ top/htop: 查看系统资源
├─ netstat/ss: 查看网络连接
├─ lsof: 查看文件描述符
└─ strace: 跟踪系统调用
预防措施:
✅ 定期备份重要数据
✅ 监控系统资源使用
✅ 配置日志轮转
✅ 设置资源限制
✅ 使用健康检查
✅ 配置自动重启
✅ 定期清理无用资源
✅ 文档化配置和变更
处理原则:
✅ 保持冷静,系统化排查
✅ 收集完整信息
✅ 由简到繁排查
✅ 记录排查过程
✅ 验证解决方案
✅ 总结经验教训
✅ 制定预防措施
下一章: Docker最佳实践
将学习:
容器启动失败: 一个容器启动后立即退出,如何排查问题?
镜像拉取失败: 从Docker Hub拉取镜像失败,如何解决?
网络不通: 容器无法访问外网,如何排查?
磁盘空间不足: Docker所在磁盘空间不足,如何清理?
容器频繁重启: 一个容器频繁重启,如何找出原因并解决?
Docker服务无法启动: Docker服务启动失败,如何排查?
完整故障排查: 模拟一个Docker应用故障,要求:
故障排查文档: 编写一份Docker故障排查文档,包含: