注:將多塊網卡虛擬成為一塊網卡,使其具有相同的IP地址,來實現提升主機的網絡吞吐量或者是提高可用性,這種技術被稱作bonding。這項技術其實在sun和cisco中已經存在,分別稱為Trunking和etherchannel技術,在Linux中,這種技術稱為bonding。
bonding驅動最早來自于Donald Becker的beowulf對kernel2.0的補丁。但是已經有了很大的改進和變化,最早來自于extreme-linux和beowulf的工具已經不適用于現在版本的驅動了。
對于新版本的驅動,請參考本文最后的鏈結地址。
1、安裝
1) 編譯帶有bonding driver的內核
對于最新版本的bonding驅動,使用內核2.2.18或以上版本(否則需要對內核打補丁)。
使用make menuconfig/xconfig/config來編譯內核,并在"Network device support"部分選擇"Bonding driver support",這里推薦配置該驅動為模塊方式,因為目前這是傳遞給參數給驅動并配置多個bonding設備的唯一方法。
編譯和安裝新的內核和模塊:
make dep;make clean;make bzImage;make modules;make modules_install;
2) 獲取并安裝用戶管理工具
這個版本的bonding驅動需要新的ifenslave程序。來自extreme-linux和beowulf的原始工具程序不能在這里使用。內核2.2.18及其以上版本在Documentation/network中包含文件ifenslave.c。對于更老的內核,請參考文章最后的資源鏈結部分的內容。
安裝ifenslave.c:
# gcc -O2 -s -o ifenslave ifenslave.c
# cp ifenslave /sbin/ifenslave
3) 配置系統
參考下一部分關于模塊參數的內容。首先需要在/etc/conf.modules中添加如下內容:
alias bond0 bonding
使用標準的發布技術來定義bond0這個網絡接口,例如在redhat發布中,在/etc/sysconfig/network-scripts目錄中添加ifcfg-bond0文件:
DEVICE=bond0
IPADDR=192.168.1.1
NETMASK=255.255.255.0
NETWORK=192.168.1.0
BROADCAST=192.168.1.255
ONBOOT=yes
BOOTPROTO=none
USERCTL=no
(使用適當的值來替代IP地址192.168.1)
所有屬于bond的接口動必須被定義為SLAVE或MASTER。例如,在Redhat中,如果希望定義eth0和eth1定義為屬于接口bond0的一部分,那么它們的配置文件(ifcfg-eth0, ifcfg-eth1,等)間如下所示:
DEVICE=eth0
USERCTL=no
ONBOOT=yes
MASTER=bond0
SLAVE=yes
BOOTPROTO=none
(對于eth1使用DEVICE=eth1;如果定義bond2,那么使用MASTER=bond1)。
如果管理工具支持可以重新啟動網絡子系統或者僅僅啟動bonding設備,否則重新啟動機器。(對于redhat發布,使用`ifup bond0@#或`/etc/rc.d/init.d/network restart@#)
如果你的發布提供的管理工具不支持在網絡接口配置中定義master/slave,則需要使用下面的命令手工配置bonding設備:
# /sbin/ifconfig bond0 192.168.1.1 up
# /sbin/ifenslave bond0 eth0
# /sbin/ifenslave bond0 eth1
(根據網絡實際情況定義IP地址等參數)
當然也可以將這些命令定義為一個腳本,以方便執行。
4) 模塊參數
下面的模塊參數可能被傳遞:
mode=
可能的值為0(默認的輪轉模式round robin policy),或者1(熱備份模式),參考下面的HA部分來得到更多的相關信息。
miimon=
整數值,定義MII鏈路監測頻率(單位為頻率)。默認值為0,表示關閉鏈路監測。如果希望使用鏈路監測,一個合適的值為100。參考HA部分得到更多信息。
downdelay=
在發現鏈路故障時,這里規定的整數值定義disable一個鏈路的延遲(單位為毫秒)。必須是miimon的整數倍。默認值為0。參考HA部分得到更多信息。
updelay=
偵測到"link up"狀態時,這里規定的整數值定義了enable一個鏈路的延遲。必須是miimon的整數倍。默認值為0。參考HA部分得到更多信息。
如果需要定義多個bonding設備,驅動必須被多次加載。例如,對于有兩個bonding設備的情況,/etc/conf.modlues必須包含如下內容:
alias bond0 bonding
alias bond1 bonding
options bond0 miimon=100
options bond1 -o bonding1 miimon=100
5) 測試配置
可以通過ifconfig命令來監測配置和傳輸策略,例如對于輪轉策略,你應該得到如下信息:
[root]# /sbin/ifconfig
bond0 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4
inet addr:XXX.XXX.XXX.YYY Bcast:XXX.XXX.XXX.255 Mask:255.255.252.0
UP BROADCAST RUNNING MASTER MULTICAST MTU:1500 Metric:1
RX packets:7224794 errors:0 dropped:0 overruns:0 frame:0
TX packets:3286647 errors:1 dropped:0 overruns:1 carrier:0
collisions:0 txqueuelen:0
eth0 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4
inet addr:XXX.XXX.XXX.YYY Bcast:XXX.XXX.XXX.255 Mask:255.255.252.0
UP BROADCAST RUNNING SLAVE MULTICAST MTU:1500 Metric:1
RX packets:3573025 errors:0 dropped:0 overruns:0 frame:0
TX packets:1643167 errors:1 dropped:0 overruns:1 carrier:0
collisions:0 txqueuelen:100
Interrupt:10 Base address:0x1080
eth1 Link encap:Ethernet HWaddr 00:C0:F0:1F:37:B4
inet addr:XXX.XXX.XXX.YYY Bcast:XXX.XXX.XXX.255 Mask:255.255.252.0
UP BROADCAST RUNNING SLAVE MULTICAST MTU:1500 Metric:1
RX packets:3651769 errors:0 dropped:0 overruns:0 frame:0
TX packets:1643480 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:100
Interrupt:9 Base address:0x1400
問題:
1. bonding會不會和SMP沖突?
不會,老的2.0.xx版本配合SMP使用會發生沖突,而新的內核不會發生問題。
2. 哪種類型的網卡可以用作bonding?
任何類型的網卡(甚至可以使用混合類型的網卡-一個Intel的therExpress PRO/100和a 3com 3c905b),甚至可以將兩個Gigabit以太網卡bond在一起使用。
3. 我可以擁有多少個bonding設備?
對應于加載的一個模塊,就可以擁有一個bonding設備,參考模塊參數部分來了解如何實現。
4. 一個bonding設備可以有多少個salve網卡?
受限于linux可以支持的網卡數量和系統可以插接的網卡數量。
5. 當一個slave鏈路出現故障,會發生什么問題?
如果你的以太網卡支持MII狀態監控,并且MII監測已經在驅動中被使用(參考模塊參數部分內容),那么就不會出現什么不幸的結果。這個版本的bonding驅動能得到MII信息并且根據鏈路狀態來enable或者disable某個slave網卡。參考HA部分得到更多信息。
所有不能報告自己的鏈路狀態的以太驅動不能很好地處理這種情況。bonding驅動不能連續發送數據報,而導致某些數據報丟失。而重傳可能會引起嚴重的性能問題(如果一塊網卡丟失,那么可能會對TCP或UDP帶來嚴重的性能影響)。
6. bonding能被用作高可用性項目么?
當然可以,如果使用了MII監測,并且你所有的網卡驅動都支持MII鏈路狀態匯報。參考HA部分內容。
7. bonding能適用于哪種類型的switches/systems?
在輪轉模式,它和下面支持trunking的系統能一起工作:
* Cisco 5500 series (參考EtherChannel支持相關內容)。
* SunTrunking software.
* Alteon AceDirector switches / WebOS (使用Trunks).
* BayStack Switches (trunks必須被配置). 可堆疊的模塊(450)能在不同的物理單元的端口中定義
* Linux bonding.
對于熱備份模式下,它能和一切二層交換機工作。
8. 一個bonding設備的MAC來自于哪個網卡?
如果沒有明顯使用ifconfig來配置指定,bonding設備的MAC地址從它的第一個slave中得到。這個MAC地址隨即被傳遞個所有其他的slave設備,這些其他的slave設備將具有這個MAC,即使第一個Slave設備被去除。只有bonding設備重起或者down了,MAC地址才會改變。
如果希望修改MAC地址,可以使用ifconfig來設置:
# ifconfig bond0 ha ether 00:11:22:33:44:55
可以通過up/down設備,然后修改其slave的順序來改變bonding設備的MAC地址:
# ifconfig bond0 down ; modprobe -r bonding
# ifconfig bond0 .... up
# ifenslave bond0 eth...
這個方法將自動從下一個將被添加的slave中得到地址。
為了恢復slave的MAC地址,需要將其從bonding設備中分離出來(`ifenslave -d bond0 eth0@#),down掉該設備(`ifconfig eth0 down@#),去除模塊(`rmmod 3c59x@#),然后重載其以使其從其eeproms中得到其MAC地址。若一個驅動被多個設備所擁有,那么需要將其全部down掉。另外一種方法是察看啟動時該卡的MAC地址(dmesg或 tail /var/log/messages),并使用ifconfig來reset它:
# ifconfig eth0 down
# ifconfig eth0 hw ether 00:20:40:60:80:A0
9. 哪些使用哪些傳輸模式?
輪轉模式:基于slave的順序,依次輪轉通過不同網卡發送數據;
熱備份模式:確保在同一時刻僅僅通過一個網卡發送數據,另外一個作為該激活卡的熱備份,在激活卡出現故障時數據流馬上切換到熱備份卡,這種模式常常用于使用交換機的高可用性中(high availability solutions )
高可用性
為了使用bonding驅動實現高可用性,需要將該驅動編譯為模塊,因為目前這時傳遞參數給驅動的唯一方式。以后這種情況可能會改變。首先需要確保所有的網卡支持MII鏈路狀態報告。在Linux2.2.17及以上版本中,所有的百兆以太網和yellowfin千兆以太網都支持MII鏈路狀態報告。如果你的網卡驅動不支持這種技術,那么會將鏈路狀態監測為有故障。
bonding驅動目前通過監測MII狀態注冊器來偵測其所有的slave鏈路。偵測間隔有模塊參數"miimon"來定義。該值為整數值,單位為milliseconds。100ms是一個合適的值,因為太小的值可能影響系統性能。也就是說鏈路發生故障以后在100ms秒以內將會被發現。
例如:
# modprobe bonding miimon=100
或在/etc/modules.conf定義如下內容:
alias bond0 bonding
options bond0 miimon=100
目前對高可用性有兩個策略,依賴于主機是否
a) 主機連接到單臺主機或支持trunking的交換機
b) 主機連接到多個不同的交換機上,或單個不支持trunking的交換機
1) 在單交換機或主機上的HA-負載均衡
這種模式易于配置和理解,只需要簡單的配置遠程設備(主機或交換機)來將數據流量分散在多個端口(trunk, etherchannel等),并配置bonding接口。如果模塊加載時指定了MII參數,MII將自動工作??梢酝ㄟ^去除或恢復不同的鏈路,然后再log文件中察看驅動設備監測到了哪些信息。在監測時,你也許會遇到這樣的問題:如果trunk連接的所有接口都down掉以后,有些具有bug的交換機會長時間地diable trunk??梢酝ㄟ^重新啟動交換機來修正這些問題。
例1:主機和主機間實現倍速:
在每個主機中,運行:
# modprobe bonding miimon=100
# ifconfig bond0 addr
# ifenslave bond0 eth0 eth1
例 2:主機連接交換機以實現倍速:
在主機A中運行:
# modprobe bonding miimon=100
# ifconfig bond0 addr
# ifenslave bond0 eth0 eth1
在交換機中:
#對port1和port2設置trunking。
2) 在多個交換機或主機上的HA-負載均衡(或不支持trunking技術的單交換機情況)
這種模式更可能會出現問題,因為它依賴于這樣的事實:雖然有多個端口,但是主機MAC地址只能被一個端口可見以避免混淆交換機。
如果需要知道哪個哪個端口是活動的,哪個是備份的,那就使用ifconfig。所有的備份接口設置有NOAEP標志。為了使用該模式,在加載時傳遞"mode=1"給模塊:
# modprobe bonding miimon=100 mode=1
或者在/etc/modules.conf中添加如下內容:
alias bond0 bonding
options bond0 miimon=100 mode=1
例1:使用多個主機和多個交換機來創建"無單故障點瓶頸"解決方案:
在這種配置下,這里有一個ISL- 交換機間連接(Inter Switch Link,可能是一個trunk),多個主機(host1, host2 ...)都同時連接到交換機,并且多個端口連接到外部網絡(port3...),每個主機中同時只有一個slave是激活的,但是所有的鏈路仍然被監測(系統能監測到活動鏈路的故障并啟動備份鏈路)。
如果host1和host2具有同樣的功能,并且被用在負載均衡中,那么將host1的活動接口連接到其中一個交換機而host2連接到另外一個交換機上是一個非常不錯的選擇。這種系統在單個主機、交換機或者線路出問題時仍能保證工作。最糟糕可能情況是,單個交換機出現故障,其中一臺主機將不可訪問,直到另外一個交換機維護的轉發表過期,另外一個主機才會轉換激活接口到正常的交換機上。
例 2:使用多個以太網卡連接到一個交換機,以應付NIC故障的情況,以提高可用性:
在主機A中:
# modprobe bonding miimon=100 mode=1
# ifconfig bond0 addr
# ifenslave bond0 eth0 eth1
在交換機中:
# (可選地)最小化轉發表過期時間
每次主機切換其活動接口,它將使用新的接口直到該接口出現故障。在這個例子中,主機受交換機轉發表的過期時間影響很大。
3) 調整交換機的頻率
如果交換機轉換到備份接口需要花費太長的時間,一般來說都希望在當前接口發生故障的情況下立即啟用備用接口??梢酝ㄟ^傳遞模塊參數"downdelay"來實現減少完全disable一個接口的延遲。
當一個交換機重啟以后,可能出現其端口在端口可用以前報告"link up"狀態。這可能使得bonding設備使用還不可用的端口這可能通過傳遞模塊參數"updelay"來延遲活動端口被重新可用的時間。
當一個主機和交換機重新交互以確定一個丟失的鏈路也會出現同樣的問題。
在bonding接口丟失了其所有的slave鏈路的情情況下,則驅動將馬上使用第一個up的接口,而不受updelay參數的限制。這樣可以減少系統down的時間。
例如:
# modprobe bonding miimon=100 mode=1 downdelay=2000 updelay=5000
# modprobe bonding miimon=100 mode=0 downdelay=0 updelay=5000
4) 限制
主要限制是:
只有鏈路狀態被監控,如果交換機本身down掉了,例如不再轉發數據但是鏈路仍然完好。則鏈路不會被diable。另外一個監測故障鏈路的方式統計一個沉重負載主機的接入數據幀數量。但是對于哪些負載較小的服務器則不大適用。
資源鏈結
Donald Becker的以太驅動和diag程序可以在下面的到:
-
- (seems to be dead now)
- (seems to be dead now)
還可以在得到很多關于ethernet、NWay和MII等信息。Y
對于新版本的驅動,牢的內核補丁和更新的用戶空間工具可以在Willy Tarreau的網站中得到:
-
-
為了得到最新的關于Linux Kernel開發信息,請關注:
Linux2.4.x內核bonding的實現
因為bonding在內核2.4.x中已經包含了,只需要在編譯的時候把網絡設備選項中的Bonding driver support選中就可以了。然后,重新編譯核心,重新起動計算機,執行如下命令:
insmod bonding
ifconfig eth0 down
ifconfig eth1 down
ifconfig bond0 ipaddress
ifenslave bond0 eth0
ifenslave bond0 eth1
現在兩塊網卡已經象一塊一樣工作了.這樣可以提高集群節點間的數據傳輸。你最好把這幾句寫成一個腳本,再由/etc/rc.d/rc.local調用,以便一開機就生效。
bonding對于服務器來是個比較好的選擇,在沒有千兆網卡時,用兩三塊100兆網卡作bonding,可大大提高服務器到交換機之間的帶寬.但是需要在交換機上設置連接bonding網卡的兩個口子映射為同一個虛擬接口(trunking技術)。
下面是引自郵件列表的一個信,希望能對出現問題時有所幫助:
> I have found a solution to another problem with the bonding driver.
>
> If you ifconfig down an enslaved eth device, the bonding driver is not
> notified and if there is an attempt to use the device then a crash
> results. I have added a one line fix to dev_close in net/core/dev.c
>
> /* if the device is a slave we should not touch it*/
> if(dev->flags&IFF_SLAVE)
> return -EBUSY;
>
> I put it after the check to see if the interface is up.
>
> This may not be the best solution but it prevents the kernel crashes and
> as bond_release is not implemented there is not much point making the
> device release it`s self.
>
> Since I made this change and the one in my last message I have not been
> able to produce a crash.
>
> (here is a script which will cause the crash on 2.2.16)
> #!/bin/bash
> insmod eepro100
> insmod bonding
> ifconfig bond0 192.168.1.2 up
> ifenslave bond0 eth0
> ifconfig eth0 down
> ifconfig bond0 down
> ifconfig bond0 192.168.1.2 up
> ifconfig bond0 down
>
> Again, if someone could confirm this fix it would be good. @#