您好,登錄后才能下訂單哦!
伴隨著電商等用戶在雙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進行了測試。
如下圖,eth3 是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_TCTO
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不支持USEUPSTREAM
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。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。