在工作中,我们使用一个特定的操作系统,我们(开发人员)在virtualbox中运行。 虚拟化的操作系统正在运行我们用来访问操作系统的Samba服务器和rsh。 此外,虚拟化的操作系统需要访问我们networking上的多台服务器。
我想实现的是有一种方法来快速启动虚拟机作为Docker安装程序的一部分。 这个想法是有一个docker容器,将提供虚拟机的访问,一个容器,在虚拟机上运行testing,并在未来的一些其他容器,将提供例如。 系统的分析。
我有一个docker容器,用桥接networking设置一个VirtualBox机器。 我可以从启动它的容器中使用rsh访问虚拟机,没有任何问题。 但是,我不能从其他容器使用rsh访问虚拟机(呃,我发现了一个解决scheme,我将在下面描述,但我不认为这是一个好的)。 有趣的是,ping工作正常。
现在设置看起来像这样:
虚拟容器
VirtualBox机器
工人容器
到目前为止,我发现只有一个解决scheme如何使用rsh连接到VirtualBox机器,那就是添加一个路由:
ip route add 172.18.1.5 via 172.18.0.5
然后rsh到172.18.1.5。 但是,这有一个严重的问题。 因为我需要知道分配给虚拟机的地址,所以我必须将virtualbox地址设置为一个可以容易地从正在运行的容器的地址中猜出的地址。更改容器内的路由也意味着容器需要特权,我想保持特权容器的数量最less。
我想要更多的是能够直接向虚拟容器(172.18.0.5)发送消息。 这样我就不必猜测虚拟机的IP,但是我可以使用docker-compose的虚拟主机名。
我以为我可以使用NAT来实现这一点。 我所做的是:
iptables -t nat -A PREROUTING - 目标172.18.0.5 -j DNAT - 到目的地172.18.1.5 iptables -t nat -A POSTROUTING --source 172.18.1.5 -j SNAT - to-source 172.18.0.5
但是,它似乎并没有工作。 注意:我不在乎是否所有端口都是转发器。 很明显,只有rsh和Samba才会更好,但是由于服务器select与被动FTP类似的通信端口,rsh是有问题的。
任何想法我做错了什么,我怎么能实现我的目标?
iptables nat表的内容:
Chain PREROUTING (policy ACCEPT) target prot opt source destination DNAT all -- anywhere 4f04152f8562 to:172.18.1.5 Chain INPUT (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination DOCKER_OUTPUT all -- anywhere 127.0.0.11 Chain POSTROUTING (policy ACCEPT) target prot opt source destination DOCKER_POSTROUTING all -- anywhere 127.0.0.11 SNAT all -- anywhere anywhere to:172.18.0.5 Chain DOCKER_OUTPUT (1 references) target prot opt source destination DNAT tcp -- anywhere 127.0.0.11 tcp dpt:domain to:127.0.0.11:43467 DNAT udp -- anywhere 127.0.0.11 udp dpt:domain to:127.0.0.11:39285 Chain DOCKER_POSTROUTING (1 references) target prot opt source destination SNAT tcp -- 127.0.0.11 anywhere tcp spt:43467 to::53 SNAT udp -- 127.0.0.11 anywhere udp spt:39285 to::53A
另外,我已经将wireshark安装到容器中,我认为问题在于由iptables规则引起的循环。
我可以看到172.18.0.5到172.18.0.5的数据包被发送到172.18.1.5,这是正确的。 此外,来自172.18.1.5的回复将源地址转换为172.18.0.5,然后将它们发送到172.18.0.6,这也是正确的。 然而,从172.18.1.5到172.18.0.5有一个连接。 我认为存在这个问题,因为连接应该是172.18.0.6。 但是,我不知道如何确保虚拟机知道连接的正确地址。
现在我正在考虑 – DNAT是不是应该保持源地址不变? 根据wireshark它被改为虚拟的地址。 所以难怪虚拟机创build连接到虚拟而不是工作者 。
所以解决scheme非常简单:
将Virtual移动到另一个子网,并将其网关设置为Container的IP
而已。 正如问题中提到的NAT规则是正确的。
因为Worker和Virtual在同一个子网上,所以当创build与RSH使用的Worker的连接时, Virtual直接连接到Worker ,从而绕过了NAT。
不幸的是我在使用wiresharkdebugging这个问题的时候又犯了一个错误。 如此无可救药,我改变了iptables规则:
-t nat -A PREROUTING -j DNAT --to-destination 172.18.1.5 -t nat -A POSTROUTING -j SNAT --to-source 172.18.0.5
有了这样的规则,似乎部分工作,因为容器突然成为最初的握手工作的来源。 然而,它打破了来自Virtual的RSH连接,因为原始连接来自Worker的信息已经丢失。