我创建了我的第一个 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 许可协议
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 主机,因此这里还有另一层,它是跨该层的通信,您会遇到问题。您需要的是以下两件事之一:
将 VirtualBox VM 上的 8080 端口连接到 Windows 主机上的 8080 端口,就像将 Docker 容器连接到主机端口一样。
使用上面描述的
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 地址的其他计算机可见。