近来同事出差在北京测试openstack性能时,我通过redhat提供的rdo以及packstack工具,快速在centos 6.5上部署了一个OpenStack多节点环境,然而在安装过程中因为neutron部署失败(主要是配置成了neutron linuxbridge模式时仍读取ovs的bridge mapping配置),因为时间紧急,来不及研究puppet的细节,导致我在packstack的应答文件中指定了不安装neutron,根据应答文件上的注释,改为安装nova-network,打算在安装完nova-network后,通过手工安装neutron的软件包,来移除掉nova-network。

此后同事在部署实例时,发现了一个比较严重的问题,就是无法获取metadata,导致ssh不可用,我尝试过使用guestfish这样的工具来修改ubuntu vm镜像,但最终还是无法改成直接启用ssh密码登陆(有机会可以再细细研究一下)。

由于我采用了linuxbridge agent,并且在l3-agent上启用了namespace,因此,metadata的预期工作顺序是这样的:

[1. 计算节点上的vm 发送metadata请求到私有ip 169.254.169.254,查默认路由后设置目的mac地址为所在子网在虚拟路由器中网关接口地址]

[2. 计算节点给报文添加vlan tag]

[3. 报文在L2底层网络上传输到网络节点]

[4. 网络节点根据tag送到为此租户创建的linux bridge上]

[5. 根据fdb报文将被转发到虚拟路由器中网关接口对应的veth]

[6. 租户namespace中的veth接收到报文]

[7. namespace中进行iptables处理,将169.254.169.254:80换成重定向到本地的9697]

[8. 本地的ns-metadata-proxy处理该请求,通过unix domain socket请求默认namespace中的nova metadata service,获取到需要的metadata,之后报文以相反的方向返回]

通过抓包分析,发现在第6步上namespace的veth无法收到这个metadata http请求,百思不得其解,后来在默认namespace中查看iptables时,注意到竟然在默认namespace中也有一条nat规则,此规则查阅代码是由nova/network/linux_net.py所下发,直接翻译到8775端口,所以原则上应该也可以工作,毕竟租户namespace中的proxy,本质上也是把请求又定向到了nova起的位于8775端口metadata service,只是当时我走偏了方向,当然,既使这样,也不建议做此处理,毕竟用neutron的话,用nova-network总是怪怪的,根据linux bridge netfilter的FAQ的如下说明,并且考虑到centos上bridge-nf-call-iptables默认是打开的,因此bridge报文将适用于iptables DNAT规则(kernel相应的函数为br_nf_pre_routing):

It is the infrastructure that enables {ip,ip6,arp}tables to see bridged IPv4, resp. IPv6, resp. ARP packets. Thanks to bridge-nf, you can use these tools to filter bridged packets, letting you make a transparant firewall. Note that bridge-nf is also referred to as bridge-netfilter and br-nf, the term bridge-nf should be preferred.

If IP DNAT happened then the bridge-nf code asks the routing table where the packet should be sent. If it has to be sent over another device (not the bridge device) then the packet is routed (an implicit redirect). If the routing table sends the packet to the bridge device, then the packet is bridged but the MAC destination is correctly changed. To do IP DNAT, you therefore need a correct routing table.

在默认namespace中的NAT规则应该会导致既使报文的目的mac不是本地接口(因为此请求报文是送往租户namespace中的接口),也仍然会执行iptables过滤,提前的进行了iptables DNAT处理,而因为我已经将l3-agent配置成了neutron模式,此时在默认namespace中就做DNAT时,会导致这个报文无处转发而被丢弃,因此果断删除此iptables规则,此后发现报文可以正常送往租户namespace。

此时问题只解决了一半,经验证即使报文能正确送到租户namespace,metadata也仍然因为404错误而无法获取,最后确认是nova配置中未删除nova-network的配置,将相应的配置清空后,metadata服务恢复正常。

OpenStack在网络节点上的逻辑,还是有些绕的,定位起来比较花时间,因此如果有时间的话,尽量不要做妥协,否则可能要花大量的时间去定位,而如果我这次不急的话,应该会努力把packstack中neutron无法安装的问题解决掉,这样就不会有后面的问题了,相信OpenStack能够继续优化,并提供一些诊断和定位措施,以便于普通用户诊断比较怪异的问题,提高易用性。

PS:

  1. packstack基于puppet实现了openstack的环境多节点的批量安装,对于部署新的openstack环境而言,确实能够减少大量的工作量,是值得推荐的工具,当然,也顺带推荐一下puppet。

  2. bridge-nf-FAQ


Comments

comments powered by Disqus