team是個啥玩意?
team實現的功能跟bond相似,team本質上也是一個虛擬的網卡驅動(networkdevicedriver),只不過並沒有真實的物理網卡與之對應,而是由這個虛擬網卡去“管轄”一系列的真實的物理網卡,它的代碼結構和一般網卡驅動的代碼結構非常類似。
team的四種模式
主備模式:activebackup 只有一個網卡處於活躍狀態,當一個宕掉另一個備份網卡馬上切換到活躍狀態。
此算法的優點是可以提供高網絡連接的可用性,但是它的資源利用率較低, 只有一個網卡處於工作狀態,在有 N 個網絡接口的情況下,資源利用率為1/N。
發包處理:從team口轉發的包修改skb->dev字段為活躍dev,然后調用dev_queue_xmit進行發包
收包處理:當netif_receive_skb收到包時,經過一系列處理之后,會調用skb->dev->rx_handler函數指針,team設備創建時注冊為team_handle_frame。 從主網卡收到的包修改skb->dev字段為team口dev,然后返回netif_receive后續流程處理,此時返回值為RX_HANDLER_ANOTHER。 從備網卡收到的包修改skb->dev字段為team口dev,然后返回netif_receive后續流程處理,此時返回值為RX_HANDLER_EXACT。
備注:當skb->dev->rx_handler返回值為RX_HANDLER_ANOTHER時,netif_recive_skb會goto至函數入口進行處理。 當返回值為RX_HANDLER_EXACT時,netif_recive_skb不會將skb交給上層協議處理。
廣播模式:broadcast 所有網卡設備均處於活躍狀態,即在每個接口上傳輸每個數據包,此模式提供了容錯能力,此模式增加了系統開銷。
發包處理:從team口轉發包時,遍歷當前team關聯的接口列表,依次修改skb->dev字段為slave dev,並調用dev_queue_xmit發包。
收包處理:在netif_receive_skb調用skb->dev->rx_handler時,會修改skb->dev字段為team口dev,並返回RX_HANDLER_ANOTHER。
loadbalance負載均衡模式:loadbalance 所有網卡設備均處於活躍狀態,根據port負載情況分配外出流量,同時如果其中某個port異常,另外的port會接管。此模式主要提升吞吐量,以及容錯能力。
發包處理:通過bfp提供的負載均衡算法獲取一個hash索引,調用當前指定的hash算法傳入hash索引獲取相應的port 修改skb->dev字段為port dev,並調用dev_queue_xmit發包。
收包處理:在netif_receive_skb調用skb->dev->rx_handler時,會修改skb->dev字段為team口dev,然后對skb進行判斷 如果是LACPDU,則返回RX_HANDLER_EXACT,否則返回RX_HANDLER_ANOTHER。
隨機平衡策略:random 所有網卡均處於活躍狀態,發包時以生成隨機索引的方式選擇網卡,同時如果某個port異常,則會停用,此模式一定程度提升了吞吐量,以及容錯能力。
發包處理:隨機一個索引值,根據索引值檢查對應port當前是否能發包,如果不能則遍歷port_list,如果找到可用port,則選取當前port為發包接口。 然后修改skb->dev字段為查到到的port dev,並調用dev_queue_xmit發包。
收包處理:在netif_receive_skb調用skb->dev->rx_handler時,會修改skb->dev字段為team口dev,並返回RX_HANDLER_ANOTHER。
輪詢平衡策略:roundrobin 所有網卡均處於活躍狀態,發包時以依次累加的計數器為索引選擇網卡,通過如果某個網卡異常,則會停用,此模式一定程度提升了吞吐量,以及容錯能力。
發包處理:以team->sent_packets為索引,查找slave設備並執行sent_packets++操作,檢查獲取到的port是否能發包,如果不能,則遍歷port_list,找到 可用的port之后,修改skb->dev字段為查到到的port dev,並調用dev_queue_xmit發包。
收包處理:在netif_receive_skb調用skb->dev->rx_handler時,會修改skb->dev字段為team口dev,並返回RX_HANDLER_ANOTHER。
team模塊初始化
1.注冊網絡事件處理函數team_notifier_block
2.注冊netlink用於與用戶態通信
team設備創建
1.用戶態通過netlink通知內核創建team。
2.調用rtnl_newlink函數,此函數會進行net_device及team相關私有數據的申請。
3.在上一步中申請net_device時,會調用team_setup對dev->netdev_ops進行賦值。
4.然后在dev->netdev_ops->ndo_init(在上一步中初始化為team_init)函數中對team相關進行初始化。
添加port過程
1.用戶態通過netlink通知內核添加port,通過team_port_add函數實現主要功能。
2.一系列參數檢查,分配一個用於存放port信息的team_port結構體。
3.對申請的team_port結構指針進行賦值,並修改open網卡設備。
4.維護vlan、組播等相關數據結構。
5.注冊收包處理函數team_handle_frame。
6.port添加至team->port_list。
實例示范
1.創建一個team接口,其中接口名為team0,模式為activebackup
nmcli connection add type team con-name team0 ifname team0 config '{"runner":{"name":"loadbalance"}}'
2.給team0設置ip地址
nmcli connection modify team0 ipv4.method manual ipv4.addresses 172.16.254.79/24
3.添加port
nmcli connection add con-name team0-ens224 type team-slave ifname ens224 master team0
nmcli connection add con-name team0-ens256 type team-slave ifname ens256 master team0
4.啟用網絡
啟用team: nmcli connection up team0
啟用port: nmcli connection up ens224; nmcli connection up ens256
5.顯示team狀態
setup:
runner: activebackup
ports:
ens224
link watches:
link summary: up
instance[link_watch_0]:
name: ethtool
link: up
down count: 0
ens256
link watches:
link summary: up
instance[link_watch_0]:
name: ethtool
link: up
down count: 0
runner:
active port: ens224
6.測試
1.在局域網內的另一台機器ping172.16.254.79 測試結果:能ping通
2.執行ifconfig ens224 down 測試ping結果:能ping通
3.此時查看team0狀態 teamdctl team0 stat; 發現active port變成了ens256
4.執行ifconfig ens256 down 測試ping結果:ping不通
5.此時查看team0狀態teamdctl team0 stat; 發現active port為空
6.執行ifconfig ens224 up 測試ping結果:又能ping通了,且active port為ens224
7.刪除網絡組
斷開連接:nmcli connection down team0
刪除team port:nmcli connection delete team0-ens224;nmcli connection delete team0-ens256
刪除team:nmcli connection delete team0