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

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

编辑:我在Linux机器上本机运行docker。

更新:

除了@larsks回答下面,为了从主机获取主机IP的IP地址,我做了以下几点:

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

在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接口。

macOS的解决scheme

Docker for Mac v 17.06及以上版本(2017年6月)

连接到特殊的仅限于Mac的DNS名称docker.for.mac.localhost ,该名称将parsing为主机使用的内部IP地址。 (感谢用户@Kyr)

Docker for Mac 17.05及以下版本

要从Docker容器访问主机,您必须将IP别名附加到您的networking接口。 你可以绑定任何你想要的IP,只要确保你没有使用它就可以了。

sudo ifconfig lo0 alias 123.123.123.123/24

然后确保你的服务器正在监听上面提到的IP或0.0.0.0 。 如果它正在本地主机127.0.0.1上侦听,它将不会接受连接。

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

为了testing你可以在容器里运行curl -X GET 123.123.123.123:3000这样的东西。

别名将在每次重新启动时重置,因此必要时创build启动脚本。

解决scheme和更多文档在这里: https : //docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds

当你有两个docker图像“已经”创build,你想把两个容器相互沟通。

为此,您可以方便地使用自己的–name运行每个容器,并使用–link标志来启用它们之间的通信。 不过在docker build中你不会得到这个。

当你在像我这样的场景中,这是你的

 docker build -t "centos7/someApp" someApp/ 

当你尝试的时候会打破

 curl http://172.17.0.1:localPort/fileIWouldLikeToDownload.tar.gz > dump.tar.gz 

并且你卡在“curl / wget”没有返回“路由到主机”。

原因在于docker设置的安全性,默认情况下是禁止从容器到主机或主机上运行的其他容器的通信。 这对我来说是非常令人惊讶的,我必须说,你会期望在本地机器上运行的docker机器的回声系统完美无缺地彼此访问而没有太多的障碍。

下面的文档详细介绍了这一点。

http://www.dedoimedo.com/computers/docker-networking.html

给出了两个快速的解决方法,通过降低networking安全性来帮助您移动。

最简单的方法就是closures防火墙 – 或者允许所有防火墙。 这意味着运行必要的命令,这可能是systemctl停止firewalld,iptables -F或等效。

希望这些信息可以帮助你。