无法从桥接网络上的 Docker 容器内部访问 HTTP

mar*_*esa 0 networking vagrant docker

我的开发环境是 Vagrant (VirtualBox) Linux 服务器,上面运行着 MySQL(端口 3306)和 Tomcat(端口 18080)。这是我运行 Docker 的主机服务器。

我需要在 docker 内运行另一个服务,连接到主机上的 MySQL 和 Tomcat 服务器以及任何外部 Web 服务器。

我发现MySQL到主机的连接是好的。但是,与 HTTP(端口 80 或 443)的连接将超时。如果我在 Mac 上(在 Vagrant 之外)运行相同的 Docker 镜像,我就可以连接到 MySQL 和任何外部 Web 服务器。

详细信息如下:

在我的主机上(Vagrant)

[root@my Downloads]# ip addr show docker0
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:95:b0:5e:47 brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.1/24 brd 192.168.100.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:95ff:feb0:5e47/64 scope link 
       valid_lft forever preferred_lft forever
[root@my Downloads]# 
Run Code Online (Sandbox Code Playgroud)

我进入 Docker 并尝试连接到主机的 MySQL。这很好用。

[root@my Downloads]# docker exec -it myDocker sh
/opt/myDocker # nc 192.168.100.1 3306
Q
5.7.26-29-logf"}1
                 Q&
                   ??S???&z GTP[a{mysql_native_passwordasdasd
!??#08S01Got packets out of order^Cpunt!

/opt/myDocker # 
Run Code Online (Sandbox Code Playgroud)

但如果我尝试连接到 HTTP,它就不起作用。

/opt/myDocker # nc 192.168.100.1 18080
/opt/myDocker # nc www.google.com 80
GET /
/opt/myDocker # GET /
sh: GET: not found
/opt/myDocker # 
Run Code Online (Sandbox Code Playgroud)

连接到我的主机 18080 上的 Tomcat 将返回到提示符。google.com 的那个会挂在那里一段时间,然后返回提示。

我在主机(Vagrant VM)上尝试了https://docs.docker.com/network/bridge/中提到的以下内容,但没有帮助。

sysctl net.ipv4.conf.all.forwarding=1
iptables -P FORWARD ACCEPT
Run Code Online (Sandbox Code Playgroud)

我没主意了。有人可以帮忙吗?

编辑1:我认为这一定与桥接网络有关。我在具有主机网络的同一虚拟机上尝试了另一个泊坞窗,效果很好。

/dokcer2 # nc 192.168.100.1 18080
GET /



<!DOCTYPE html >
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
    <meta name="theme-color" content="#000000">
    <link rel="shortcut icon" href="/auth/images/favicon.ico?v=13"/>
    <link rel="stylesheet" type="text/css" href="/auth/static/styles/main.a7589877fc3cc07b7ac7.css"/>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="loginAppRoot"></div>
<script type="text/javascript" src="/auth/static/js/main.f5071db7f71c2283a0f9.js"></script>
</body>
</html>^Cpunt!

/docker2 # nc www.google.com 80
GET /
HTTP/1.0 200 OK
Date: Sun, 15 Nov 2020 05:21:20 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=ISO-8859-1
... yada yada yada redacted ...
Run Code Online (Sandbox Code Playgroud)

rzl*_*vmp 5

  1. 好的,首先我建议更好地了解 docker 网络(以及所有网络)

Docker 网络概述

Docker 桥接网络

绑定集装箱端口

  1. 在你的情况下:

虚拟机内网为10.0.2.0/24(桥接接口10.0.2.1)
Docker内网为192.168.100.0/24(桥接接口192.168.100.1)

当您尝试连接到虚拟机时,您使用的是 10.0.2.11,而不是 10.0.2.1(即桥接接口),
Docker 的网络是相同的。您无法直接通过 192.168.100.1 访问 192.168.100.11 的容器,因为您无法从 192.168.0.X 访问 10.0.2.1。
您需要将 192.168.100.0/24 的端口绑定(转发)到 10.0.2.0/24,并通过 10.0.2.X 访问您的服务。
如何绑定端口?请参阅Binding container ports链接
Docker 的内部网络(我图中的浅蓝色)仅适用于 Docker。

码头网络