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。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章