我有个码头集装箱在运行詹金斯。作为构建过程的一部分,我需要访问在主机上本地运行的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.]+'
当前回答
使用docker-compose的解决方案: 要访问基于主机的服务,可以使用network_mode参数 https://docs.docker.com/compose/compose-file/#network_mode
version: '3'
services:
jenkins:
network_mode: host
EDIT 2020-04-27:建议仅在本地开发环境中使用。
编辑2021-09-21:ihavehandedinmyresign写道,它不适用于Mac和Windows。选项仅支持Linux操作系统
其他回答
为此我创建了一个docker容器https://github.com/qoomon/docker-host
然后,您可以简单地使用容器名称dns访问主机系统。 curl http://dockerhost: 9200
使用docker-compose的解决方案: 要访问基于主机的服务,可以使用network_mode参数 https://docs.docker.com/compose/compose-file/#network_mode
version: '3'
services:
jenkins:
network_mode: host
EDIT 2020-04-27:建议仅在本地开发环境中使用。
编辑2021-09-21:ihavehandedinmyresign写道,它不适用于Mac和Windows。选项仅支持Linux操作系统
对于使用桥接网络在容器之间创建专用网络的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模块分别配置和持久化防火墙规则。
适用于所有平台
Docker v 20.10及以上版本(自2020年12月14日起)
在Linux上,在Docker命令中添加——add-host=host.docker.internal:host-gateway来启用该功能。(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
MacOS和早期版本的Docker
Mac v 17.12到v 18.02的Docker
与上述相同,但使用docker.for.mac.host.internal代替。
Mac v 17.06到v 17.11的Docker
与上述相同,但使用docker.for.mac.localhost代替。
Docker适用于Mac 17.05及以下版本
要从docker容器访问主机,必须为网络接口附加一个IP别名。你可以绑定任何你想要的IP,只要确保你没有使用它到其他任何东西。
sudo ifconfig lo0又名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
对我来说(Windows 10, Docker Engine v19.03.8),它是https://stackoverflow.com/a/43541732/7924573和https://stackoverflow.com/a/50866007/7924573的组合。
change the host/ip to host.docker.internal e.g.: LOGGER_URL = "http://host.docker.internal:8085/log" set the network_mode to bridge (if you want to maintain the port forwarding; if not use host): version: '3.7' services: server: build: . ports: - "5000:5000" network_mode: bridge or alternatively: Use --net="bridge" if you are not using docker-compose (similar to https://stackoverflow.com/a/48806927/7924573) As pointed out in previous answers: This should only be used in a local development environment. For more information read: https://docs.docker.com/compose/compose-file/#network_mode and https://docs.docker.com/docker-for-windows/networking/#use-cases-and-workarounds