我在用着Docker管理 LXC 容器。目前,Docker 使用仅主机路由配置底层 LXC 容器,然后使用 iptables/DNAT 在容器中打洞,使其可通过主机 IP 和“随机”端口访问。
由于多种原因,这对我们来说行不通。我们希望每个容器都可以通过其自己的(可路由)IP 访问。所以我一直在尝试使用 IP 表来实现这一点。它在家里运行良好(在 Ubuntu Raring 上运行),但在工作中却不行(在 Ubuntu Precise 上运行)。我猜有一些默认内核配置发生了变化,而我不知道。
以下是我正在做的事情:
1)设置新的 macvlan 虚拟接口,以便我可以使用 DHCP 获取 IP:
ip link add container1 link eth0 type macvlan
dhclient container1
ip link set container1 up
此时,我有一个新的接口,它有自己的 IP 地址和默认网关、子网掩码等,与底层物理接口相匹配(eth0
)。
2) 配置 IP 表以对来自新接口 IP 的传入流量进行 DNAT。假设新接口有 IP 10.10.10.88
,而 Docker 控制的 LXC 容器有 IP 172.17.0.20。
iptables -t nat -N CONTAINER1
iptables -t nat -A PREROUTING -p all -d 10.10.10.88/32 -j CONTAINER1
iptables -t nat -A CONTAINER1 -p tcp -m tcp --dport 80 -j DNAT --to-destination 172.17.0.20:8080
(这里,我还将端口从 80 NAT 到 8080)。
如上所述,这在家里工作得很好。我现在可以从主机 172.17.0.20:8080 访问此容器,也可以从 LAN 上的另一台机器 10.10.10.88:80 访问此容器。(有趣的是,我无法从主机内部访问 10.10.10.88:80,但我想我可能需要在 OUTPUT 链中再添加一条规则来捕获它。)但在工作中却不行。
在工作中,当我尝试使用其可路由 IP(本例中为 10.10.10.88)访问此容器时,我可以看到数据包到达并与 iptables 规则匹配,直至符合 DNAT 规则。我可以使用 iptables -L 打印的数据包计数器以及使用原始表上的 TRACE 目标并查看内核日志来观察这一点。但在匹配 DNAT 规则后,数据包就消失了。在我的家用机器(可以正常工作)上,在 DNAT 之后,我可以看到数据包通过过滤表中的 INPUT 链,并带有新的(NAT 的)目标 IP。在我的工作机器上,此步骤不会发生。
两台机器都开启了IP转发。