網卡驅動引起openstack的mtu問題


一套Pike版本的openstack測試環境,使用vlan模式的網絡,數據網網卡使用的是綠聯的usb百兆網卡,遇到了虛擬機網絡異常的問題。同一個vlan下,不同宿主機上的兩台虛擬機,相互之間可以ping通,但是不能ssh。

ICMP能通,說明鏈路沒有問題,ssh走的是ssh協議,不通的話,最常見時兩種情況,一種是防火牆安全組禁用了ssh的端口,經過排查,發現不是這個問題。

另一種情況可能是MTU設置錯誤的問題。
按照以太網早期的設計,鏈路層最大傳輸的數據的長度(MTU)最小46個字節,最大1500個字節(原因可以知乎搜索),如果傳輸的數據大小超過了1500個字節,要切分成多分小於1500的數據再交給鏈路層。對應的,鏈路層設備接受到的幀大小的范圍時64-1518注1 ,如果以太網上的設備,如網卡,交換機網卡接收到的幀大小超過了1518注2,默認會直接丟棄這樣的數據幀注3

有的時候網絡通信,就是因為上層協議沒有很好的根據mtu調整自己單次傳輸的數據大小,導致部分數據在傳輸過程中丟失,網絡通信故障。但是對於ssh,ssh使用的是tcp協議,這個按理不會出現,tcp通信時,tcp鏈接的兩端會根據雙方以及整條線路上設備的最小mtu,協商出一個MSS,即tcp層每次傳輸的最大的數據,有的時候MTU設置的太大,會導致數據幀的長度超出限制,連接到某些網絡失敗。按理說,無論哪一個設備的mtu設置錯誤,都不應該影響ssh。

但是還是要試一試,現在虛擬機默認的mtu大小是1500,ssh不通,嘗試將mtu調整成1499,依舊不通,1498通了。這就很奇怪了,為什么鏈路層支持傳輸的最大數據少了2字節?當時還不知道這個數據網出口時綠聯的usb網卡,開始懷疑時不是vxlan相關的配置引起的bug,決定通過抓包來定位問題設備。

vlan 模式下不同宿主機上的虛擬機通信邏輯比較簡單,如下圖所示:

vlan模式不同宿主機上的虛擬機通信

灰色設備是ovs port,類似網線的作用,藍色是物理的或者虛擬的二層交換設備,橙色是物理的或者虛擬的網卡
嘗試從vm1執行ping -s 1471 192.168.11.106,然后再物理機02上抓包,發現再eth1上抓包,沒有問題,可以抓得到,在qvo上抓包,抓不到。這里要確認,是eth1把收到的包丟掉了,還是eth1把包交給qvo的過程中,包丟失了。

在物理機2上執行下面的命令:

(openvswitch-vswitchd)[root@compute01 /]# ovs-dpctl show
system@ovs-system:
	lookups: hit:7589478 missed:410086 lost:0
	flows: 54
	masks: hit:62147619 total:10 hit/pkt:7.77
	port 0: ovs-system (internal)
	port 1: br-int (internal)
	port 2: br-tun (internal)
	port 3: eth1
	port 4: br-data (internal)
	port 5: qvo34b16ff1-bb
	port 6: qvoe6366126-d8


(openvswitch-vswitchd)[root@compute01 /]# ovs-dpctl dump-flows | grep -r "6e:f2" 
recirc_id(0),in_port(3),eth(src=fa:16:3e:a9:6e:f2,dst=fa:16:3e:07:ee:2c),
eth_type(0x8100),vlan(vid=131,pcp=0),encap(eth_type(0x0800),ipv4(frag=no)),
packets:2122, bytes:3223318, used:0.726s,
actions:pop_vlan,6
recirc_id(0),in_port(6),eth(src=fa:16:3e:07:ee:2c,dst=fa:16:3e:a9:6e:f2),
eth_type(0x0800),ipv4(frag=no), packets:1046, bytes:1582598, used:0.726s,
actions:push_vlan(vid=131,pcp=0),3

可以看到,從port3(eth1)進入的icmp包,被ovs刪掉vlan id后交給port 6(qvoe6366126-d8)了, 但是我們在qvo上抓包卻抓不到,說明qvo把eth1交給他的包丟掉了。
使用tcpdump -i eth1 icmp -w packages.cap 把eth4上的包保存到packages.cap中,在wireshark中打開,可以看到下面的內容:

wireshark截圖

仔細觀察圖中,我們發現,抓到的數據包的大小是1519字節,超過了1518字節的限制,這就是qvo丟棄他的原因吧。但是我們ping使用的是1471個字節的數據,加速8字節的icmp首部,20字節ip頭部,6字節鏈路層源地址,6字節目的地址,2字節幀類型,4字節vlan信息,應該只有1517字節,不超過限制才對。多出來的2字節哪里來的?仔細觀察,發現多出來的兩字節在幀的末尾,被wireshark解析為:vssmonitoring Ethernet trailer。在qvo上抓包,發現抓到的包里面的內容不包括這部分數據,說明是包數據從qvo到eth1的途徑中被加了這兩個額外字節。但是為什么會有這兩個字節額外字節?使用vssmonitoring + openstack在google上搜索,發現了一篇叫openstack network mystery的文章,作者遇到了一樣的問題,作者的解釋是:

Finally, we’ve found the 2 additional bytes! But, where do they come from? Google tells us that this can be caused by the padding of packets at the network-driver level. I reconsidered my setup and identified the USB network adapter as the weakest link. To be honest, I suspected this might be the issue from the beginning, but I never imagined it would catch up with me in this way

.
I downloaded and built the latest version of the driver and replaced the kernel module. Lo and behold, all my networking problems were gone! Pings of arbitrary payload sizes, SSH sessions, and file transfers all suddenly worked. In the end, my networking issues were caused by an issue with the driver that ships by default with the Linux kernel.

作者說是因為他的usb 網卡驅動的問題,我們使用的也是一個usb網卡,那問題看來是一樣的了,去綠聯官網下載最新的驅動,更新到我們的環境中,確實解決了我們的問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM