1. 程式人生 > >UCloud基於OpenvSwitch解除安裝的高效能25G智慧網絡卡實踐

UCloud基於OpenvSwitch解除安裝的高效能25G智慧網絡卡實踐

伴隨著電商等使用者在雙11、秒殺之類業務高峰期流量的迅猛增長,對虛擬機器網路效能提升的需求日益迫切,25G網路逐漸成為一種標配。為了解決傳統純軟體Virtual Switch方案帶來的效能瓶頸,我們在調研了業界主流的智慧網絡卡方案之後,最終決定採用基於OpenvSwitch的開源方案,併成功在公有云落地應用。

相較於傳統方案,新的智慧網絡卡方案在整個switch的轉發上效能為小包24Mpps,單VF的接收效能達15Mpps,網絡卡整體效能提升10倍以上。應用於雲主機後,可將其網路能力提升至少4倍,時延降低3倍,有效解決電商等業務高峰期的穩定性問題。本文將詳細講講新方案從選型到落地過程中遇到的坑及解決之道,希望能給人以借鑑與啟發。

業界主流的智慧網絡卡方案對比

傳統的軟體Virtual Switch的效能瓶頸,在於其從物理網絡卡接收報文後,是按照轉發邏輯傳送給vhost執行緒,vhost再傳遞給虛擬機器的方式執行,如此一來,vhost的處理能力就成為了影響虛擬機器網路效能的關鍵。

於是,在宿主機上通過25G SmartNIC對網路流量進行解除安裝成為業界公認的主流方向。現階段,智慧網絡卡的實現百花齊放,例如:AWS採用基於通用ARM的眾核方案、Azure採用基於FPGA的方案、華為雲採用基於專用網路處理器(NP)的方案、阿里雲採用基於可程式設計ASIC晶片的方案。就目前來看各個方案各有優劣,並沒有特別突出一統天下的方案。

基於通用ARM、MIPS的眾核方案,簡單將原來跑在宿主機上的vSwitch移植到網絡卡上,既可以支援Linux Kernel也可以支援DPDK,從而達到釋放宿主機計算資源的目的。而其他基於FPGA、NP和可程式設計ASIC的方案,大多在網絡卡上維護一個快速轉發路徑(Fast Path),當收到報文後,首先檢查是否在Fast Path已經快取了該類報文的處理規則,如果找到,則直接按照規則執行動作,否則就轉發到Slow Path去處理。而這個Slow Path可以是DPDK,也可以是Linux Kernel。

因此,Fast Path最重要的是看是否支援足夠多的Action,以及自定義Action的可擴充套件性。Slow Path和Fast Path通訊除了各廠商的私有介面外,也有標準的TC Offload介面和DPDK提供的RTE Flows介面。

不過,FPGA的功耗和成本較高,研發週期長且不能快速地落地,從硬體到軟體都需要投入大量的資源。而其他基於第三方網絡卡廠家的軟體定製化方案,對於網絡卡軟體的穩定性嚴重依賴於第三方廠商, 遇到問題時不能快速的定位排障。

我們的選擇

在業界沒有非常完美的實現方案下,我們開始將目光轉向開源技術,由於OpenvSwitch本身支援基於Linux Tc Flower Offload解除安裝介面, 對現有控制管理面影響小,並且能夠快速應用落地開發給使用者使用。因此,我們選擇了基於Tc Flower Offload的OpenvSwitch開源方案。

報文處理可以被看做是通過一系列順序操作將一個報文從接收發送到最終的目的地,最典型處理的是傳送或者丟棄。這一系列操作通常是連續的match然後執行action。Linux kernel TC子系統的Tc Flower可以將報文基於流進行控制轉發,而流通常是基於報文常見域來分類,這些域組成了名叫flow key的match項,flow key包括了報文常見域和可選的隧道資訊,TC actions對報文執行丟棄、修改、傳送等操作。

這個方式類似於OpenvSwitch的分類方式。通過Tc Flower分類器的offload對於flow-based的系統提供強有力的方法來增加吞吐量並減少CPU利用率。

基於OpenvSwitch解除安裝的智慧網絡卡落地實踐

方案選定之後,我們開始在原有架構上進行落地實踐,這個過程並非一帆風順,在具體落地的過程中,我們也遇到了幾個方面的問題:

1. 虛擬機器的遷移

落地之初,首先要進行虛擬機器的遷移。因為各個廠商的SmartNIC都是基於VF passthrough的方案,而VF的不可遷移性為虛擬機器遷移帶來了困難。在業界,Azure主要通過bonding VF和virtio-net device的方案解決這一問題,但是這種方法需要使用者在一定層面上的介入,帶來了虛擬機器映象管理的問題。

通過調研upstream(https://patchwork.ozlabs.org

/cover/920005/)“Enable virtio_net toact as a standby for a passthrough device”方案,我們發現此環境下,使用者不需要手工設定bonding操作或者製作特定的映象,可以完美的解決使用者介入的問題。最終,我們採用了 VF+standby virtio-net的方式進行虛擬機器的遷移。具體遷移過程為:

建立虛擬機器自帶virtio-net網絡卡,隨後在Host上選擇一個VF 作為一個hostdev的網絡卡,設定和virtio-net網絡卡一樣的MAC地址,attach到虛擬機器裡面,這樣虛擬機器就會對virtio-net和VF網絡卡自動形成類似bonding的功能,此時,在Host上對於虛擬機器就有兩個網路Data Plane;

virtio-net backend的tap device在虛擬機器啟動時自動加入到Host的OpenvSwitch bridge上,當虛擬機器網絡卡進行切換的時候datapath也需要進行切換。VF attach到虛擬機器後,在OpenvSwitch bridge上將VF_repr置換掉tap device;

2. VXLAN encap/decap不能offload

接下來需要做SmartNIC端的適配。以Mellanox CX5網絡卡為例,軟體環境包括OpenvSwitch-2.10.0、ukernel-4.14和MLNX_OFED-4.4-1.0.0.0。由於mlx5_coredriver最新版本並不支援Ethernet over GRE tunnel offload,所以我們先通過VXLAN進行了測試。

如下圖,eth2 是PF, mlx_0是VF0的representor,通過以下命令就進行初始化。首先,開啟一個VF裝置,將VF裝置在driver mlx5_core上解綁,設定PF裝置的IP地址,設定PF網絡卡相關switched模式,開啟PF網絡卡encap功能。

OpenvSwitch 配置如下:虛擬機器VF利用representor mlx_0連線到 br0,通過vxlan0 傳送給對端。VXLAN隧道本地地址為172.168.152.75,對端地址為172.168.152.208。

Encap/decap報文都能有效收發,但是並沒有offload到網絡卡上:

首先發現dmesg顯示錯誤:

查詢原因後發現OpenvSwitch在建立vxlan device時,並沒有將vxlan dport資訊註冊進網絡卡。OpenvSwitch通常是通過 vxlan device的netdev_ops->ndo_add_vxlan_port介面完成這一功能,但是在較新的核心比如ukernel-4.14中是通過netdev_ops->ndo_udp_tunnel_add介面完成的。

後來我們給OpenvSwitch 提交patch “datapath: support upstream ndo_udp_tunnel_add in net_device_ops”https://patchwork.ozlabs.org/patch/953417/來解決這一問題。

3. Decap報文不能offload

解決上述問題後,egress方向的encap報文雖然可以有效的offload,但是ingress decap報文卻依然不可以。

case2的vxlan decap列印是在mlx_0 VF上,因此我們推測decap規則可能也下發到了VF port上。由於tc規則設置於vxlan_sys的虛擬device上,因而很可能是在尋找設定的物理網絡卡上出現了問題。

通過程式碼分析,可以看到虛擬device的設定物理網絡卡是通過action device找到的,即mlx_0 VF,而OpenvSwitch下發給mlx_0 VF的tc_flower帶著egress_dev為true的標誌,由此推斷,TC規則是設定在VF對應的PF上。

沿著此推斷,我們查看了mlx5 driver的程式碼backports/0060-BACKPORT-drivers-net-ethernet-mellanox-mlx5-core-en_.patch

發現ukernel-4.14可以支援cls_flower->egress_devflag,但並不支援HAVE_TC_TO_

NETDEV_EGRESS_DEV。因此,我們斷定mlx5_core driver在核心相容性的判斷上出現問題。隨後,我們提交了相應的patch給Mellanox解決此問題。

4. Backend tap device encap報文被丟棄

在做live migration時需要用到backend tap sdevice,OpenvSwitch在傳送報文時將tc規則設定到了tap device上,依靠tc的in_sw方式進行tunnel_key set然後轉發給gre_sys device進行傳送,但是gre_sys device直接將報文丟棄,這讓我們非常詫異。

分析其原因,我們發現,在tc offload的in_sw情況下,報文會繞過 OpenvSwitch的轉發邏輯直接通過gre_sysdevice進行傳送。而我們使用的是OpenvSwitch-2.10.0所帶的核心模組程式碼,核心模組相容性編譯時判斷ukernel-4.14並不支援USE_UPSTREAM_TUNNEL,所以,gre_sys device並不是核心自帶的gre裝置,而是OpenvSwitch自己建立的一種不具備nodo_start_xmit函式的裝置,OpenvSwitch核心態gre tunnel的轉發並不通過gre_sys device真正做傳送。

雖然ukernel-4.14不支援USE_UPSTREAM_

TUNNEL,但對於核心自帶的gre device是能支援通過ip_tunnel_key進行nodo_start_xmit傳送的,因而對於核心自帶的gredevice來說,USE_UPSTREAM_TUNNEL的標誌是有效的。

由此,OpenvSwitch可以通過acinclude.m4檔案去判斷

由於OpenvSwitch判斷這個功能根據gre以及erspan來決定的,但ukernel-4.14對於erspan來說,USE_UPSTREAM_TUNNEL的標誌是無效的。

之後,我們引入上游https://patchwork.ozlabs.org/

cover/848329/ patch系列“ERSPAN version 2(type III) support”,使OpenvSwitch感知核心支援USE_UPSTREAM_TUNNEL來解決gre_sys device drop報文的問題。

5. Ethernet over gre tunnel不能offload

打入Mellanox提供了基於ethernet over gre的patch後,我們又發現ingress的decap方向不能做offload。

這是由於在gre_sys device上並沒有生成tc ingress qdisc,OpenvSwitch 通過vport的get_ifinex獲取device的ifindex設定tc 規則,而gre tunnel type的vport 並沒有enable get_ifindex功能。

我們查找了upstream的OpenvSwitch,並通過patch“netdev-vport: Make gre netdev type to use TC rules”解決這個問題。

此外,egress encap offload的報文也不能被對方接收,通過抓包發現gre header裡面帶了csum field,但是OpenvSwitch上的gre tunnel並沒有設定csum options。

研究程式碼cls_tunne_key的set action裡預設是帶csum field的,必須通過顯示的設定TCA_TUNNEL_KEY_NO_CSUM才會關閉csum filed。而OpenvSwicth-2.10.0沒有做這方面的適配。

我們查找了upstream的OpenvSwitch,並最終通過patch “netdev-tc-offloads: TC csum option is notmatched with tunnel configuration”解決了這一問題。

綜上,我們詳細介紹了UCloud 25G SmartNIC的選型方案,以及在實踐的過程中遇到的各種技術問題及其解決方案,通過對ukernel、OpenvSwitch、mlx5_core driver的功能補全和bugfix,最後將這一開源方案成功落地應用。

效能對比

落地應用後,我們基於OpenvSwitch解除安裝的高效能25G智慧網絡卡方案下,從vSwitch效能、虛擬網絡卡效能等維度進行了系列效能測試。可以看到,

單VF的接收效能可達15Mpps:

整個vSwitch的轉發效能為小包24Mpps:

而一般傳統純軟體環境下,vSwitch的轉發效能為2Mpps,虛擬網絡卡的接收效能僅1.5Mpps左右。相較於原方案,網絡卡整體效能提升了10倍以上。

應用在雲主機時,同樣8核配置的主機,以收向UDP小包(1 Byte)場景為例,新方案的PPS值可達469w,而原值為108w。

後續計劃

目前,該方案已經成功應用於公有云上,將作為網路增強2.0雲主機推出,使雲主機的網路能力提升到目前網路增強1.0版本的4倍以上。後續我們計劃將該方案移植到Bare Metal物理雲主機產品上,讓公有云和物理雲主機在功能和拓撲上一致,並研究有狀態的Firewall/NAT的Offload。