我有个码头集装箱在运行詹金斯。作为构建过程的一部分,我需要访问在主机上本地运行的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,使用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-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 run命令中使用——net="host",那么docker容器中的localhost将指向docker主机。
当你“已经”创建了两个docker映像,并且你想让两个容器彼此通信时。
为此,您可以方便地使用自己的——name运行每个容器,并使用——link标志来启用它们之间的通信。但是在docker构建期间你不会得到这个。
当你和我一样身处险境时,那是你的
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
本文给出了两个快速解决方案,可以帮助您降低网络安全性。
最简单的选择是关闭防火墙——或者允许所有防火墙。这意味着运行必要的命令,可以是systemctl stop firewall, iptables -F或等效命令。
为此我创建了一个docker容器https://github.com/qoomon/docker-host
然后,您可以简单地使用容器名称dns访问主机系统。 curl http://dockerhost: 9200
我探索了各种解决方案,我发现这是最简单的解决方案:
定义网桥网关的静态IP地址。 在extra_hosts指令中添加网关IP作为额外的条目。
唯一的缺点是,如果你有多个网络或项目这样做,你必须确保它们的IP地址范围不冲突。
下面是一个Docker Compose的例子:
version: '2.3'
services:
redis:
image: "redis"
extra_hosts:
- "dockerhost:172.20.0.1"
networks:
default:
ipam:
driver: default
config:
- subnet: 172.20.0.0/16
gateway: 172.20.0.1
然后,您可以使用主机名“dockerhost”从容器内部访问主机上的端口。