当 Docker 容器无法 ping 通时,可能是多种网络配置问题导致的。以下是系统的排查步骤和解决方案:
# 首先检查宿主机网络是否正常
ping 8.8.8.8
# 检查容器是否能解析DNS
docker run --rm busybox ping -c 4 google.com
# 查看容器的网络模式
docker inspect <container_id> | grep NetworkMode
# 如果是none模式,容器将没有网络
解决方案: - 使用默认的bridge模式或host模式运行容器
docker run --network bridge ...
# 或
docker run --network host ...
# 检查iptables规则
sudo iptables -L -n
# 检查firewalld
sudo firewall-cmd --list-all
解决方案:
# 临时关闭防火墙测试
sudo systemctl stop firewalld
# 或
sudo ufw disable
# 永久允许Docker流量
sudo firewall-cmd --permanent --zone=trusted --add-interface=docker0
sudo firewall-cmd --reload
# 列出所有Docker网络
docker network ls
# 检查网络详情
docker network inspect <network_name>
解决方案: - 创建新的bridge网络
docker network create my_network
docker run --network=my_network ...
# 获取容器IP
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container_id>
# 测试从另一个容器ping该IP
docker run --rm -it busybox ping <container_ip>
解决方案: - 确保容器在同一网络中 - 使用容器名而非IP(Docker内置DNS)
# 从宿主机ping容器
ping <container_ip>
# 从容器ping宿主机
docker exec <container_id> ping <host_ip>
解决方案:
- 确保docker0网桥配置正确
- 检查路由表:ip route show
# 查看容器的网络命名空间
docker inspect -f '{{.State.Pid}}' <container_id>
sudo nsenter -t <pid> -n ip a
# 在宿主机上抓取docker0接口流量
sudo tcpdump -i docker0 -nn -vv
# 在容器内抓包
docker run --rm --net=host nicolaka/netshoot tcpdump -i eth0 -nn -vv
docker run --rm -it nicolaka/netshoot
# 检查NAT规则
sudo iptables -t nat -L -n
# 解决方案:启用IP转发
echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
# 解决方案:使用用户自定义网络
docker network create mynet
docker run --network=mynet --name=container1 ...
docker run --network=mynet --name=container2 ...
# 在/etc/docker/daemon.json中添加
{
"ipv6": true,
"fixed-cidr-v6": "2001:db8:1::/64"
}
如果以上方法仍不能解决问题,请提供以下信息以便进一步诊断:
- docker version
- docker info
- ifconfig
或 ip a
- iptables -L -n -v
- 具体错误信息和复现步骤