用Docker这几年,各种奇葩问题都遇到过。整理出来,下次再遇到直接查。


一、容器无法启动

1.1 查看启动日志


# 查看容器日志

docker logs <container_id>

# 实时查看

docker logs -f <container_id>

1.2 常见原因

原因1:端口被占用


# 错误信息

Error: bind: address already in use

# 解决:查看端口占用

lsof -i :80
netstat -tlnp | grep 80

原因2:权限问题


# 错误信息

Permission denied

# 解决:修改目录权限

chmod -R 777 /data/xxx

1.3 进入失败的容器调试


# 改用交互模式启动

docker run -it --entrypoint /bin/sh <image>


二、容器内网络问题

2.1 容器无法访问外网


# 测试网络

docker run --rm alpine ping -c 3 8.8.8.8

# 如果ping不通,检查:

# 1. 宿主机能否上网

# 2. Docker网络配置

# 3. 重启Docker

systemctl restart docker

2.2 容器间无法通信


# 同一网络下的容器才能互相访问

docker network create mynet

docker run --network mynet --name app1 ...
docker run --network mynet --name app2 ...

# 可以用容器名访问

docker exec app1 ping app2

2.3 DNS解析失败


# 解决:指定DNS

docker run --dns 8.8.8.8 --dns 114.114.114.114 ...


三、存储/挂载问题

3.1 挂载目录权限问题


# 解决1:指定用户

docker run -u $(id -u):$(id -g) -v /data:/data ...

# 解决2:SELinux问题(CentOS)

docker run -v /data:/data:Z ...

3.2 磁盘空间不足


# 查看Docker占用空间

docker system df

# 清理方案

docker container prune  # 清理停止的容器
docker image prune -a   # 清理无用镜像
docker volume prune     # 清理无用数据卷
docker system prune -a  # 一键清理所有


四、镜像问题

4.1 拉取镜像失败


# 配置镜像加速器

cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors": [
"https://mirror.ccs.tencentyun.com"
]
}
EOF

systemctl daemon-reload
systemctl restart docker

4.2 镜像太大


# 优化方案:

# 1. 使用alpine基础镜像

FROM alpine:3.18

# 2. 多阶段构建

FROM golang:1.21 AS builder
RUN go build -o app

FROM alpine:3.18
COPY --from=builder /app /app


五、容器资源问题

5.1 容器占用CPU过高


# 查看容器资源使用

docker stats

# 限制CPU

docker run --cpus=2 ...

5.2 OOM Killed


# 查看是否被OOM杀掉

docker inspect <container> | grep OOMKilled

# 解决:增加内存限制

docker run -m 1g ...


六、深入理解Docker网络

6.1 Docker网络模式

模式 特点 适用场景
bridge 默认模式,NAT转发 大多数场景
host 共享宿主机网络栈 高性能需求
none 无网络 安全隔离
container 共享其他容器网络 Pod模式

6.2 容器间通信原理


容器A (172.17.0.2) → docker0网桥 → 容器B (172.17.0.3)

# 查看网桥

brctl show docker0

# 查看veth pair

ip link show | grep veth

6.3 DNS解析流程


容器内DNS查询流程:

1. /etc/resolv.conf → 127.0.0.11(Docker内置DNS)
2. Docker DNS → 容器名解析
3. 未命中 → 转发到宿主机DNS


七、容器资源限制原理

7.1 Cgroups限制

# CPU限制(--cpus=2)
cat /sys/fs/cgroup/cpu/docker/<container_id>/cpu.cfs_quota_us

# 内存限制(-m 512m)
cat /sys/fs/cgroup/memory/docker/<container_id>/memory.limit_in_bytes

7.2 OOM Killer触发条件

当容器内存使用达到限制时:
1. 内核尝试回收页面缓存
2. 回收失败 → 触发OOM Killer
3. 选择得分最高的进程kill

# 查看OOM得分
cat /proc/<pid>/oom_score

八、远程服务器排查

如果Docker服务器在公司内网,在家怎么排查?

我用星空组网把本地和服务器连起来,然后直接SSH上去操作:

# 组网后直接连
ssh root@192.168.188.10
docker logs xxx
docker exec -it xxx /bin/sh

比VPN稳定,也不用申请跳板机权限,排查效率高很多。


十、常用排查命令汇总

# 容器状态
docker ps -a                    # 所有容器
docker inspect <container>      # 容器详情
docker logs <container>         # 容器日志

# 资源使用
docker stats                    # 资源统计
docker system df                # 磁盘占用

# 进入容器
docker exec -it <container> /bin/bash

# 清理
docker system prune -a          # 清理所有

八、快速排查流程

遇到容器问题,按这个顺序排查:

1. docker ps -a        → 看容器状态
2. docker logs xxx     → 看启动日志
3. docker inspect xxx  → 看详细配置
4. docker exec -it xxx /bin/sh → 进入容器调试
5. docker stats        → 看资源使用

总结

Docker排错核心思路:

问题类型 排查方向
启动失败 看日志、检查端口、检查权限
网络问题 检查网络模式、DNS、防火墙
存储问题 检查权限、SELinux、磁盘空间
性能问题 docker stats、限制资源

记住:docker logs是第一步

有问题评论区交流~


更多推荐