如何从主机外部(同一网络)连接到docker容器[Windows]

问题描述 投票:62回答:7

我创建了我的第一个docker容器,它使用Go运行服务器,但我无法从主机外部访问它。我刚刚开始使用码头工具,所以我有点迷失在这里。

所以我有一个非常简单的Go代码启动服务器,我已经构建了docker镜像,它安装Go并在Linux基础映像中构建代码。我在端口8080上运行服务器,所以我将该端口暴露给运行容器的主机,如下所示:

docker run -p 8080:8080 dockertest

这工作,我通过docker的机器IP(启动时出现在Docker Quickstart终端上的那个)访问服务器,问题是我无法访问我从主机外部托管的网站,所以如果我尝试要在我的手机上打开相同的IP地址,它只会给我一个错误:此网页不可用(ERR_CONNECTION_TIMED_OUT)。

我也试过像这样指定IP:

docker run -p 192.168.0.157:8080:8080 dockertest

但是,当我这样做时,我可以通过上面的命令行上的docker机器的IP和指定的IP访问该网站。我也不确定我应该在该命令中使用我的计算机IP写入哪个IP,我也尝试过127.0.0.1(localhost),但这给了我相同的结果:无法访问任何网站知识产权无论如何。

我已经搜索了这个问题,发现了许多StackOverflow问题但是没有帮助我解决我的问题,其中大多数都面向Linux或Mac,所以解决方案不适用于我的情况。

此外,我可以在我的计算机上运行Go代码,并通过我的计算机的IP从同一网络中的另一台设备访问该网站。我不明白为什么我在docker机器上运行它时无法访问它,我想到它可能与IP转发或其他东西有关但我在网络中是一个完整的菜鸟,我我主要是一名网络开发人员,几乎没有本地人的经验。

windows docker virtualbox
7个回答
72
投票

TL; DR检查VirtualBox主机的网络模式 - 如果您希望在本地网络上访问虚拟机(以及它托管的Docker容器),则应该是bridged


听起来你的困惑在于连接哪个主机以便通过HTTP访问你的应用程序。你还没有真正说明你的配置是什么 - 我会根据你的标签中有“Windows”和“VirtualBox”的事实做出一些猜测。

我猜你有一个Docker在Windows主机上的VirtualBox中运行的某些Linux上运行。我要将IP地址标记如下:

D = Docker容器的IP地址

L =在VirtualBox中运行的Linux主机的IP地址

W = Windows主机的IP地址

在Windows主机上运行Go应用程序时,可以从本地网络上的任何位置使用http://W:8080/连接到该应用程序。这是有效的,因为Go应用程序绑定Windows机器上的端口8080,并且任何尝试访问IP地址W上的端口8080的人都将连接。

而这里变得更加复杂:

VirtualBox在设置虚拟机(VM)时,可以在几种不同模式中的一种模式下配置网络。我不记得所有不同的选项是什么,但你想要的是bridged。在此模式下,VirtualBox将虚拟机连接到本地网络,就好像它是网络上的独立计算机一样,就像插入网络的任何其他计算机一样。在bridged模式下,虚拟机与任何其他计算机一样出现在您的网络中。其他模式设置不同,机器将无法在您的网络上显示。

因此,假设您为Linux主机(bridged)正确设置了网络,Linux主机将在您的本地网络上具有IP地址(类似于192.168.0.x),您将能够访问http://L:8080/上的Docker容器。

如果Linux主机设置为bridged以外的某种模式,您可以从Windows主机访问,但这将取决于它所处的模式。

编辑 - 根据下面的评论,听起来非常像我上面描述的情况是正确的。

让我们稍微回顾一下:这就是Docker在我的计算机上运行的方式(Ubuntu Linux)。

想象一下,我运行的命令与你一样:docker run -p 8080:8080 dockertest。这样做是基于dockertest映像和Linux主机(我的PC)上的前向(连接)端口8080启动一个新容器到容器上的端口8080。 Docker设置自己的内部网络(具有自己的IP地址集),以允许Docker守护程序进行通信并允许容器相互通信。所以基本上你正在做的-p 8080:8080正在将Docker的内部网络与“外部”网络连接起来 - 即。主机的网络适配器 - 在特定端口上。

和我一起到目前为止?好的,现在让我们退一步看看你的系统。您的计算机正在运行Windows - Docker当前没有在Windows上运行,因此您使用的工具已在VirtualBox虚拟机中设置了Linux主机。当您在您的环境中执行docker run时,发生的情况完全相同 - Linux主机上的端口8080连接到容器上的端口8080。这里最大的区别是你的Windows主机不是运行容器的Linux主机,所以这里有另一层,它在这个层的通信中遇到了问题。

你需要的是两件事之一:

  1. 将VirtualBox VM上的端口8080连接到Windows主机上的端口8080,就像将Docker容器连接到主机端口一样。
  2. 使用上面描述的bridged网络模式将VirtualBox VM直接连接到本地网络。

如果您选择第一个选项,则可以访问http://W:8080上的容器,其中W是Windows主机的IP地址或主机名。如果您选择第二个,您将能够访问http://L:8080上的容器,其中L是Linux VM的IP地址或主机名。

这就是所有更高级别的解释 - 现在您需要弄清楚如何更改VirtualBox VM的配置。在这里,我无法真正帮助你 - 我不知道你在Windows机器上使用什么工具来完成所有这些工作而且我并不熟悉在Windows上使用Docker。

如果您可以进入VirtualBox配置窗口,则可以进行如下所述的更改。还有一个命令行客户端将修改VM,但我不熟悉它。

对于bridged模式(这实际上是最简单的选择),关闭您的VM,单击顶部的“设置”按钮,然后将网络模式更改为bridged,然后重新启动VM,您就可以开始使用了。 VM应通过DHCP在本地网络上获取IP地址,并且应该对该IP地址的网络上的其他计算机可见。


98
投票
  1. 打开Oracle VM VirtualBox Manager
  2. 选择Docker使用的VM
  3. 单击设置 - >网络
  4. 适配器1应该(默认?)是“附加到:NAT”
  5. 单击“高级” - >“端口转发”
  6. 添加规则:协议TCP,主机端口8080,访客端口8080(保留主机IP和访客IP为空)
  7. Guest是您的docker容器,Host是您的机器

您现在应该可以通过localhost:8080和your-internal-ip:8080浏览到您的容器。


4
投票

在尝试了几件事后,这对我有用:

  • 使用--publish = 0.0.0.0:8080:8080 docker标志
  • 将虚拟盒网络模式设置为NAT,不使用任何端口转发

除了0.0.0.0以外的地址,我没有成功。


2
投票

TLDR:如果启用了Windows防火墙,请确保专用网络上的“vpnkit”存在例外情况。

对于我的特定情况,当我尝试从本地网络上的另一台机器访问我的容器的已发布端口时,我发现Windows防火墙阻止了我的连接,因为禁用它使一切正常。

但是,我不想完全禁用防火墙,因此我可以访问我的容器服务。这就提出了一个问题,即“app”代表我的容器服务正在监听。在找到another SO thread教我使用netstat -a -b来发现我机器上的监听套接字背后的应用程序之后,我了解到它是vpnkit.exe,它已经在我的Windows防火墙设置中有一个条目:但是“私有网络”被禁用了,并且一旦我启用它,我就可以从另一台机器访问我的容器服务,而无需完全禁用防火墙。


1
投票

这是Windows用户运行Docker容器时面临的最常见问题。国际海事组织这是“关于Docker的百万美元问题”; @“Rocco Smit”正确指出“我的主机防火墙默认禁用入站流量”;就我而言,我的McAfee Anti Virus软件。我在McAfee的防火墙设置中为同一Wifi LAN上的其他计算机添加了允许来自其他计算机的其他端口;那真是太神奇了。我曾经挣扎了一个多星期浏览互联网,SO,Docker文档,与Docker网络相关的教程之后的教程,以及“macvlan”,“ipvlan”,“用户”的“Windows不支持”的许多插图定义了桥梁“甚至同样的SO线程几次。我甚至开始使用“生产中使用Docker的任何人?”开始浏览谷歌,(是的,我知道Linux比Prod工作负载更受欢迎,因为我无法访问(来自同一家庭wifi中的移动设备)nginx应用程序部署在Windows上的Docker Container中。毕竟,如果你不能至少从同一局域网中的其他计算机/设备访问应用程序(部署在Docker容器上),它会有什么好处;最终在我的情况下,问题只是防火墙阻止了入站流量;


1
投票

我无法相信您无法从主机外部建立与Docker容器的连接。我已经使用Docker一年多了,并在Linux上设置了系统。本周是我第一次使用Docker for Windows,我很震惊,在主机上创建套接字很困难。

有没有解决这个问题的方法,还是我真的需要在具有桥接适配器的VM中运行docker?


0
投票

我发现除了设置-p端口值之外,Docker for Windows使用vpnkit和入站流量,因为它在我的主机防火墙上默认禁用。在为vpnkit启用入站TCP规则后,我能够从本地网络上的其他计算机访问我的容器。

© www.soinside.com 2019 - 2024. All rights reserved.