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

新手上路,请多包涵

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

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

 docker run -p 8080:8080 dockertest

这有效, 我可以通过 docker 的机器 IP (启动时出现在 Docker 快速启动终端 上的那个)访问服务器,问题是我 无法从主机外部访问我托管的网站, 所以如果我尝试要在我的手机上打开相同的 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 转发或其他东西有关,但我是网络方面的一个完全菜鸟,我我主要是一名网络开发人员,几乎没有本地经验。

原文由 redsalt 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 517
2 个回答

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)并且您将能够访问你的 Docker 容器在 http://L:8080/

如果 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 配置窗口,则可以进行如下所述的更改。还有一个命令行客户端可以修改虚拟机,但我不熟悉。

对于 bridged 模式(这确实是最简单的选择),关闭您的虚拟机,单击顶部的“设置”按钮,并将网络模式更改为 bridged ,然后重新启动虚拟机,你很高兴。 VM 应该通过 DHCP 在您的本地网络上获取一个 IP 地址,并且应该对网络上具有该 IP 地址的其他计算机可见。

原文由 Kryten 发布,翻译遵循 CC BY-SA 3.0 许可协议

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

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

原文由 Davey Chu 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题