我无法从Docker容器访问主机专用接口(ip)。我相当确定它与我的Iptables规则(或路由)有关。当我将--net=host
标志添加到时docker run
,一切都会按预期进行。同样,当我指定INPUT策略遵循Liberal时-P INPUT ACCEPT
,事情也会按我期望的那样工作。但是,这些都是我要避免的不理想和不安全的选择。
由于它不特定于我的服务(DNS),因此已将其排除在问题之外,因为与docker结合进行搜索会在另一个(受欢迎的)问题区域中产生结果,从而给搜索结果增加了噪音。
另外,链接Docker容器也不是一个可行的选择,因为某些容器需要使用--net = host选项运行,从而阻止了链接,我想在可能的情况下创建一致的情况。
我有以下Iptables规则。我假设结合了CoreOS,Digital Ocean和Docker。
-P INPUT DROP
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-N DOCKER
-A INPUT -i lo -j ACCEPT
-A INPUT -i eth1 -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 0 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 3 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 11 -j ACCEPT
-A FORWARD -o docker0 -j DOCKER
-A FORWARD -o docker0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i docker0 ! -o docker0 -j ACCEPT
-A FORWARD -i docker0 -o docker0 -j ACCEPT
我的(相关)主机接口:
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
inet 10.129.112.210/16 brd 10.129.255.255 scope global eth1
valid_lft forever preferred_lft forever
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
inet 172.17.42.1/16 scope global docker0
valid_lft forever preferred_lft forever
我运行一个Docker容器:
$ docker run --rm -it --dns=10.129.112.210 debian:jessie # Specifying the DNS is so that the public DNS servers aren't used.
此时,我希望能够使用绑定在10.129.112.210:53上的本地服务。这样以下内容将产生答复:
$ ping google.com
^C
$ ping user.skydns.local
^C
当我从主机运行相同的命令时:
$ ping photo.skydns.localPING photo.skydns.local (10.129.112.206) 56(84) bytes of data.
64 bytes from 10.129.112.206: icmp_seq=1 ttl=64 time=0.790 ms
^C
我的resolv.conf
$ cat /etc/resolv.conf
nameserver 10.129.112.210
nameserver 127.0.0.1
nameserver 8.8.8.8
nameserver 8.8.4.4
这里的重点不是使用主机上可用的本地DNS服务(通过另一个docker实例)访问公共主机,而是内部主机。
为了进一步说明(我的ascii艺术设计技能超过了iptables fu,因此在这一点上应该足够说明):
______________________________________________
| __________________________ Host |
| | Docker DNS container | |
| ``````````````````````|``` |
| | |
| ,----------,---( private n. interface ) |
| | | |
| | | ( public n. interface )---
| | | |
| | | ( loopbck n. interface ) |
| | | |
| | | |
| | __|_______________________ |
| | | Docker service container | |
| | `````````````````````````` |
| | |
| | |
| [ Local host service using DNS. ] |
| |
|______________________________________________|
private (host) network interface: eth1 (10.129.0.0/16)
Docker network interface: docker0 (172.17.0.0/16)
我已经搜索,阅读并应用了不同的示例Iptables配置,但是我对“高级” Iptables规则知之甚少,无法理解正在发生的事情并因此无法获得所需的结果。
输出iptables -t nat -nL
:
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DOCKER all -- 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0
Chain DOCKER (2 references)
target prot opt source destination
输出cat /proc/sys/net/ipv4/ip_forward
:
1
$ cat /proc/sys/net/ipv4/ip_forward -> 1
并-A INPUT -i eth1 -j ACCEPT
接受专用接口上的所有连接。您缺少什么规则?
-A INPUT -i docker0 -j ACCEPT
iptables -t nat -nL
吗?您是否进行了任何数据包分析,例如从源容器执行ping操作,然后使用tcpdump捕获主机上的数据包。