我设置了一个 OpenStack Folsom (2012.2) 多节点、单网络基础设施。一切运行良好,实例在任何计算节点上运行良好,私有网络运行良好,所有实例都可以通过浮动 IP 从外部访问,并且可以访问外部。
但是,当尝试通过浮动 IP 从虚拟机向其自身执行网络请求时,它会失败。
ping 和 ssh 都不起作用。
安全组全部打开。
Ping 可以通过浮动 IP 从一个虚拟机到另一个虚拟机进行,但 SSH不。
示例的一些数据
- 10.0.0.0/24 是私有网络
- 10.0.0.1 是控制器
- 10.1.100.0/24 是浮动 IP 网络
- 具有 10.0.0.13 的虚拟机具有浮动 IP 10.1.100.4
控制器上的 iptables 条目(关于 10.1.100.4/10.0.0.13)(包括网络在内的所有服务):
-A nova-network-2.7-OUTPUT -d 10.1.100.4/32 -j DNAT --to-destination 10.0.0.13
-A nova-network-2.7-PREROUTING -d 10.1.100.4/32 -j DNAT --to-destination 10.0.0.13
-A nova-network-2.7-float-snat -s 10.0.0.13/32 -o eth0 -j SNAT --to-source 10.1.100.4
计算节点上的 iptables 条目:
关于 10.1.100.4/10.0.0.13:
-A nova-compute-2.7-local -d 10.0.0.13/32 -j nova-compute-2.7-inst-143
关于nova-compute-2.7-inst-143:
-N nova-compute-2.7-inst-143
-A nova-compute-2.7-inst-143 -m state --state INVALID -j DROP
-A nova-compute-2.7-inst-143 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A nova-compute-2.7-inst-143 -j nova-compute-2.7-provider
-A nova-compute-2.7-inst-143 -s 10.0.0.1/32 -p udp -m udp --sport 67 --dport 68 -j ACCEPT
-A nova-compute-2.7-inst-143 -s 10.0.0.0/24 -j ACCEPT
-A nova-compute-2.7-inst-143 -p tcp -m tcp --dport 22 -j ACCEPT
-A nova-compute-2.7-inst-143 -p tcp -m tcp --dport 3389 -j ACCEPT
-A nova-compute-2.7-inst-143 -p tcp -m multiport --dports 1:65535 -j ACCEPT
-A nova-compute-2.7-inst-143 -p udp -m multiport --dports 1:65535 -j ACCEPT
-A nova-compute-2.7-inst-143 -p icmp -j ACCEPT
-A nova-compute-2.7-inst-143 -j nova-compute-2.7-sg-fallback
欢迎提出任何有关如何查找问题的建议。当然,我会提供解决问题所需的任何数据。目前我不太确定哪些数据会有所帮助。
答案1
蒂洛,
这很好地体现在https://bugs.launchpad.net/nova/+bug/1096259,目前正在为 nova 开发补丁(https://review.openstack.org/#/c/19139/) 截至今日(2013年1月7日)。
完整修复还适用于错误 1096987(https://bugs.launchpad.net/nova/+bug/1096987) 和 1096985 (https://bugs.launchpad.net/nova/+bug/1096987) 来涵盖更常见的部署场景,其中您使用预定义的外部网关或利用 nova-network linux/iptables 网络公共桥接设置。
答案2
好的,我找到问题了:
所有发往浮动 IP(我这里是 10.1.100.0/24)的数据包都经过 DNAT 处理,到达私有网络目的地(我这里是 10.0.0.0/24)。ssh 数据包通过控制器传输,然后直接返回虚拟机。ssh 服务器应答,但发送数据包时会将其私有地址作为源地址(当然,它没有其他地址)。因此,ssh 客户端会从 10.0.0.13 收到一个数据包,作为对发往 10.1.100.4 的请求的应答,但客户端会忽略该请求。
好吧,所以当从私有 IP 向浮动 IP 发送数据包时,不仅目的地需要进行 NAT,源也需要进行 NAT。但这并不简单,因为 DNAT 处于 PREROUTE 中,而 SNAT 处于 POSTROUTE 中。可以使用连接跟踪模块来完成:
iptables -t nat -A nova-network-2.7-float-snat -s 10.0.0.13/32 -d 10.0.0.0/24 -j SNAT --to-source 10.1.100.4 -m conntrack --ctstate DNAT
这对我来说很管用(当然对于每个浮动 IP 来说都是如此)。它会破坏每个从私有到私有的数据包,这些数据包已经经过 DNAT 处理(然后它应该转到浮动 IP),使其看起来好像来自浮动 IP。
在我的 ssh 场景中现在发生以下情况:
- 客户端从 10.0.0.13 发送到 10.1.100.4
- 数据包被 DNAT 到 10.0.0.13
- 数据包被 SNAT 到 10.1.100.4
- 服务器应答数据包到 10.1.100.4
- 数据包被 DNAT 到 10.0.0.13
- 数据包被 SNAT 到 10.1.100.4
- 客户端收到来自 10.1.100.4 的答复并且很高兴
这对于 ping 以及不同虚拟机之间的流量同样有效。
看起来我必须修补 nova-network 代码并将其提交给 openstack 项目 :-/。