网站首页 > 基础教程 正文
最近在使用Docker时,可能会遇到容器无法访问外网的问题。本篇文章记录了一个从问题发现到最终解决的完整过程,涵盖了问题分析、尝试解决方案以及最终的成功经验,希望能为遇到类似问题的读者提供参考。
背景
在某次部署Docker服务时,我发现运行的容器无法访问外网。例如,执行以下命令时:
sudo docker run --rm alpine ping -c 4 security.ubuntu.com
容器内返回的结果是:
ping: bad address 'security.ubuntu.com'
通过多次排查后发现,问题不仅仅是DNS配置的问题,而是与宿主机的多网卡和网络路由冲突相关。本篇记录了问题的完整解决过程。
问题分析
初步排查
- 检查容器内的DNS配置: 使用以下命令进入容器并查看DNS配置:
sudo docker run --rm -it alpine sh
cat /etc/resolv.conf
结果显示DNS配置正确:
nameserver 8.8.8.8
nameserver 8.8.4.4
- 测试直接访问IP地址: 在容器中尝试直接访问 security.ubuntu.com 的IP地址:
ping -c 4 91.189.91.81
结果同样无法访问。这表明问题不仅仅是DNS解析,而是网络连接本身的问题。
- 检查宿主机的Docker网桥 (docker0) 状态:
ip link show docker0
结果显示 docker0 的状态为 DOWN,说明Docker的默认网桥未正常工作。
- 查看宿主机路由表:
ip route
路由表显示存在多个默认网关:
default via 192.168.2.1 dev ens32 proto static
default via 122.147.187.1 dev ens33 proto static
这表明宿主机存在两个网卡(ens32 和 ens33),并且都配置了默认路由,可能导致路由冲突。
解决问题的尝试过程
1. 重建Docker网桥 (docker0)
首先尝试手动删除并重建 docker0 网桥:
sudo ip link set docker0 down
sudo brctl delbr docker0
sudo brctl addbr docker0
sudo ip addr add 192.168.200.1/24 dev docker0
sudo ip link set docker0 up
重新启动Docker服务后,检查 docker0 的状态为 UP:
ip addr show docker0
尽管 docker0 已正常工作,但容器内的网络问题依然存在。
2. 强制刷新和重建NAT配置
尝试清空并重建宿主机的NAT配置:
sudo iptables -t nat -F
sudo iptables -t nat -A POSTROUTING -s 172.17.0.0/16 ! -d 172.17.0.0/16 -j MASQUERADE
sudo iptables -P FORWARD ACCEPT
重新启动Docker服务并测试容器网络,问题仍未解决。
3. 修改Docker默认网桥IP
怀疑 docker0 使用的IP段可能与现有网络冲突,于是修改Docker默认网桥的IP段。
编辑 /etc/docker/daemon.json:
{
"dns": ["8.8.8.8", "8.8.4.4"],
"bip": "192.168.200.1/24"
}
重新启动Docker服务:
sudo systemctl restart docker
问题依然未解决。
4. 禁用多余网卡(ens32)
发现宿主机中存在两个网卡,并且都设置了默认路由。怀疑这是导致网络流量被错误路由的原因。
临时禁用 ens32:
sudo ip link set ens32 down
禁用后,容器内的网络测试成功:
sudo docker run --rm alpine ping -c 4 security.ubuntu.com
最终解决方案
经过排查,确认问题根源是宿主机的多网卡和多默认路由配置冲突。以下是最终的解决方案:
修改Netplan配置
编辑宿主机的 netplan 配置文件 /etc/netplan/*.yaml,确保只有一个默认网关(保留 ens33):
network:
version: 2
ethernets:
ens32:
addresses:
- 192.168.2.95/24
nameservers:
addresses: []
search: []
ens33:
addresses:
- 122.147.187.95/24
nameservers:
addresses:
- 168.95.1.1
- 8.8.8.8
search: []
routes:
- to: default
via: 122.147.187.1
应用Netplan配置
sudo netplan apply
验证路由表,确保只有一个默认路由:
ip route
结果应类似于:
default via 122.147.187.1 dev ens33 proto static
192.168.2.0/24 dev ens32 proto kernel scope link src 192.168.2.95
测试和验证
- 测试容器的DNS解析:
sudo docker run --rm alpine nslookup security.ubuntu.com
- 测试容器的外网连接:
sudo docker run --rm alpine ping -c 4 security.ubuntu.com
- 结果:
- 容器内的网络恢复正常。
- 宿主机的多网卡冲突问题解决。
总结
本次问题的根源是宿主机的多网卡和多默认网关配置冲突,导致Docker容器的网络流量无法正确路由到外网。通过以下步骤最终解决了问题:
- 删除多余的默认网关。
- 修改 netplan 配置,确保宿主机只有一个默认路由。
- 调整Docker的默认网桥配置。
通过这次排查,可以更加深入理解了Docker的网络机制以及宿主机网络配置的重要性,希望这篇备忘录能帮助遇到类似问题的读者快速定位和解决问题。
猜你喜欢
- 2025-01-20 Docker下var/lib/docker/overlay2空间清理办法
- 2025-01-20 Docker容器基于WebDav通过Alist挂载(百度网盘/阿里云盘)
- 2025-01-20 dcoker之容器数据卷,以及定制镜像Dockerfile配置与设置
- 2025-01-20 Docker ToolBox 如何重置环境?
- 2025-01-20 【收藏】Docker容器高频率使用命令整理
- 2025-01-20 39K Star!一款超好用 Docker 终端工具!
- 2025-01-20 开源分布式系统追踪-03-CNCF jaeger-02-如何通过 docker 安装?
- 2025-01-20 docker基础知识/尚硅谷docker学习笔记
- 2025-01-20 七、Docker-PS命令解析
- 2025-01-20 使用Docker轻松搭建DNS服务器
- 05-162025前端最新面试题之HTML和CSS篇
- 05-16大数据开发基础之HTML基础知识
- 05-16微软专家告诉你Win10 Edge浏览器和EdgeHTML的区别
- 05-16快速免费将网站部署到公网方法(仅支持HTML,CSS,JS)
- 05-16《从零开始学前端:HTML+CSS+JavaScript的黄金三角》
- 05-16一个简单的标准 HTML 设计参考
- 05-16css入门
- 05-16前端-干货分享:更牛逼的CSS管理方法-层(CSS Layers)
- 最近发表
- 标签列表
-
- jsp (69)
- pythonlist (60)
- gitpush (78)
- gitreset (66)
- python字典 (67)
- dockercp (63)
- gitclone命令 (63)
- dockersave (62)
- linux命令大全 (65)
- pythonif (86)
- location.href (69)
- dockerexec (65)
- deletesql (62)
- c++模板 (62)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- console.table (62)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)