《OpenStack运维指南》节选—— 双层VLAN

小豆芽 2015-08-27

双层VLAN

我在加拿大不列颠哥伦比亚省的基隆拿创建了一套新的OpenStack系统。整个部署过程是全自动的:Cobbler负责在硬件上部署OS,OS被引导后,Puppet接手剩下的事情。我已经在实践中运行这套部署方案很多次了,就理所应当地认为没有任何问题。

在基隆拿的最后一天,我在酒店里参加电话会议。实际上,我正在新部署出来的云系统里面随便玩着。我启动了一个虚拟机实例,并登录进去。一切看起来都很正常。闲着无聊,我运行了一下ps aux命令,突然整个虚拟机实例就锁住了。

我认为这是一个偶发事件,因此我停止了这个实例,并启动了一个新的。这时,电话会议结束了,我需要去数据中心走一趟。

在数据中心,我完成了一些收尾的工作,这时想起了那个实例锁住的的事情。于是我登录到新的实例,并再一次运行ps aux。它工作正常。唷。我决定再运行一次。它又锁住了。搞什么啊!

在重现了这个问题几次之后,我得出一个不幸的结论,那就是这套云系统其实真的有问题。更糟的是,我在基隆拿的出差就要结束了,我必须回到卡尔加里去。

我应该从哪里开始排查像这样的故障呢?一个虚拟机实例因为一个命令就随机地锁住了。是镜像的问题吗?不——所有镜像都有这个问题。 是计算节点的问题吗? 不——所有节点都有这个问题。实例真的锁住了吗?不!因为新的SSH连接很正常!

我们去寻求帮助,一个网络工程师说可能是MTU的问题。太棒了!MTU!终于有进展了!MTU是什么?它为什么会出问题?

MTU是最大传输单元(maximum transmission unit)的英文缩写。它规定了网卡接收的每一个数据包字节的最大值。如果两个网卡上的MTU设置不一样,过来的字节就会被卡住,奇怪的事情就会发生 ——比方说会话随机被锁住。

并非所有的数据包都有1500 B这么大。通过SSH运行ls命令可能只会创建一个小于1500 B的数据包。但是,运行的命令如果有很大的输出,比方说ps aux命令,就需要多个1500 B的数据包。

好的,那么MTU的问题是从哪儿跑出来的?为什么我们在其他的任一部署中没有遇到过这个问题?这次的情况有啥新变化吗?好吧,新的数据中心,新的上行链路,新的交换机,新的交换机型号,新的服务器,第一次使用这个型号的服务器……所以,基本上所有东西都是新的。太棒了。我们在各个地方都要调大了MTU:交换机,计算节点的网卡,实例的虚拟网卡,甚至使数据中心为我们的上行链路接口都调大了MTU。一些修改起作用了,一些却没用。可是这条排障的方向似乎不对,我们没必要在这些地方调整MTU。

作为最后一根救命稻草,我们的网络管理员(Alvaro)和我坐在一起,旁边有四个终端窗口、一根铅笔和一张纸。在其中一个窗口中,我们运行ping。在第二个窗口中,我们在云控制器上运行tcpdump。在第三个窗口,我们在计算节点上运行tcpdump。然后第四个窗口中,我们在实例上运行tcpdump。介绍一些背景:我们这个云是多节点而不是多主机设置。

一个云控制器作为所有计算节点的网关。VlanManager用来配置网络。这意味着,云控制器和所有计算节点在每一个OpenStack的项目中都使用一个不同的VLAN。我们使用了ping的-s选项来修改数据包的大小。我们观察到有时这个包可以完整地返回,有时它发出去了却没法回来,而有时它会随机地停下来。我们修改tcpdump来显示数据包的十六进制转储,并不停地修改ping的组合:外部、控制器、计算节点和虚拟机实例。

最终,Alvaro发现了一个问题。当一个数据包从外面到达云控制器的时候,它不应该配有一个VLAN。我们确认了这点。当数据包从云控制器发往计算节点时,只有当目的地是一个虚拟机实例时,它才会携带一个VLAN。这也是对的。当ping应答从实例发出时,它应该在一个VLAN里面。确实如此。当它返回到控制器,然后发送到互联网上时,它不应该再带有一个VLAN。不对。噢,看起来好像是这个包的VLAN部分没有被移除掉。

那是说不通的。

带着这个想法,我在计算节点上随机地敲了一些命令:

$ ip a… 


 


10: vlan100@vlan20: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br100 state UP 


 


… 

“嘿,Alvaro,你能在一个VLAN上运行一个VLAN吗?”

“如果你这么做,就会给数据包增加额外4个字节。”

那么这就全说通了:

grep vlan_interface /etc/nova/nova.conf 


 


vlan_interface=vlan20 

在nova.conf中,vlan_interface指定了OpenStack要在哪个网卡上挂VLAN。正确的设置本应该是:vlan_interface=bond0。

这也就是服务器捆绑后的网卡。

vlan20是数据中心分配给我们用于公网访问的VLAN。它是一个正确的VLAN,也和bond0相连。

结果我错误地把OpenStack配置成了将所有的租户VLAN与vlan20而不是bond0相连,所以这就在一个VLAN上又叠加了另一个VLAN。结果每个包增加了额外的4 B,导致发出的是一个1504 B的包,这当然会出问题,因为我们网卡有1500 B的限制啊!

这个设置一修复,一切都好了。

相关推荐