Link aggregation
網路聚合(Link Aggregation),在電腦網路領域這個名詞代表的是將多重網路介面NIC(Network interfaces)用並列的方式結合來增進網路流量,也可以提高其容錯能力。主要的方式是建立一個LAG(Link Aggregation Group),而這個LAG群組底下會有多個實體的埠(port),每個port都有辦法處理高流量的封包,所以將這些port都結合在一起的話,就可以增加很大的彈性。
在Link Aggregation這個名詞底下又有衍生其他相同類型的字眼,像是『port trunking』,『link bundling』『Ethernet/network/NIC bonding』,『NIC teaming』..等等。這些衍生的專有名詞通常都環繞著各個廠商的標準像是,在『IEEE 802.1AX』,『IEEE 802.1aq』或是之前的『IEEE802.3ad』裡對乙太網路定義的『Link Aggregation Control Protocol(LACP)』等等。
網路架構上可以在OSI的最低三層來實現Link Aggregation的功能:
- Layer 1 (實體層): 包含了使用電源線(e.g. IEEE 1901)和無線網路(e.g. IEEE 802.11)裝置來結合多重頻寬。
- Layer 2 (連接層): 通常聚合會發生在跨埠口(switch ports),不管是實體的port還是由作業系統所管理的虛擬port。
- Layer 3 (網路層): 在這一層可以使用『round-robin scheduling』或是從封包標頭檔所算得的『hash 』雜湊值,當然你也可以結合這兩項。
不管以上選擇如何實做,這都會在所有連結之間來平衡所有的網路流量,而大部分的方法都提供很大的容錯能力。而每個聚合都可以在多個介面之間分享單一個邏輯位址(i.e. ip)或是一個實體位址(i.e. MAC 位址),也允許每個NIC擁有自己的位址。
在多數比較高階的裝置上,都有部分支援Link Aggregation,又或者是有軟體的實作,像是BSD的lagg package,Linux的 bonding driver和teaming driver,還有Solaris 的dladm aggr等等。
Linux Bonding and Teaming
在這篇文張裡面,主要是要介紹在Linux底下,要怎麼去實作Link Aggregation的功能,這邊挑了兩個目前主要的技術-『bonding』和『teaming』,主要也是透過將多個實體NIC分配到單一個邏輯網路,這樣可以增加網路的流通量和穩定性和讀取平衡。舉例來說,可以將兩個NIC「eth0」和「eth1」組成一個群組「group1」,然後分配一個IP給這個群組,這樣的話,你就有兩倍的流量了,又或者是你也可以設置成備用的用途,像是如果eth0壞掉了,這個群組會自動的改走「eth1」。
Bonding in Ubuntu
安裝
sudo apt-get install ifenslave
介面組態
Step 1: 確保Kernel支援
在Ubuntu可以將你的NIC綁訂成一個群組之前,你必須要先確保你的核心模組(kernel module)-『bonding』已經正確的啟動,並且在開機時已經被讀取了。
編輯你的組態檔『/etc/modules』:
sudo vim /etc/modules
確保『bonding』模組已經被讀取了,如果沒有的話,就請填入如下圖一樣吧:
Step 2: 設定NIC組態
首先確認你有兩個以上的NICs,像我的是『enp0s3』和『enp0s8』如下:
在來就是確保你的網路已經關掉了:
sudo systemctl stop networking
然後讀取bonding的核心模組:
sudo modprobe bonding
加下來就要來準備設定你的NICs了,
大致的步驟會如下:
1. 選擇哪幾個NICs你要加入到群組裡 - (假設是enp0s3和enp0s8)。
2. 如往常般設定這些NICs。
3. 將這些NICs加入群組 - (bond0) :
4. 設定這個NIC群組,把它當成一般的NIC就好。
5. 在這個NIC群組裡面加入一些額外的參數 - (假設mode是active-backup)。
所以根據以上的情境,我們就是要將『enp0s3』和『enp0s8』這兩個NIC給綁定成群組『bond0』的兩個slaves,模式設定為active-backup,然後主要介面為『enp0s3』,並且給予bond0一組static的IP。
編輯你的檔案:
sudo vim /etc/network/interfaces
#enp0s3 is manually configured, and slave to the "bond0" bonded NIC
auto enp0s3
iface enp0s3 inet manual
bond-master bond0
bond-primary enp0s3
#enp0s8 ditto, thus creating a 2-link bond.
auto enp0s8
iface enp0s8 inet manual
bond-master bond0
#bond0 is the bonding NIC and can be used like any other normal NIC.
#bond0 is configured using static network information.
auto bond0
iface bond0 inet static
address 192.168.1.29
gateway 192.168.1.1
netmask 255.255.255.0
bond-mode active-backup
bond-miimon 100
bond-slaves none
最後,啟動你的網路:
sudo systemctl start networking
檢查bonding介面
到這一步應該已經設定好了,也啟動我們的NIC群組了,就來檢查一下:
# cat /proc/net/bonding/bond0
Ethernet Channel Bonding Driver: v3.7.1 (April 27, 2011)
Bonding Mode: fault-tolerance (active-backup)
Primary Slave: enp0s3 (primary_reselect always)
Currently Active Slave: enp0s3
MII Status: up
MII Polling Interval (ms): 100
Up Delay (ms): 0
Down Delay (ms): 0
Slave Interface: enp0s3
MII Status: up
Speed: 1000 Mbps
Duplex: full
Link Failure Count: 0
Permanent HW addr: 08:00:27:1e:b6:9a
Slave queue ID: 0
開啟/關閉bonding介面
啟動介面bonding,請輸入:
ifup bond0
關閉介面,請輸入:
ifdown bond0
Ethernet Bonding模式
在bonding裡面有許多不同的模式可以選擇,就像是上面的例子,我們選用的方式是:
bond-mode active-backup
底下是各個模式的描述介紹
Mode 0
blance-rr
將傳輸(傳送/接收)的網路封包依序的從第一個到最後一個分配,這個模式提供了平衡讀取和容錯能力。
Mode 1
active-backup
這個模式之下只會啟動一個slave,只有在這個已經啟動的slave失敗的狀態之下才會去啟動其他的slave。簡單來說就是其他的slave都是備用。這個bond的MAC址在外部只會看得到一個port,以防止切換的混亂。在這個模式之下提供了很高的容錯能力。在這個模式底下你可以利用選項『primary』來設定你預設啟動的主要slave。
Mode 2
balance-xor
傳輸的方式使用可選擇性的雜湊(hashing)演算法,預設的方式是簡單的來源+目的 MAC位址演算法。而其他替代的傳輸方式可經由選項『xmit_hash_policy』來選擇,balance-xor同樣也提供讀取平衡和容錯。
Mode 3
booadcast
會傳輸到所有的slave介面,只提供容錯能力。
Mode 4
802.2ad
IEEE 802.3ad動態網路聚合(Dynamic link aggregation),建立了分享相同速度和雙工(duplex)設定的聚合群組,根據802.3ad規格在『aggregator』群組裡面建立slave。
要使用這個模式的話,需要兩個先決條件:
- 需要有Ethtool,因為底層的驅動程式就需要用它來取得各個slave的速率和多工狀態。
- 你的switch需要支援IEEE802.3ad動態網路聚合。通常大部份的switch都需要某種的設定才能開啟這個功能。
Mode 5
balance-tlb
這個模式採用『Adaptive transmit load balancing』,向外傳送會根據目前各個slave的的平均負載來分配。接收的話則只會由目前的slave。如果目前的接收slave出問題了,則其它的slave將會將目前這個失敗的slave的MAC位址拿來自己用,並且開始充當接收slave的角色。
使用這個模式不需要任何特殊的switch支援,但是需要有Ethtool,因為底層的驅動程式就需要用它來取得各個slave的速率。
Mode 6
balance-alb
這個模式採用『Adaptive load balancing』,其中對於IPV4的流量包含了balance-tlb和receive load balancing(rlb),並且也不需要特殊的switch支援。這部份的rlb是透過ARP協商所完成的。bonding的驅動程式會攔截由主機所送出的封包的ARP回應,並且將我們某個slave的獨特的硬體位址給複寫到封包的來源硬體位址上去。
Descriptions of balancing algorithm modes
平衡演算法(balancing algorithm)是由選項『xmit_hash_policy』來設定的。
主要的內容為:
layer2 - 使用MAC位址的XOR來產生雜湊表(hash)。這個演算法將會把所有的流量給放置到相同slave上的特定端點上。
layer2+3 - 使用MAC位址和IP位址的XOR來產生雜湊表(hash)。 這個演算法將會把所有的流量給放置到相同slave上的特定端點上。
layer3+4 - 主要利用上層協定的資訊來產生雜湊表。這個演算法可以允許到特定端點的流量跨到多重的slave上,雖然單一個連線不會跨到多重的slave身上。
encap2+3 - 這個演算法使用的跟layer2+3一樣,但是它主要用『skb_flow_dissect』來獲取標頭欄位(header field),而這個欄位將會在你使用encapsulation protocol時,帶入到內部的標頭檔裡。
encap3+4 - 這個演算法使用的跟layer3+4一樣,但是它主要用『skb_flow_dissect』來獲取標頭欄位(header field),而這個欄位將會在你使用encapsulation protocol時,帶入到內部的標頭檔裡。
這些演算法的預設值為layer2。這個選項在版本2.6.3時就被加入了。在更早期的bonding版本裡,這個參數根本不存在,因為只有layer2一個而已。而layer2+3則是在版本3.2.2被加入的。
Teaming in RedHat
安裝Teaming Daemon
[root@ ~]yum install teamd -y
使用nmcli設定teaming的組態
「nmcli」是一套Network Manager的cmd工具,首先我們可以藉由底下的指令來顯示我們有的NIC
[root@ ~]nmcli con show
如上圖所示,我要將「enp0s8」和「enp0s9」組成「team0」,指令如下
[root@ ~]nmcli con add type team con-name team0
在一次看一下NIC,你會發現多一個叫「team 0」的nm-team 裝置檔:
下個步驟,將「enp0s8」和「enp0s9」加到「team0」裡面:
[root@ ~]nmcli con add type team-slave inname enp0s8 master team0
[root@ ~]nmcli con add type team-slave inname enp0s9 master team0
在顯示NIC,會多兩個team-slave:
底下也可以看到系統已經自動幫我們建立了相關的組態:
這些自動產生的組態一開始是使用「dhcp」,但是如果你想要將它改成static ip的話,有兩種方式,你可以自行修改組態檔,只是改完後記得執行「nmcli con reload」更新一下,又或者使用底下的nmcli的方式來修改:
[root@ ~]nmcli con mod team0 ipv4.method manual
[root@ ~]nmcli con mod team0 ipv4.addresses 192.168.1.2/24
[root@ ~]nmcli con mod team0 ipv4.gateway 192.168.1.254
啟用team
到這一步我們的設定檔都已經處理好了,接下來就是啟用team,首先必須將裡面的兩個team-slave啟動:
[root@ ~]nmcli connection up team-slave-enp0s8
[root@ ~]nmcli connection up team-slave-enp0s8
然後你的「nm-team」就會自動啟動了,根據這篇文章,如果你只是單純的啟動「nm-team」,這樣是不會有用的,一定要啟動底下所有的slave才行。
修改team
像這樣把複數個NIC綁在一起,那網路流量是怎麼送的呢?像是下圖所顯示,預設team會使用robin runner:
而這個runner是可以改變的,底下是四個演算法:
- roundrobin : 這個演算法會輪流依序的將網路封包送給各個NIC。
- broadcase : 將所有的封包同時送到每個介面。
- activebackup : 啟用一個介面,然後將其中另一個介面設定為backup,使用中的介面將會被監視,如果它出問題的話就會自動的切換到另一個備用的介面。
- loadbalance : 這個選項會根據你所有可取得的NIC Tx流量去平均分配。
在建立team時,你就可以指定以上四種的runner :
[root@ ~] nmcli con add type team con-name team0 config '{ "runner": {"name": "broadcast"}}'
如果你已經建立起你的team了,也可以藉由修改組態檔來達成這個目的:
[root@ ~] vim /etc/sysconfig/network-scripts/ifcfg-team0
加入底下這一行
TEAM_CONFIG='{"runner": {"name": "activebackup"}, "link_watch": {"name": "ethtool"}}'
重啟介面
[root@ ~] systemctl restart network
檢查runner
[root@ ~] teamdctl nm-team state
進階文件
如果想要知道進階的資訊的話,可以看一下:
man 5 nmcli-examples #尋找關鍵字 "team"
也可以藉由底下指令來看一下debugging的資訊
teamnl nm-team options
其他設定teaming的方式
對於許多人來說,要設定teaming,要那麼多指令,還有很多細節,這是很麻煩的,所以現在有兩套GUI的工具可以來設定,有興趣的人請自行參閱:
Ref:
No comments:
Post a Comment