繁体   English   中英

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

[英]How to connect to a docker container from outside the host (same network) [Windows]

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

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

docker run -p 8080:8080 dockertest

那行得通,我可以通过 docker 的机器 IP启动时出现在Docker 快速入门终端上的那个IP)访问服务器,问题是我无法从主机外部访问我托管的网站,所以如果我尝试要在我的手机上打开相同的 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) 但这给了我相同的结果:无法通过任何方式访问网站任何IP。

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

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

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

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

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


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

我猜你在 Windows 主机上的 VirtualBox 中运行了某种 Linux 版本的 Docker。 我将按如下方式标记 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 容器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 地址的网络上的其他计算机应该可以看到该地址。

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

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

对于0.0.0.0以外的地址,我没有成功。

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

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

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

这是 Windows 用户在运行 Docker 容器时面临的最常见问题。 IMO 这是“关于 Docker 的百万美元问题”; @“Rocco Smit”正确地指出“我的主机防火墙默认禁用了它的入站流量”; 就我而言,我的迈克菲防病毒软件。 我在 McAfee 的防火墙设置中添加了额外的端口,以允许来自同一 Wifi LAN 上的其他计算机的入站流量; 那就太神奇了。 我花了一个多星期的时间浏览互联网、SO、Docker 文档、与 Docker 网络相关的教程之后的教程,以及“macvlan”、“ipvlan”、“用户”的“Windows 不支持”的许多插图定义的桥接”,甚至多次使用相同的 SO 线程。 我什至开始浏览谷歌,“有人在生产中使用 Docker 吗?”,(是的,我知道与 Windows 服务器相比,Linux 在 Prod 工作负载中更受欢迎),因为我无法访问(从我的手机在同一个家庭 wifi 中)一个 nginx部署在 Windows 上的 Docker 容器中的应用程序。 毕竟,如果您至少无法从同一 LAN 中的其他计算机/设备访问应用程序(部署在 Docker 容器上),这有什么好处; 最终,就我而言,问题只是防火墙阻止了入站流量;

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

我尝试了很多东西,但没有任何效果,最后我使用我机器的 IP 地址访问了 docker 主机按照步骤操作

  1. 打开命令
  2. IPCONFIG /所有
  3. 查找 IPV4 地址,在我的例子中是 192.168.1.7
  4. 然后我使用映射端口访问了托管在 docker 容器中的应用程序
  5. 就我而言,我尝试访问作为容器托管的 Jenkins 应用程序
  6. 简单地工作 192.168.1.7:50000
  7. 以同样的方式,我能够访问使用 docker 托管的所有容器应用程序

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM