如何从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或等效。
希望这些信息可以帮助你。