我无法从 docker 容器访问主机私有接口 (ip)。我相当肯定它与我的 Iptables 规则(或者可能是路由)有关。当我将--net=host
标志添加到 时docker run
,一切都按预期工作。同样,当我指定 INPUT 政策遵循自由主义时-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
Run Code Online (Sandbox Code Playgroud)
我的(相关)主机接口:
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
Run Code Online (Sandbox Code Playgroud)
我运行一个 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.
Run Code Online (Sandbox Code Playgroud)
此时,我希望能够使用绑定在 10.129.112.210:53 上的本地服务。因此,以下内容应产生答复:
$ ping google.com
^C
$ ping user.skydns.local
^C
Run Code Online (Sandbox Code Playgroud)
当我从主机运行相同的命令时:
$ 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
Run Code Online (Sandbox Code Playgroud)
我的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
Run Code Online (Sandbox Code Playgroud)
这里的重点不是访问公共主机,而是内部主机,使用主机上可用的本地 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)
Run Code Online (Sandbox Code Playgroud)
我搜索、阅读并应用了不同的示例 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
Run Code Online (Sandbox Code Playgroud)
的输出cat /proc/sys/net/ipv4/ip_forward
:
1
Run Code Online (Sandbox Code Playgroud)
Lau*_*scu 17
容器使用docker0
接口与主机通信。要允许来自容器的流量添加:
-A INPUT -i docker0 -j ACCEPT
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
29928 次 |
最近记录: |