如何从 docker 容器访问主机端口

新手上路,请多包涵

我有一个运行 jenkins 的 docker 容器。作为构建过程的一部分,我需要访问在主机上本地运行的 Web 服务器。有没有办法可以将主机 Web 服务器(可以配置为在端口上运行)暴露给 jenkins 容器?

我在 Linux 机器上本地运行 docker。

更新:

除了下面的@larsks 回答,要从主机获取主机 IP 的 IP 地址,我执行以下操作:

 ip addr show docker0 | grep -Po 'inet \K[\d.]+'

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

阅读 1.5k
2 个回答

在 Linux 上原生运行 Docker 时,可以使用 docker0 接口的 IP 地址访问主机服务。从容器内部,这将是您的默认路线。

例如,在我的系统上:

 $ ip addr show docker0
7: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
    link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::f4d2:49ff:fedd:28a0/64 scope link
       valid_lft forever preferred_lft forever

在容器内:

 # ip route show
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0  src 172.17.0.4

使用一个简单的 shell 脚本很容易提取这个 IP 地址:

 #!/bin/sh

hostip=$(ip route show | awk '/default/ {print $3}')
echo $hostip

您可能需要修改主机上的 iptables 规则以允许来自 Docker 容器的连接。像这样的东西可以解决问题:

 # iptables -A INPUT -i docker0 -j ACCEPT

这将允许从 Docker 容器访问主机上的任何端口。注意:

  • iptables 规则是有序的,这条规则可能会也可能不会做正确的事情,这取决于它之前的其他规则。

  • 您将只能访问正在 (a) 监听 INADDR_ANY (又名 0.0.0.0)或明确监听 docker0 接口的主机服务。


如果您在 MacOSWindows 18.03+ 上使用 Docker,则可以连接到神奇的主机名 host.docker.internal


最后,在 Linux 下,您可以通过设置 --net=host 在主机网络命名空间中运行容器;在这种情况下,您主机上的 localhost localhost 与容器内的 --- 相同,因此容器化服务将像非容器化服务一样运行,无需任何额外配置即可访问。

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

适用于所有平台

Docker v 20.10 及更高版本(自 2020 年 12 月 14 日起)

在 Linux 上,将 --add-host=host.docker.internal:host-gateway 添加到 Docker 命令以启用此功能。 (有关 Docker Compose 配置,请参见下文。)

使用您的内部 IP 地址或连接到特殊的 DNS 名称 host.docker.internal 这将解析为主机使用的内部 IP 地址。

要在 Linux 上的 Docker Compose 中启用此功能,请将以下几行添加到容器定义中:

 extra_hosts:
- "host.docker.internal:host-gateway"

适用于 macOS 和 Windows

Docker v 18.03 及更高版本(自 2018 年 3 月 21 日起)

使用您的内部 IP 地址或连接到特殊的 DNS 名称 host.docker.internal 这将解析为主机使用的内部 IP 地址。

Linux 支持待定 https://github.com/docker/for-linux/issues/264

带有早期版本 Docker 的 MacOS

Docker for Mac v 17.12 到 v 18.02

与上述相同,但使用 docker.for.mac.host.internal 代替。

Docker for Mac v 17.06 到 v 17.11

与上述相同,但使用 docker.for.mac.localhost 代替。

适用于 Mac 17.05 及更低版本的 Docker

要从 docker 容器访问主机,您必须将 IP 别名附加到网络接口。你可以绑定任何你想要的IP,只要确保你没有将它用于其他任何东西。

sudo ifconfig lo0 alias 123.123.123.123/24

然后确保您的服务器正在侦听上述 IP 或 0.0.0.0 。如果它正在监听 localhost 127.0.0.1 它不会接受连接。

然后只需将你的 docker 容器指向这个 IP,你就可以访问主机了!

要进行测试,您可以在容器内运行 curl -X GET 123.123.123.123:3000 之类的东西。

别名将在每次重新启动时重置,因此如有必要,请创建一个启动脚本。

解决方案和更多文档: https ://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds

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

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