歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> 鏈路層的網卡聚合-基於Linux bonding

鏈路層的網卡聚合-基於Linux bonding

日期:2017/2/28 16:16:25   编辑:Linux教程

Linux總是可以用一種最簡單的方式實現一個很復雜的功能,特別是網絡方面的 ,哪怕這個功能被認為只是在高端設備上才有,linux也可以很容易的實現,以前的文章已經說了不少次了,比如vlan功能,比如高級路由和防火牆功能等等,本文著重說一下linux的bonding,也就是端口聚合的功能模塊。不可否認,在網絡設備這個層面上上,linux搞出了兩個很成功的虛擬設備的概念,一個是tap網卡,另一個就是本文所講述的bonding,關於tap網卡的內容,請參閱之前關於OpenVPN的文章。

如果有一個問題擺在眼前,那就是關於linux bonding有什麼比較好的資料,答案就是linux內核的文檔,該文檔在$KERNEL-ROOT/Documentation/networking/bonding.txt,我覺得沒有任何資料比這個更權威了。
一、bonding簡介
bonding是一個linux kernel的driver,加載了它以後,linux支持將多個物理網卡捆綁成一個虛擬的bond網卡,隨著版本的升級,bond驅動可配置的參數越來越多,而且配置本身也越來越方便了。
我們在很多地方會使用到物理網卡端口匯聚的功能,比如我們想提升網絡速率,比如我們想提供熱備份,比如我們想把我們的主機配置成一個網橋,並且使之支持802.3ad動態端口聚合協議等等,然而最重要的還是兩點,第一點是負載均衡,第二點就是熱備份啦。
二、驅動以及Changes介紹
linux的bonding驅動的最初版本僅僅提供了基本的機制,而且需要在加載模塊的時候指定配置參數,如果想更改配置參數,那麼必須重新加載bonding模塊;然後modprobe支持一種rename的機制,也就是在modprobe的時候支持使用-o重新為此模塊命名 ,這樣就可以實現一個模塊以不同的配置參數加載多次了,起初比如我有4個網口,想把兩個配置成負載均衡,兩個配置成熱備,這只能手工重新將bonding編譯成不同的名稱來解決,modprobe有了-o選項之後,就可以兩次加載相同的驅動了,比如可以使用:
modprobe bonding -o bond0 mode=0
modprobe bonding -o bond1 mode=1

加載兩次bonding驅動,用lsmod看一下,結果是bond0和bond1,並沒有bonding,這是由於modprobe加載時命名了,然而最終,這個命名機制不再被支持了,因為正如modprobe的man手冊所敘述的一樣,-o重命名機制主要適用於test。最後,bonding支持了sysfs的配置機制,對/sys/class/net/目錄下的文件進行讀或者寫就可以完成對驅動的配置。
不管怎樣,在sysfs完全支持bonding配置之前,如果想往某一個bonding網卡添加設備或者刪除設備的時候,還是要使用經典且傳統的ioctl調用,因此必然需要一個用戶態程序與之對應,該程序就是ifenslave。
我想,如果linux的所有關於設備的配置都能統一於sysfs,所有的關於內核和進程配置統一於procfs(內核是所有進程共享的地址空間,也有自己的內核線程以及進程0,因此對內核的配置應該在procfs中),對所有的消息,使用netlink通信,這就太好了,擺脫了命令式的ioctl配置,文件式(netlink使用的sendto之類的系統調用也可以歸為文件系統調用相關的)的配置將更加高效,簡單以及好玩!
三、bonding配置參數
在內核文檔中,列舉了許多bonding驅動的參數,然後本文不是文檔的翻譯,因此不再翻譯文檔和介紹和主題無關的參數,僅對比較重要的參數進行介紹,並且這些介紹也不是翻譯,而是一些建議或者心得。
ad_select: 802.3ad相關。如果不明白這個,那不要緊,拋開Linux的bonding驅動,直接去看802.3ad的規范就可以了。列舉這個選項說明linux bonding驅動完全支持了動態端口聚合協議。
arp_interval和arp_ip_target: 以一個固定的間隔向某些固定的地址發送arp,以監控鏈路。有些配置下,需要使用arp來監控鏈路,因為這是一種三層的鏈路監控 ,使用網卡狀態或者鏈路層pdu監控只能監控到雙絞線兩端的接口 的健康情況,而監控不到到下一條路由器或者目的主機之間的全部鏈路的健康狀況。
primary: 表示優先權,順序排列,當出現某種選擇事件時,按照從前到後的順序選擇網口,比如802.3ad協議中的選擇行為。
fail_over_mac: 對於熱備模式是否使用同一個mac地址,如果不使用一個mac的話,就要完全依賴免費arp機制更新其它機器的arp緩存了。比如,兩個有網卡,網卡1和網卡2處於熱備模式,網卡1的mac是mac1,網卡2的mac是mac2,網卡1一直是master,但是網卡1突然down掉了,此時需要網卡2接替,然而網卡2的mac地址與之前的網卡1不同,別的主機回復數據包的時候還是使用網卡1的mac地址來回復的,由於mac1已經不在網絡上了,這就會導致數據包將不會被任何網卡接收。因此網卡2接替了master的角色之後,最好有一個回調事件,處理這個事件的時候,進行一次免費的arp廣播,廣播自己更換了mac地址。
lacp_rate: 發送802.3ad的LACPDU,以便對端設備自動獲取鏈路聚合的信息。
max_bonds: 初始時創建bond設備接口的數量,默認值是1。但是這個參數並不影響可以創建的最大的bond設備數量。
use_carrier: 使用MII的ioctl還是使用驅動獲取保持的狀態,如果是前者的話需要自己調用mii的接口進行硬件檢測,而後者則是驅動自動進行硬件檢測(使用watchdog或者定時器),bonding驅動只是獲取結果,然而這依賴網卡驅動必須支持狀態檢測,如果不支持的話,網卡的狀態將一直是on。
mode: 這個參數最重要,配置以什麼模式運行,這個參數在bond設備up狀態下是不能更改的,必須先down設備(使用ifconfig bondX down)才可以配置,主要的有以下幾個:
1.balance-rr or 0: 輪轉方式的負載均衡模式,流量輪流在各個bondX的真實設備之間分發。注意,一定要用狀態檢測機制,否則如果一個設備down掉以後,由於沒有狀態檢測,該設備將一直是up狀態,仍然接受發送任務,這將會出現丟包。
2.active-backup or 1: 熱備模式。在比較高的版本中,免費arp會在切換時自動發送,避免一些故障,比如fail_over_mac參數描述的故障。
3.balance-xor or 2: 我不知道既然bonding有了xmit_hash_policy這個參數,為何還要將之單獨設置成一種模式,在這個模式中,流量也是分發的,和輪轉負載不同的是,它使用源/目的mac地址為自變量通過xor|mod函數計算出到底將數據包分發到哪一個口。
4.broadcast or 3: 向所有的口廣播數據,這個模式很XX,但是容錯性很強大。
5.802.3ad or 4: 這個就不多說了,就是以802.3ad的方式運行。
...
xmit_hash_policy: 這個參數的重要性我認為僅次於mode參數,mode參數定義了分發模式 ,而這個參數定義了分發策略 ,文檔上說這個參數用於mode2和mode4,我覺得還可以定義更為復雜的策略呢。
1.layer2: 使用二層幀頭作為計算分發出口的參數,這導致通過同一個網關的數據流將完全從一個端口發送,為了更加細化分發策略,必須使用一些三層信息,然而卻增加了計算開銷,天啊,一切都要權衡!
2.layer2+3: 在1的基礎上增加了三層的ip報頭信息,計算量增加了,然而負載卻更加均衡了,一個個主機到主機的數據流形成並且同一個流被分發到同一個端口,根據這個思想,如果要使負載更加均衡,我們在繼續增加代價的前提下可以拿到4層的信息。
3.layer3+4: 這個還用多說嗎?可以形成一個個端口到端口的流,負載更加均衡。然而且慢! 事情還沒有結束,雖然策略上我們不想將同一個tcp流的傳輸處理並行化以避免re-order或者re-transmit,因為tcp本身就是一個串行協議,比如Intel的8257X系列網卡芯片都在盡量減少將一個tcp流的包分發到不同的cpu,同樣,端口聚合的環境下,同一個tcp流也應該使用本policy使用同一個端口發送,但是不要忘記,tcp要經過ip,而ip是可能要分段的,分了段的ip數據報中直到其被重組(到達對端或者到達一個使用nat的設備)都再也不能將之劃為某個tcp流了。ip是一個完全無連接的協議,它只關心按照本地的mtu進行分段而不管別的,這就導致很多時候我們使用layer3+4策略不會得到完全滿意的結果。可是事情又不是那麼嚴重,因為ip只是依照本地的mtu進行分段,而tcp是端到端的,它可以使用諸如mss以及mtu發現之類的機制配合滑動窗口機制最大限度減少ip分段,因此layer3+4策略,很OK!
miimon和arp: 使用miimon僅能檢測鏈路層的狀態,也就是鏈路層的端到端連接(即交換機某個口和與之直連的本地網卡口),然而交換機的上行口如果down掉了還是無法檢測到,因此必然需要網絡層的狀態檢測,最簡單也是最直接的方式就是arp了,可以直接arp網關,如果定時器到期網關還沒有回復arp reply,則認為鏈路不通了。

Copyright © Linux教程網 All Rights Reserved