近期的項目中遇到了這樣一個問題,引發了筆者對linux bond和lacp協議的一些研究:
情景:
如上圖所示,server有兩張網卡配置了bond0, 工作在mode4負載均衡模式下, 現在從client對server進行持續的ping測試,發現:
- 插拔server端物理網口的網線時, ping一直正常,無丟包;
- 用ifconfig down enp4s0f0/1 來關閉物理網口時,ping會丟包,且持續1分多鐘,之後恢復正常;
這個測試結果實在是非常的令人髮指,bond技術的初衷就是爲了鏈路冗餘和增加帶寬,現在卻發現在人爲關閉其中一個物理網口後,竟然會造成如此長時間的網絡中斷,不得不教人對其深究一二了,爲了解決這個問題,我們必須搞清楚以下幾個問題:
- 插拔網線時,網絡正常,說明bond保證了鏈路冗餘,是如何做到的?
- ifconfig down關閉網口時,網絡中斷,說明bond沒有保證鏈路冗餘,爲什麼?
- 網絡中斷後,是怎麼自動恢復的?
- 在bond無法保證鏈路冗餘時,爲何中斷時間這麼長?
此處貼上server上的網卡配置文件,注意倒數第2,3行的註釋信息,這將是本文討論的重點內容:
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
# The loopback network interface
auto lo
iface lo inet loopback
auto enp4s0f0
iface enp4s0f0 inet manual
bond-master bond0
auto enp4s0f1
iface enp4s0f1 inet manual
bond-master bond0
# mgmt network
auto bond0
iface bond0 inet static
address 172.31.20.22
mtu 1550
netmask 255.255.255.0
gateway 172.31.20.254
dns-nameservers 172.31.20.64
bond-mode 4
bond-miimon 100 # mii對slave網口的檢測週期,爲100ms
bond-lacp-rate 1 # lacpud發送週期爲1s,配置爲0則爲30s
bond-slaves enp4s0f0 enp4s0f1
問題1:插拔網線時,網絡正常,說明bond保證了鏈路冗餘,是如何做到的?
解答:bond爲了保證鏈路高可用,提供了兩種鏈路檢測機制,分別是MII檢測和ARP檢測,上述配置中,`bond-miimon 100`表示bond進行MII檢測的週期爲100ms,在拔掉網線時,bond的MII檢測會發現相應網口的鏈路故障,從而將流量引導到健康的網口上,關於MII檢測的深入信息,與本文關係不大,可以參考IBM的相關文檔。
問題2:既然bond可以檢測到鏈路故障,爲何在ifconfig down關閉網口時不能呢?
解答:bond的去讀取/proc/net/bonding/bond0這個文件,去獲取bond相關接口的狀態信息,來達到檢測的目的,正常情況下,該文件如下, 可以看到(已省去不必要的信息),bond0以及兩個物理網口下,`MII Status: up`:
root@tr02n12:~# cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)
Bonding Mode: IEEE 802.3ad Dynamic link aggregation
Transmit Hash Policy: layer2 (0)
MII Status: up
...
...
Slave Interface: enp4s0f0
MII Status: up
...
...
Slave Interface: enp4s0f1
MII Status: up
...
...
如果拔掉enp4s0f0對應的網口,則會發現,enp4s0f0下會發生改變 `MII Status: down`, bond由此知道了該接口故障,將流量引導到enp4s0f1;
root@tr02n12:~# cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)
Bonding Mode: IEEE 802.3ad Dynamic link aggregation
Transmit Hash Policy: layer2 (0)
MII Status: up
...
...
Slave Interface: enp4s0f0
MII Status: down
...
...
Slave Interface: enp4s0f1
MII Status: up
...
...
那麼如果使用命令關閉網口呢,讓我們測試一下, 發現該文件中enp4s0f1的相關信息被刪去了,因此bond不能獲取到enp4s0f1的MII Status,也就無法檢測到該條鏈路故障,也無法保證鏈路高可用了:
root@tr02n12:~# ifdown enp4s0f1
root@tr02n12:~# cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)
Bonding Mode: IEEE 802.3ad Dynamic link aggregation
Transmit Hash Policy: layer2 (0)
MII Status: up
...
...
Slave Interface: enp4s0f0
MII Status: up
問題3:網絡中斷後,是怎麼自動恢復的?
解答:既然在運行命令關閉網口的情形下,bond無法做到故障檢測,那麼網絡在一段時間後是如何自動恢復的呢?從bond的配置文件中,我們可以看到`bond-mode 4`, 這個模式也叫做802.3ad模式,可基於LACP協議保證鏈路的高可用,在故障時自動恢復,因此,這個問題的答案就是,網絡中斷是因爲bond沒有檢測到鏈路故障,而LACP檢測到了鏈路故障並進行了自動恢復,LACP是如何進行鏈路恢復的呢,這將在下一個問題中進行說明。
問題4:在bond無法保證鏈路冗餘時,爲何中斷時間這麼長?
解答:LACP鏈路聚合的兩端設備的網口間,通過LACPDU與對端交換信息,首先讓我們來看一下LACP報文的格式,其中:
LACP_Timeout:代表鏈路接收LACPDU報文的週期,有兩種,快週期1s和慢週期30s,超時時間爲週期的3倍。短超時被編碼爲1,長超時被編碼爲0。
這一字段規定了超時時間,如果在超時時間內沒有收到對端發送的LACPDU, 則認爲鏈路故障,進行鏈路切換。在鏈路兩端設備的LACP_Timeout值不一致時,以長的一方爲準。鑑於我們的情景中,網絡中斷的時間足有1分多鐘,有理由懷疑是因爲此處超時時間協商爲了90s,從配置文件中, `lacp-rate fast`表示server的bond口該字段配置的是短超時,那麼問題有可能出現在對端交換機的聚合口配置上,讓我們用tcpdump抓包驗證一下(在enp4s0f0上抓取1個二層協議類型爲0x8809,即LACP協議的包,並顯示詳細信息):
root@tr02n12:~# tcpdump -e ether -i enp4s0f0 proto 0x8809 -vv -c 1
tcpdump: listening on enp4s0f0, link-type EN10MB (Ethernet), capture size 262144 bytes
17:54:03.486988 ec:0d:9a:9c:99:56 (oui Unknown) > 01:80:c2:00:00:02 (oui Unknown), ethertype Slow Protocols (0x8809), length 124: LACPv1, length 110
Actor Information TLV (0x01), length 20
System ec:0d:9a:9c:99:56 (oui Unknown), System Priority 65535, Key 15, Port 3, Port Priority 255
State Flags [Activity, Timeout, Aggregation, Synchronization, Collecting, Distributing]
Partner Information TLV (0x02), length 20
System 5c:83:8f:4b:eb:c1 (oui Unknown), System Priority 32768, Key 126, Port 283, Port Priority 32768
State Flags [Activity, Aggregation, Synchronization, Collecting, Distributing]
Collector Information TLV (0x03), length 16
Max Delay 0
Terminator TLV (0x00), length 0
1 packet captured
1 packet received by filter
0 packets dropped by kernel
通過對比enp4s0f0的mac地址,可以確定上面這個包爲從enp4s0f0發送給對端LACP接口的LACPDU包,按照LACP報文的格式中的信息,可以看出,對端沒有置位Timeout位,因此是設置的長超時,也就是90s,因此鏈路恢復的時間纔會如此長。要解決該問題,則需要在交換機上對應的聚合端口也配置lacp超時時間爲短超時,這樣的話,在手動關閉網口後的恢復時間應會變成3s左右。
小結
本文通過一個手動關閉端口引發的bond口中斷故障,進行分析,闡明瞭bond的鏈路檢測及高可用原理,驗證LACP的超時時間參數效果。解釋了bond下插拔網線和命令關閉端口造成結果不同的原因。