京東網絡接入體系解密之高性能四層網關DLVS「轉」

DLVS 誕生之初

在 SLB 這塊,京東用戶接入系統提供四層負載均衡服務和應用層負載均衡服務,對於公網流量接入部分,和很多公司一樣採用的是四層和應用層負載相結合的架構,利用四層負載來實現應用層的水平擴展。四層負載在 JFE 1.0 版本中使用開源的 LVS 實現,考慮單機性能的問題,使用了 DR 模式和集群部署方式,並將 LVS 和應用層負載按照服務單元進行部署。這種模式在中等規模的業務場景運行良好,隨著業務的不斷增長,單業務 QPS 超過 200 萬,以及全站 HTTPS 改造要求 SSL 在 SLB 上完成卸載,應用層負載集群規模將不斷擴大,同時受限機房機架資源等因素,需要實現四,應用層負載解耦。為此我們對四層負載進行了重新的設計和自主研發,加入了在線上服務保障過程中的業務訴求,在性能、可用性、運維管理以及安全防護上提升。



業務增長對性能的需求

在過去的 10 年,京東的流量峰值從幾十萬到現在的千萬級 QPS,給流量分發的四層負載均衡服務帶來了巨大的挑戰。Linux 內核實現版本受限於網卡的中斷收包模式以及二三層鎖的開銷,系統經過調優後的轉發能力單臺 QPS 在十萬級別。為了滿足業務流量的陡增,只能是通過增加集群規模和通過多集群的方式進行擴容,隨著集群數量和規模的不斷增加,給服務保障帶來了具大的挑戰,容量管理以及容災方案設計都變得非常的複雜。

服務質量的精細化

由於支撐的業務場景越來越豐富,既有長連接(IM)應用場景又有視頻業務需求,同時業務對服務穩定性的要求越來越高,接入平臺作為基礎設施服務,可用性要求越來越高,要求在不同層面保障服務的穩定性,避免單機故障和機房故障對線上服務的影響。

目前常用的集群方案是採用路由來實現,在京東內部我們使用的 BGP 協議(後面會介紹部署方式),最終要依賴交換機的 ECMP 來實現,ECMP 的缺陷是如果一臺服務器宕機,同一條流的數據包可能就會被轉發到集群其它機器上,如果沒有會話同步,那麼該連接數據包就會丟棄,最終業務層超時。這對於一些長連接在線的業務影響會更加明顯,比如在線的 IM 業務以及推送業務等服務。

運維管理的自動化

隨著業務流量的陡增,集群規模越來越大和多集群的出現,同時對於線上大量應用的業務配置變更,對運維也是很大的挑戰。自動化程度,成為衡量公司技術能力的一項重要指標。

對於接入平臺,承載了公司眾多的業務,實現快速的業務變更同時做到每次變更對業務無損,從平臺角度看這是必須要去解決的問題。

安全防護能力

接入流量作為服務入口,在面對網絡攻擊時,需要具備安全防護的能力,保障平臺服務的穩定性,同時做到對業務透明和精準防護,減少對業務的影響。傳統方案通常採用單獨的檢測和清洗集群來實現,從技術層面看完全可以把異常流量清洗功能移到四層負載上,並以集群的方式部署,節省資源的同時減少旁路部署帶來的複雜網絡拓撲。同時四層負載更加接近業務,更方便用戶根據特定業務定製一些安全規則,真正起到分層防護的能力,保證業務的安全穩定。

方案選擇與功能定義

數據包收發方案選擇

對於高性能的數據包處理方案來說,目前主流方案包括了硬件化方案和軟件化方案。

對於硬件化方案,性能上雖然會優於軟件化方案,但它昂貴的價格、有限的容量、靈活性和擴展性都不太適合處於中間轉發位置的四層負載。而且隨著多核服務器的普及,軟件方案也可以達到網卡限速的性能,從價格、容量和靈活性上都遠高於硬件方案,最終我們放棄了硬件方案。

在眾多的軟件化方案中,pfring 依然輪詢 RX Queue,而不能同時訪問所有的 RX Queue。導致單核佔用率比較高,不能充分利用多核性能。pfring 和 netmap 對於大葉內存和 numa 等也沒有庫來支持,在實際的應用中 (多路處理器和網卡),必然會影響性能。

綜合來看,dpdk 能充分發揮多核處理的的優勢,來提供更好的轉發性能外。同時 dpdk 提供了便於快速開發的庫(內存池、網卡信息獲取、無鎖隊列、hash 等)。最重要的是 dpdk 由 Intel 發起並支撐,加之社區活躍程度高,我們最終選擇了 dpdk 作為數據包收發方案。

功能定義

  • 支持集群部署
  • 支持配置集中管理
  • 支持會話保持
  • 支持 tcp、udp 的四層負載均衡
  • 支持 DR 和 FULLNAT 模式
  • 支持 rr、wrr、源 ip hash 等負載均衡算法
  • 支持主動健康檢查
  • 支持透傳客戶機 IP
  • 支持會話同步
  • 支持 syn flood, ack flood 等四層攻擊防護
  • 支持畸形報文過濾、黑白名單

系統實現

DLVS 核心架構

結合各個功能的實現方式,下圖是四層負載的 DLVS 的核心架構(後續章節會展開講解)。

京東網絡接入體系解密之高性能四層網關DLVS「轉」

DLVS 包括數據平面和控制平面,控制平面主要負責配置、監控和日誌的管理。數據平面主要是基於 dpdk 實現的數據包處理和轉發。控制平面和數據平面的通信主要通過 kni 接口和 unix 域套接字接口。

控制平面的 quagga 用於和交換機建立 BGP 連接,發佈路由和 DLVS 保活監控;keepalived 用於 vip、real server 等業務的配置和 real server 的健康檢查;管理 agent 用於提供對外配置接口和日誌上報接口。

數據平面雖然是單進程,但我們在內部採用了多線程機制,並將管理和業務流量分離,以避免大的業務流量對管理流量產生影響。即把線程分為管理線程和業務線程,它們之間通過隊列進行通信。管理線程負責處理經過內核的報文、進程間通信的報文等,同時將配置下發給各個業務線程,既每個業務線程都擁有一份配置。業務線程有多個線程,包括負載均衡業務的處理、安全防護和會話管理等。

接下來我們從業務角度、性能角度、高可靠性角度和安全防護角度來說明四層負載 DLVS 的具體實現。

負載均衡業務的實現

結合京東商城和京東雲的業務需求,對於四層負載我們支持了 TCP 和 UDP 兩種協議,支持 fullnat 和 dr 兩種模式,並支持了 rr、wrr 和源 ip 哈希選擇 real server 等基本功能,具體的實現我們不再詳細解讀,大家參考 kernel 版 lvs 的實現即可,原理方法基本一致。在這裡我們只結合真實業務場景中遇到的問題來提醒大家在實現過程中特別需要注意的幾點。

rr 算法選取 real server

在實際使用過程中,每臺 DLVS 選取 real server 都是從頭開始輪詢的。在實際應用場景中,我們發現集群新增 DLVS 時,real server 的流量嚴重不平衡,都集中在了配置的比較靠前的幾臺 real server 上。我們通過隨機哈希 real server 的位置,再進行 rr 選取,從而解決了這個問題。wrr 的選取解決方案類似。

業務配置的加載

開源的 lvs 是 kernel 的 module,在 dpdk 上來實現 lvs 的功能會導致原有的 keepalived 和 ipvsadm 無法進行配置和監控的管理。我們利用域套接字實現的接口來替換 keepalived 和 ipvsadm 的消息下發接口,從而實現了 dpdk 版 lvs 與 keepalived 和 ipvsadm 的無縫對接。

業務的接口我們使用統一的庫 DLVS wrapper 來實現,交互流程如下圖所示:

京東網絡接入體系解密之高性能四層網關DLVS「轉」

Client 真實 IP 獲取

由於業務的需要,有些服務需要獲取到 client 的真實 IP 和端口號。開源的 lvs 採用的 toa(將真實源 IP 和端口加在 tcp option 中的方式),需要 real server 安裝相應的內核補丁,這對於在線業務遷移帶來具大的成本。

我們採用 proxy protocol 將 client 的真實 IP 和端口號進行封裝,然後傳遞給後端的應用,由於採用了應用層的方式,應用層支持 proxy protocol 即可,無需要修改內核代碼,並且升級修改對業務無損。

proxy protocol 交互過程和協議格式如下圖所示:

京東網絡接入體系解密之高性能四層網關DLVS「轉」

proxy protocol formatPROXY_STRING + single space + INET_PROTOCOL + single space + CLIENT_IP + single space + PROXY_IP + single space + CLIENT_PORT + single space + PROXY_PORT + "\\r\\n"

Example:PROXY TCP4 198.51.100.22 203.0.113.7 35646 80\\r\\n

在收到客戶端發過來的第一個 ACK 數據包時,插入一個 TCP 數據包,負載是上述 proxy protocol 內容。

高可靠性的實現

管理流量與業務流量分離

如果管理流量和業務流量夾雜在一起,在高業務流量的情況下,對管理流量可能會產生影響,如:bgp 引流出錯、配置的丟失、健康檢查報文的丟失等。所以我們需要將業務流量和管理流量進行分離。我們結合 dpdk 的 fdir 技術和對 rss hash 配置的源碼修改來實現。

由於控制平面基於 Linux 的進程,所以我們使用了 kni 口作為管理數據流接口,首先我們通過 fdir 接口,將 kni 的 IP 地址下發給網卡,並綁定到網卡的 0 號隊列。然後對 dpdk 的 rss hash 進行了修改,保證業務報文(非 kni ip)在 rss hash 隊列時,從 1~N 中選擇。邏輯流程如下圖所示:

京東網絡接入體系解密之高性能四層網關DLVS「轉」

會話同步

為了保障一些服務的長鏈接在部分四層負載服務節點出現異常後,同集群其他節點能夠處理已建立的 TCP 連接,需要對會話進行跨機器存儲,來保證四層負載設備出現異常時,流量被牽引到其他四層負載節點上,數據包能夠繼續正確轉發。

對於京東一個在線業務來說,在線活躍連接在大促期間會非常大,為此,DLVS 會話同步方案設計出發點是需要支持億級用戶在線,並可以根據業務增長在單集群內水平擴展。對於會話保持的實施方案,我們先對現有方案進行了調研,然後結合現有方案的不足進行重新設計。

現有方案:

方案一,每臺四層負載都採用主備的方式。具體邏輯架構如圖所示:

京東網絡接入體系解密之高性能四層網關DLVS「轉」

從邏輯架構圖上,可以明確看到這種方案的優缺點。優點是實現簡單、擴展性好。缺點是正常工作時,一半的服務器閒置,造成資源浪費。

方案二,對四層負載進行分組,組內成員通過組播進行會話同步,邏輯架構如圖所示:

京東網絡接入體系解密之高性能四層網關DLVS「轉」

與方案一相比,該方案可以充分利用四層負載服務器,不會造成資源的浪費。但是,它的缺點也很明顯,由於四層負載集群被分組。分組內的四層負載通過組播的方式相互同步會話。這就會導致組的大小受限於單臺四層負載的容量和帶寬,集群組無法靈活地擴展。

DLVS 會話同步方案:

為了儘量減少資源浪費的問題,我們對四層負載進行了分類,master DLVS 和 backup DLVS。master DLVS 用於承載正常業務流量,backup DLVS 用於承載出現異常的 master DLVS 的流量。考慮到業務整體突發異常性的概率, backup DLVS 數量遠小於 master DLVS 的數量,而且對 backup DLVS 的容量和帶寬進行了擴容。

為了解決橫向擴展的問題,我們首先採取了外部 cache 存儲全局會話,其次將分組對業務(vip)透明,通過虛擬的分組來進行 cache 和 backup DLVS 的劃分,從而使得橫向擴展不會受限於單臺四層負載的容量和帶寬。使得四層負載在支持會話同步的情況下,實現對億級在線用戶流量的負載服務穩定。

結合解決資源浪費和擴展性的問題,給出整體的系統架構圖:

京東網絡接入體系解密之高性能四層網關DLVS「轉」

為了更加方便大家瞭解會話同步相關的數據流程,我們結合幾個場景講解數據流的走向。

1. 分組對業務透明

通過將 backup DLVS 和 cache 進行分組,實現了業務 master DLVS 的分組的透明。使得 DLVS 的集群可以橫向擴展,用於支撐億級在線用戶業務。

京東網絡接入體系解密之高性能四層網關DLVS「轉」

2. 正常 DLVS 的數據流

京東網絡接入體系解密之高性能四層網關DLVS「轉」

3. 宕機 DLVS 的數據流

京東網絡接入體系解密之高性能四層網關DLVS「轉」

4. 重啟 DLVS 的數據流

重啟過程中的數據流和宕機的數據流基本一致,參考宕機數據流。

重啟後的數據流,首先恢復的 master DLVS 依據 device id 與 cache 進行會話批量同步,同步完後發送恢復通告給 backup DLVS,然後 master DLVS 進行業務流量的轉發。

京東網絡接入體系解密之高性能四層網關DLVS「轉」

5. 新增 DLVS 的數據流

新增 master DLVS 時,首先根據 device id 與 cache 進行會話同步,然後發送設備新增通告,最後轉發業務流量。由於一致性 hash 的原因,會有一部分原有會話流量發送到新增 DLVS 上,DLVS 將流量轉發給 backup DLVS,backup 進行會話查詢,根據 device id 進行二層轉發給原 DLVS,保證會話的一致性。

京東網絡接入體系解密之高性能四層網關DLVS「轉」

安全防護的實現

作為流量的入口,需要提供基礎的流量防護功能。傳統的方式是在流量出入口部署流量檢測和清洗設備。檢測是被一般是旁路部署,通過引流的方式將異常流量引流到清洗設備進行清洗,然後進行流量回注。採用旁路部署的方式,主要是為了防止因為清洗異常流量的性能消耗(清洗設備對報文進行了深度的分析)而影響到正常流量。但旁路部署同樣帶來了一些問題,比如:清洗設備對報文進行了深度的解析分析(七層報文解析分析),使其自己成為流量的瓶頸;流量的多次轉發造成一定的延遲;未被牽引的流量不能進行安全防護;對實際業務用戶無感知等

四層負載作為流量的入口,由於我們採用的高性能實現方案,大大提升了四層負載的性能,所以我們希望四層負載能夠替代傳統的流量檢測和清洗設備功能。來減少延遲、對全部業務進行四層防護,並結合業務進行定製化防護等。同時不需要在部署流量監測和清洗設備,節省大量的資源。

流量清洗設備防護內容一般包括畸形報文防護、黑白名單支持、dns 防護、四層 ddos 防護、cc 防護等。考慮到報文解析和深度分析帶來的性能消耗,結合四層負載所承載的功能,我們已經將報文解析到了傳輸層(TCP、UDP 等),將 cc 的防護放到了四層負載後端的七層負載上來進行。把畸形報文防護、黑白名單、dns 防護和四層 ddos 防護放到 DLVS 上來實現(這也符合網絡分層防護的思想)。最終流量接入的防護架構如下。

京東網絡接入體系解密之高性能四層網關DLVS「轉」

在通過四七層負載來提供分層防護替換流量檢測和清洗設備後,使得整個流量接入的網絡拓撲變得簡單易操作。

結合具體的實現我們來詳細解讀四層防護在 DLVS 上的實現

一鍵開啟關閉

對於安全防護,我們採取了一鍵開啟或關閉。在安全防護能力比較健全的用戶環境中,可以直接關閉安全防護功能,以便進一步提升四層負載的性能。

同時,我們也支持了基於 vip 的安全防護開關,可以根據特殊的業務,開啟安全防護功能,使得安全防護更加靈活。

多樣性防護

開源 lvs 在安全防護上,只支持了 synproxy(用於對 tcp syn flood 的偽造源 IP 進行校驗)。我們在支持 synproxy 的基礎上,增加了多種防護機制。

畸形報文防護:對於數據報文解析過程中,對非法的報文(IP 分片攻擊、TCP 標誌位攻擊、smurf 攻擊和 land 攻擊等)格式進行過濾。

黑白名單:結合大數據學習分析和威脅情報的信息,直接對五元組報文進行過濾或放行。對於臨時的業務封禁非常便捷。

DNS 防護:對於 DNS 的 flood 攻擊、DNS 緩存投毒攻擊、DNS 異常報文攻擊等的防護。

四層 DDOS 防護:對 udp flood、icmp flood、tcp flags flood 等進行防護。

結合一鍵開關和多樣性防護,我們安全防護內部的數據包流程邏輯如下圖所示:

京東網絡接入體系解密之高性能四層網關DLVS「轉」

增加了安全防護後,必然會對四層負載的性能造成一定的影響,不過我們經過優化處理後,單機的 TCP 新建也達到了 1M、併發達到了 8M+,足以滿足線上業務需求。

常用防護手段

結合業務使用場景的實現。我們對主要的 TCP 攻擊防護、UDP 攻擊防護和 DNS 攻擊防護進行概要的介紹。

  • TCP 防護的常用手段:synproxy、首包丟棄、tcp flags 檢查、sequence 檢查、基於閾值的分析、限速等
  • UDP 防護的常用手段:基於閾值的分析、UDP 報文隨機指針內容統計、負荷指紋學習和識別、限速等。
  • DNS 防護的常用手段:基於閾值的分析、首包丟棄、構造 request 回驗、校驗 query id 和域名等

高性能的實現

dpdk 的使用

底層的框架我們採用的是 Intel 提供的 dpdk 技術。dpdk 的特性 (用戶態驅動、網卡驅動採取 poll mode、支持 burst 收發、支持大頁內存、numa、無鎖隊列、CPU 親和性、內存池等) 我們這裡不再重複,詳情參考官網 www.dpdk.org 。我們採用了 run-to-completion 的方式,主要是考慮到減少線程之間通過隊列傳遞報文造成的性能損耗。dpdk 主要模塊分解 (摘自網絡) 如下圖所示:

京東網絡接入體系解密之高性能四層網關DLVS「轉」

配置無鎖實現

四層負載配置的管理不同於通用網絡設備,由於後端的 real server 可能會經常的變化。所以四層負載下發配置的頻率也會比較高。傳統的實現方式,對於配置的下發,都是要進行加鎖處理的。這勢必會影響其它流量的性能。

為了避免這種影響,我們通過配置 per core 化即 master core 利用 core 間隊列,為每個業務 core 都下發一份配置,各個業務 core 順序執行讀取配置和處理業務,實現了配置下發的無鎖。

京東網絡接入體系解密之高性能四層網關DLVS「轉」

會話無鎖實現

四層負載的新建和併發能力,直接和會話的創建和查找是否加鎖有直接關係。如果一個會話只有一個 core 來處理,即可實現無鎖,但是多核處理器下如何保證上下行流量都能落到同一個 core 呢?

我們再下發配置時,將 local ip 進行了 per core 綁定,即下行流量通過 rss hash 到達某個 core 綁定的隊列時,在選擇 local ip 時,也就只會選擇已經綁定該 core 的 local ip。同時我們利用 fdir 技術,將該 local ip 與該 core 綁定的網卡隊列綁定。這樣便實現了上下行流量都落在同一個業務處理 core。邏輯流程如下所示:

京東網絡接入體系解密之高性能四層網關DLVS「轉」

性能數據

數據基於 X86 服務器並配置 Intel X520 網卡,分別以大小數據包為例,對轉發過程中的 bps、cps 及 cpu 使用率進行了統計。


京東網絡接入體系解密之高性能四層網關DLVS「轉」


線上應用

京東商城 SLB 應用場景

DLVS 是京東商城用戶接入系統一部分,為全站業務提供四層負載均衡服務,目前接入業務除了有短連接服務,還有像 IM,消息推送等長連接業務場景。 DLVS 作為底層服務,承載全站業務流量,除了在實現上要保障高可用,同時在線上部署架構層面,我們要規避依賴的基礎設施故障(比如機房,機架) 層面對服務的影響,為此我們和網絡團隊一起協作,設計了一套全新部署架構,實現了部署在多機房裡的 DLVS 集群互備,依賴京東商城內網傳輸網絡,通過動態路由(IBGP)將流量導入到 DLVS 集群,依賴 BGP 的強大流量調度功能,可以快速地將不同 VIP 的流量在集群間調度,在依賴底層的基礎設施出現故障時,系統自動將流量切換到其它機房備份集群,整個過程對服務幾乎無影響,示意圖如下:

京東網絡接入體系解密之高性能四層網關DLVS「轉」

DLVS 和交換機建立 BGP 連接,集群的機器發佈同樣的路由,不同集群之間通過 BGP 的 community 選項進行區分,通過匹配不同的 community 字段在把路由重分佈時設置不同的 cost,來控制路由。在所有集群的 BGP 失效時,所有流量落到其中一個默認的集群

京東雲 IP 高防應用場景

京東雲高防產品針對網站類業務提供網站高防服務,非網站類業務提供 IP 高防服務。

在高防業務場景中,流量首先到我們的 DLVS,經過清洗模塊完成流量清洗後,通過 FULLNAT 模式將流量導入到用戶源站或者我們的 WAF 集群。在高防 IP 中部署邏輯圖如下:

京東網絡接入體系解密之高性能四層網關DLVS「轉」

總結

基於 Intel dpdk 實現的高性能四層負載 DLVS,無論是京東商城接入體系和京東雲高防產品中作為所有業務流量的入口,在平臺可用性和支撐業務發展都發揮了重要的作用。與開源實現相比,支持會話同步以及層網絡防護等特性,為業務提供了更精細化的服務質量保障,成為同類產品中的佼佼者。現已整合為企業接入系統解決方案的核心部件,對外提供解決方案支持,幫助公司快速建立一套領先的流量接入體系,並可在此基礎上進行二次開發,根據公司業務特點進行定製化,為業務保駕護航。


原文地址:https://www.infoq.cn/article/jingdong-network-framework-gateway-dlvs/


分享到:


相關文章: