15.4.7 容器故障排查与恢复
容器故障排查与恢复#
本节以“快速定位—最小影响—可回滚”为主线,结合常见故障场景给出可执行诊断流程、命令与恢复操作,并提供练习任务用于实战演练。
原理草图:故障定位路径#
诊断流程与关键命令(含解释与示例)#
- 确认容器状态
- 查看状态、退出码、重启次数:
docker ps -a --format "table {{.Names}}\t{{.Status}}\t{{.Image}}\t{{.RunningFor}}"
# 预期:显示 Restarting/Exited 状态与退出原因提示
- 查看配置与挂载、网络与健康检查:
docker inspect myapp --format 'Status={{.State.Status}} Exit={{.State.ExitCode}} Health={{.State.Health.Status}}'
# 解释:State.ExitCode 判断异常退出类型;Health 确认健康检查状态
- 检查日志与事件
- 获取容器启动失败或异常退出日志:
docker logs --tail 200 myapp
# 解释:--tail 200 只取最后 200 行,便于快速定位
- 查看近期事件(重启/oom/kill):
docker events --since 1h | grep myapp
# 解释:事件流可能出现 OOM、die、restart 等关键字
- 核对资源与限制
docker stats myapp --no-stream
# 解释:CPU/MEM/IO 实时资源,快速判断是否因限制导致异常
docker inspect myapp --format 'Mem={{.HostConfig.Memory}} OOMKill={{.HostConfig.OomKillDisable}}'
# 解释:Memory 为字节数;OOMKillDisable=true 可能导致系统更大影响
- 进入容器验证进程与端口
docker exec -it myapp sh -c "ps aux | head -n 5; ss -lntp"
# 解释:确认进程是否存在、端口是否监听
- 验证外部依赖
docker exec -it myapp sh -c "nslookup mysql && nc -zv mysql 3306"
# 解释:DNS 与端口探测;若失败,检查网络与依赖服务
常见故障场景与处理(含示例)#
- 启动失败(Exit Code 125/126/127)
- 125:Docker 调用失败,检查参数或权限。
- 126:命令不可执行,检查脚本权限。
- 127:命令未找到,检查镜像依赖与 PATH。
docker ps -a --format "table {{.Names}}\t{{.Status}}\t{{.Command}}"
docker logs myapp
# 预期:日志显示权限或命令缺失
修复示例(脚本权限):
docker exec -it myapp sh -c "ls -l /entrypoint.sh"
# 若无执行权限,重新构建镜像或临时修复
- 应用异常退出(Exit Code 1/137)
docker inspect myapp --format 'Exit={{.State.ExitCode}} OOM={{.State.OOMKilled}}'
# Exit=137 且 OOMKilled=true 表示内存不足
调整资源示例:
docker rm -f myapp
docker run -d --name myapp --memory 512m --memory-swap 512m myimage:stable
# 预期:容器不再因 OOM 重启
- 健康检查失败导致重启
docker inspect myapp --format 'Health={{.State.Health.Status}}'
docker inspect myapp --format '{{json .Config.Healthcheck}}'
修改 healthcheck 示例(Dockerfile 片段):
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD curl -fsS http://127.0.0.1:8080/health || exit 1
- 网络连通性问题
docker exec -it myapp sh -c "ip a; ip route; cat /etc/resolv.conf"
docker exec -it myapp sh -c "ping -c 2 8.8.8.8"
# 解释:验证路由与 DNS 是否正确
- 存储与数据问题
docker inspect myapp --format '{{json .Mounts}}' | jq
# 解释:确认绑定目录/卷挂载是否正确
修复挂载示例:
docker rm -f myapp
docker run -d --name myapp -v /data/app:/var/lib/app myimage:stable
恢复与回滚操作(带完整示例)#
- 快速恢复(重启/重建)
docker restart myapp
# 预期:状态变为 Up
docker rm -f myapp
docker run -d --name myapp -p 8080:8080 -v /data/app:/var/lib/app myimage:stable
# 解释:重建容器,保留数据卷
- 版本回滚
docker pull myimage:stable
docker rm -f myapp
docker run -d --name myapp myimage:stable
# 解释:使用稳定标签回滚
- 数据恢复(示例:使用 tar 恢复卷数据)
# 备份示例:docker run --rm -v /data/app:/data -v $(pwd):/backup alpine \
# sh -c "tar -czf /backup/app-$(date +%F).tgz -C /data ."
# 恢复示例
docker run --rm -v /data/app:/data -v $(pwd):/backup alpine \
sh -c "tar -xzf /backup/app-2024-01-01.tgz -C /data"
# 预期:数据目录恢复到 /data/app
实战排错示例(端到端)#
场景:容器频繁重启,日志显示“Out of memory”。
docker ps -a | grep myapp
docker inspect myapp --format 'Exit={{.State.ExitCode}} OOM={{.State.OOMKilled}}'
docker logs --tail 50 myapp
docker stats myapp --no-stream
处理步骤:
docker rm -f myapp
docker run -d --name myapp --memory 1g --memory-swap 1g myimage:stable
验证:
docker ps | grep myapp
docker inspect myapp --format 'Status={{.State.Status}} Health={{.State.Health.Status}}'
命令速查(带用途说明)#
docker ps -a:查看容器状态、退出与重启信息docker logs <id>:应用日志与启动失败原因docker inspect <id>:配置、挂载、网络、健康检查、资源限制docker stats:实时资源占用docker events --since 1h:事件追踪(OOM、kill、restart)docker exec -it <id> sh:进入容器排查进程、端口与配置docker rm -f <id>:强制删除异常容器docker restart <id>:快速恢复
练习#
- 构造一个启动失败容器(入口脚本无执行权限),用
docker logs和inspect定位问题并修复。 - 将容器内存限制设置为 64MB,触发 OOM 后通过
inspect确认原因并调整到 256MB。 - 人为配置错误 DNS,使用容器内
nslookup和ping定位网络故障并恢复。 - 模拟数据卷挂载错误,修正挂载路径后恢复服务。