为什么 Openstack VM 无法通过其浮动 IP 访问自身?

为什么 Openstack VM 无法通过其浮动 IP 访问自身?

我设置了一个 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 项目 :-/。

相关内容