问答

docker 容器无法连接外网

作者:admin 2021-04-21 我要评论

事情是这样的: 前阵子买了 Godaddy 的服务器,然而使用 docker 部署 golang 项目时,发现无法安装依赖,一直在超时。 我在其他厂商的运行以下命令在容器中是可...

在说正事之前,我要推荐一个福利:你还在原价购买阿里云、腾讯云、华为云服务器吗?那太亏啦!来这里,新购、升级、续费都打折,能够为您省60%的钱呢!2核4G企业级云服务器低至69元/年,点击进去看看吧>>>)

事情是这样的:

前阵子买了 Godaddy 的服务器,然而使用 docker 部署 golang 项目时,发现无法安装依赖,一直在超时。

我在其他厂商的运行以下命令在容器中是可以 curl 到响应的 : docker run -i -t nginx curl baidu.com,然而在 Godaddy 买的就不行,提示超时或无主机(宿主机是可以使用 curl 的)。

尝试过在宿主机起个 server,然后容器通过 172.0xx 是可以访问到,其他域名一律不可以。

于是我查看了 dorker bridge 的区别,仅仅是在 IPAM.Config 多了个 gateway。

正常:
image.png

异常:
image.png

我曾尝试做了以下工作:

  1. 更改 /etc/resolv.conf 的 nameserver:8.8.8.8 不行
  2. 反复重启 docker
  3. 升级 docker 到20+
  4. 升级 ubuntu 到 18+
  5. 搜索了大量方案

找到了临时解决的方案:https://segmentfault.com/a/11...

问题表现

  1. 容器内部 ping 不通外网 docker run --rm alpine ping -c 2 baidu.com
  2. netstat -ntlp 没有发现端口 53
###

执行ip a命令看下docker0 网桥的ip地址在不在,这个问题就是缺少网关吧,容器访问外网的路径应该是容器ip--docker0网桥ip--默认网关

###

如果是 dns 的问题,配置一下应该是可以的,但显然不是:

$:docker run --dns=8.8.8.8 --dns=8.8.4.4 nginx curl baidu.com

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:00:19 --:--:--     0
  
  curl: (6) Could not resolve host: baidu.com

如果指定 --net 是可以的

$: docker run --net=host  nginx curl baidu.com
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:--  0:00:04 --:--:--     0<html>
<meta http-equiv="refresh" content="0;url=http://www.baidu.com/">
</html>
100    81  100    81    0     0     15      0  0:00:05  0:00:05 --:--:--    18

所以问题几乎是出在使用默认的 bridge 网络。

###

直接IP地址不通,不是路由表就是防火墙的问题。

(容器)路由表

跟踪路由跳转,正常情况下,下一跳应为宿主机。

traceroute 8.8.8.8

如果不通,检查路由

ip route | grep default

默认路由应为桥接网关地址

(容器)防火墙

如果路由表正确,检查防火墙设置。
一般容器默认不会设置防火墙。可以自行检查防火墙规则。如使用iptables

iptables -t nat -L POSTROUTING
(容器)监测数据包

如果防火墙规则正确,检查数据是否经过接口
使用tcpdump监测网络接口。如

tcpdump -i eth0
(宿主)监测数据包

如果数据经过了容器接口,检查数据是否经过在宿主机上与容器内桥接的接口。

tcpdump -i docker0
(宿主)防火墙

如果数据包已经被宿主接收,那么检查防火墙规则。
检查PREROUTING/FORWARD/POSTROUTING表,是否有拒绝或丢弃数据包的规则。

(宿主)路由配置

检查宿主机是否运行路由转发。应返回1。

sysctl net.ipv4.ip_forward
(宿主)路由表

检查路由表和路由规则。

ip route
ip rule
(宿主)监测数据包

使用tcpdump检测宿主网络出口数据。

数据包返回

如果发送一切正常,但无法收到回来的数据,检查防火墙是否启用IP伪装。

iptables -t nat -L POSTROUTING | grep masquerade
###

大佬,你好。
我现在遇到了和你完全一模一样的问题,我也已经仔细阅读过此贴,完全按照你和其他大佬的对话中的方法进行排查,现在依然无果。
我的是ESXI环境,但我刚刚使用了其他网络环境中(不是本公司)的另一台ESXI主机开了一台centos7来测试,一模一样的镜像(把现存问题的centos7镜像导入),但却没有出现此问题,网络完全正常。
我现在还剩下两个地方待排查:
1、ESXI母鸡的网络层。
2、物理网络层。
我的问题大概率是出在这两个地方上。

版权声明:本文转载自网络,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。本站转载出于传播更多优秀技术知识之目的,如有侵权请联系QQ/微信:153890879删除

相关文章
  • docker 容器无法连接外网

    docker 容器无法连接外网

  • reducer不可以对prevState进行修改吗?

    reducer不可以对prevState进行修改吗?

  • 如果你打算找工作或者换岗位,后端开发

    如果你打算找工作或者换岗位,后端开发

  • python爬虫程序报错:ConnectionResetEr

    python爬虫程序报错:ConnectionResetEr

腾讯云代理商
海外云服务器