UCloud基於OpenvSwitch卸載的高性能25G智能網卡實踐

伴隨着電商等用戶在雙十一、秒殺之類業務高峯期流量的迅猛增加,對虛擬機網絡性能提高的需求日益迫切,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的功耗和成本較高,研發週期長且不能快速地落地,從硬件到軟件都須要投入大量的資源。而其餘基於第三方網卡廠家的軟件定製化方案,對於網卡軟件的穩定性嚴重依賴於第三方廠商, 遇到問題時不能快速的定位排障。阿里雲

咱們的選擇spa

在業界沒有很是完美的實現方案下,咱們開始將目光轉向開源技術,因爲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。

相關文章
相關標籤/搜索