我有个码头集装箱在运行詹金斯。作为构建过程的一部分,我需要访问在主机上本地运行的web服务器。是否有一种方法可以将主机web服务器(可以配置为在端口上运行)暴露给jenkins容器?
我在Linux机器上本机运行docker。
更新:
除了下面的@larsks答案,要从主机上获取主机IP的IP地址,我做了以下操作:
ip addr show docker0 | grep -Po 'inet \K[\d.]+'
我有个码头集装箱在运行詹金斯。作为构建过程的一部分,我需要访问在主机上本地运行的web服务器。是否有一种方法可以将主机web服务器(可以配置为在端口上运行)暴露给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或Windows 18.03+上使用Docker,你可以连接到神奇的主机名host.docker.internal。
最后,在Linux下你可以通过设置——net=host在主机网络命名空间中运行容器;在这种情况下,主机上的localhost与容器内的localhost相同,因此容器化服务将像非容器化服务一样,无需任何额外配置即可访问。
其他回答
为此我创建了一个docker容器https://github.com/qoomon/docker-host
然后,您可以简单地使用容器名称dns访问主机系统。 curl http://dockerhost: 9200
我们发现,对于所有这些网络垃圾,一个更简单的解决方案是仅为服务使用域套接字。如果您无论如何都试图连接到主机,只需将套接字作为卷挂载,就可以了。对于postgresql,这很简单:
docker run -v /var/run/postgresql:/var/run/postgresql
然后,我们只需设置数据库连接以使用套接字而不是网络。就是这么简单。
对于使用桥接网络在容器之间创建专用网络的docker-compose,使用docker0的公认解决方案不起作用,因为容器的出口接口不是docker0,而是一个随机生成的接口id,例如:
$ ifconfig
br-02d7f5ba5a51: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.32.1 netmask 255.255.240.0 broadcast 192.168.47.255
不幸的是,随机id是不可预测的,并且每次compose必须重新创建网络时(例如在主机重新启动时)都会改变。我的解决方案是在一个已知的子网中创建私有网络,并配置iptables以接受该范围:
撰写文件片段:
version: "3.7"
services:
mongodb:
image: mongo:4.2.2
networks:
- mynet
# rest of service config and other services removed for clarity
networks:
mynet:
name: mynet
ipam:
driver: default
config:
- subnet: "192.168.32.0/20"
如果您的环境需要,您可以更改子网。我使用docker network inspect任意选择了192.168.32.0/20,以查看默认创建的内容。
在主机上配置iptables,允许私有子网作为源:
$ iptables -I INPUT 1 -s 192.168.32.0/20 -j ACCEPT
这是最简单的iptables规则。您可能希望添加其他限制,例如按目的端口。当你对iptables的工作感到满意时,不要忘记坚持你的规则。
这种方法的优点是可重复的,因此是可自动化的。我使用ansible的模板模块使用变量替换来部署我的compose文件,然后使用iptables和shell模块分别配置和持久化防火墙规则。
在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或Windows 18.03+上使用Docker,你可以连接到神奇的主机名host.docker.internal。
最后,在Linux下你可以通过设置——net=host在主机网络命名空间中运行容器;在这种情况下,主机上的localhost与容器内的localhost相同,因此容器化服务将像非容器化服务一样,无需任何额外配置即可访问。
在近7年的时间里,这个问题被提出了,要么docker已经改变了,要么没有人尝试过这种方法。所以我会给出我自己的答案。
我发现所有的答案都使用了复杂的方法。今天,我需要这些,并找到了两种非常简单的方法:
在主机上使用ipconfig或ifconfig,并记录所有的IP地址。容器至少可以使用其中的两个。 我有一个固定的本地网络地址在WiFi局域网适配器:192.168.1.101。这可能是10.0.1.101。结果会根据你的路由器而改变 我在windows上使用WSL,它有自己的vEthernet地址:172.19.192.1 使用host.docker.internal。大多数答案都有这样或那样的形式,这取决于操作系统。从这个名字可以看出,docker现在在全球范围内使用它。
第三种选择是使用计算机的WAN地址,或者换句话说,由服务提供者提供的IP地址。然而,如果IP不是静态的,并且需要路由和防火墙设置,这可能不起作用。
PS:虽然和这里的这个问题很像,我把这个答案贴在那里,但我是先找到这个帖子的,所以我也贴在这里,以免忘记我自己的答案。