故障現象
在監控上發現部分虛拟機每隔大概20分鐘就會出現一次入口流量高峰,大小在1MB/s左右:

故障原因
交換機上配置了廣播抑制,導緻整個環境中沒有廣播包。在計算節點上Linux Bridge的MAC learning table中網關對應的MAC位址過期後(預設值300秒),沒有及時更新,Linux Bridge會把本來應該發到網關對應端口的資料包發送到所有端口。部分業務Client虛拟機會持續向業務Server發送資料,當網關MAC 失效後,本來發送給業務Server的資料包被發送給了同主控端上的所有虛拟機,是以出現入口流量峰值。
處理方法
方法一:解除交換機上的廣播抑制。
方法二:配置Linux Bridge的MAC Ageing Time為1500秒,此時間大于交換機ARP的過期時間,保證在Linux Bridge上的網關MAC位址記錄過期之前收到來自網關的ARP請求包,因而可以及時更新網關MAC位址。
排查過程
在虛拟機出現流量峰值時,登陸到虛拟機使用iftop檢視流量詳情:
# iftop -nNBP
發現峰值流量的源目的位址都不是本機,于是分别檢視源目的位址機器,經過粗略分析判斷目的位址是業務Server,源位址是某台業務Client伺服器,業務Client發送給業務Server的流量竄到其他虛拟機上了。
下意識感覺受害虛拟機跟這兩個機器應該存在某些關聯,由于目的機器是一台實體機,關系應該不大,于是重點檢視源位址,這是一台虛拟機。果然,發現這兩台虛拟機位于同一台主控端上。檢視主控端上的其他虛拟機,存在同樣的問題:
繼續去受害虛拟機上抓包,分析錯誤發來的資料包存在什麼特征,因為Linux Bridge執行二層轉發的功能,于是列印出資料包的鍊路頭資訊:
# tcpdump -e -nnn host 10.212.26.241 and host 10.212.13.14
發現目的MAC都是10:0a:10:0b:10:0c,這明顯不是一個正常的MAC位址,檢視arp表:
顯示這個MAC位址對應的是網關。到主控端上檢視arp表,結果一樣:
猜測這是在交換機上的封裝過的MAC位址,這不重要,對于整個虛拟化環境來說,它就是網關的MAC位址。在主控端上抓包:
可以看到源目的IP正常通信的往來資料包。而且在正常情況下,受害虛拟機沒有收到誤轉發流量包時,實體機上也能抓到形式一樣的資料包。那麼在什麼情況下,本應發送給網關的資料包會被網橋錯誤地轉發給虛拟機呢?
經過一番搜尋,查到了Linux Bridge的MAC learning table這個東西,交換機上也有一樣的概念。它記錄着網橋的每個端口連接配接着同個二層網絡的哪些MAC位址,即便跨越了多個交換機。使用brctl showmacs BR-NAME檢視Linux Bridge的MAC learning table:
而在出現異常流量時,MAC learning table是這樣的:
明顯看到網關的MAC消失了。這是因為預設MAC learning table記錄的過期時間是300秒,超過300秒後記錄就被删除。而每當收到某個端口資料包時,Linux Bridge會更新這個資料包的源MAC位址到MAC learning table。
經過觀察發現MAC learning table中網關的記錄會不定期地在ageing time到達幾十秒、一百多秒時更新一次,但是周期性地會有一次不更新,在ageing time達到300秒後消失幾分鐘,也正是在網關MAC消失的這個時間段内虛拟機上會出現異常流量。
在實體交換機上,如果資料包的目的MAC位址在MAC learning table裡找不到,那麼這個資料包會被丢棄,但是由于我們的Linux Bridge沒有開啟STP,它會将資料包發送到所有端口,類似一個集線器。
因為有多個叢集,為什麼其他叢集是正常的而隻有這個叢集出現問題。在不同叢集的計算節點上抓包:
看到在正常環境中會頻繁收到來自網關的ARP廣播,所已Linux Bridge能夠及時更新MAC learning table,而在問題叢集中,完全沒有廣播包,隻有在網關需要查詢這個主機上存在的機器時,才會發送一個ARP單點傳播包。這超出了正常的認知,懷疑是交換機做了特殊配置,跟網絡組溝通,又向廠商詢問後,得到回複确實是為了避免泛洪,交換機上配置了廣播抑制,才出現這樣的情況。
那麼如何解決呢,一個辦法是關閉交換機的廣播抑制,但是這樣會引入廣播泛洪的風險。另一個辦法是将計算節點Linux Bridge的MAC Ageing Time調高,使它超過交換機上ARP的過期時間,這樣就能保證在網關MAC位址記錄過期之前收到來自網關的ARP請求包,因而可以及時更新網關MAC位址。目前設定Ageing Time為1500秒:
# brctl setageing brqa96cd777-01 1500
為了保證配置不失效,将指令寫入/sbin/ifup-local腳本,這個腳本會在每個網絡裝置啟動後,被/etc/sysconfig/network-scripts/ifup-post調用。/sbin/ifup-local内容:
if [[ "$1" == "brq"* ]]; then
/sbin/brctl setageing $1 1500
fi
參考文檔
How to disable MAC learning in a Linux bridge ARP Timeout Value for Cisco 3750, Linux and Windows How to configure a Linux Bridge to act as a Hub instead of a Switch CentOS: Start custom script automatically after network startup