網易數帆基於 Envoy 的雲原生閘道器實踐

語言: CN / TW / HK

簡介:Envoy 是由 Lyft 開源的高效能網路代理軟體。相比於 Nginx、HAProxy 等經典代理軟體,Envoy 具備豐富的可觀察性和靈活的可擴充套件性,並且引入了基於 xDS API 的動態配置方案。目前,Envoy 被廣泛應用於新興微服務閘道器與服務網格之中作為核心資料面。而本次分享將從網易數帆實踐出發,介紹網易數帆是如何基於開源 Envoy 構建高效能、易擴充套件、可觀察的雲原生微服務閘道器函谷(Hango)的。

函谷開源地址:github.com/hango-io/hango-gateway

1 雲原生微服務閘道器

微服務閘道器是微服務架構中最為核心和關鍵的元件之一,負責微服務叢集中服務 API 統一暴露和出入口流量管理。舉一個具體的例子,在微服務叢集中可能同時存在上百個微服務,其中有些是內部依賴,有些則需要對外暴露 API,為外部客戶端提供服務。如果讓各個微服務自身負責 API 的暴露,那一個微服務叢集可能會同時有幾十個流量出入口,大大提高流量安全和流量管理的成本,同時對客戶端也非常不友好。所以引入一個集中元件來統一控制 API 暴露,並負責流量的均衡和分發就是一個自然而然的選擇了(事實上,服務暴露還涉及一個網路隔離的問題,不過本文主要介紹的是七層 API 閘道器,網路問題暫且忽略)。

相比於傳統的反向代理,微服務閘道器有了一個職能的增強。傳統的反向代理更加註重基礎的路由轉發和負載均衡,而 API 閘道器除此以外,更多的還要關注流量的治理能力和流量的觀察能力。

在構建函谷閘道器之前,集團內部實際上已經有了一些其他的 API 閘道器方案。比如網易傳媒、嚴選使用的是 Kong,還有一些業務使用基於 Spring Gateway 的技術方案。但是這些 API 閘道器都有一些侷限性,比如它們的容器化支撐能力,再比如它們的效能,又或者它們的治理能力。網易數帆最初的動機就是準備構建一個具備豐富能力、覆蓋多種場景需求併兼具高效能的新 API 閘道器統一和替代網易集團內部的這些技術方案。

 

2 如何做好微服務閘道器?

在對微服務閘道器本身有了基礎的瞭解之後。第二個問題就是,如何才能做好一個微服務閘道器呢?只有先明確目標,確立一個好的微服務閘道器需要解決的問題,才能為後續的技術選型、以及具體實踐方向提供指導。在梳理了集團內已有的各種閘道器解決方案以及各個業務方的需求和場景之後,團隊總結了一下六條微服務閘道器需要具備的關鍵特性(一家之言,僅作參考)。

  • 高效能:作為叢集流量入口,效能是必須保證的。包括吞吐量和延遲,都是衡量一個高效能閘道器的關鍵要素。作為一個通用的解決方案,網易數帆的輕舟微服務閘道器設計之初,就希望儘可能覆蓋未來更多的場景和業務方需求。所以效能自然要求越高越好,要滿足對效能要求最苛刻的那一個業務方的需求。但是,如果各位希望自研微服務閘道器,那所謂高效能,不一定是吞吐量和延遲達到某個固定標準,只要滿足業務方的實際需求就是高效能閘道器,沒有必要過早優化。很多時候,閘道器的開銷只有幾 ms,而業務本身開銷幾十 ms,瓶頸不在閘道器。

  • 可觀察:可觀察性在微服務架構當中非常重要。因為業務不再是單體,為排障監控帶來了新的複雜度,所以需要可觀察性的支援。

    • 自證清白:實踐得來的一個經驗是,一旦叢集內流量產生了一些業務層面的波動,作為入口的微服務閘道器幾乎總是第一個被懷疑的物件。明確的可觀察資料比如說日誌、指標可以有說服力的證明閘道器的清白;

    • 輔助排障:日誌指標也會包含業務的一些特徵情況,可以幫助業務方快速定位出問題所在。

    • 觀察趨勢:最後,作為流量統一入口,閘道器的可觀察性可以讓使用者瞭解到叢集內的流量現狀、趨勢,並且形成長效的監控告警系統,提前發現問題。

  • 豐富的治理能力:目前稍好一點的小區大門一般都會加上人臉解鎖、一杆一車之類的功能。API 閘道器也類似,作為入口的它也被要求做越來越多的與業務邏輯無關的額外治理功能,比如黑白名單、限流、熔斷等等。

  • 可擴充套件性:和治理能力非常相關的一個關鍵特性就是可擴充套件性。業務方的需求是無窮無盡的,甚至會有一些非常定製化的需求,API 閘道器開發團隊也難以覆蓋所有需求,所以可擴充套件性就非常關鍵了。

    • 對閘道器開發團隊:良好的可擴充套件性可以幫助 API 閘道器快速迭代新功能,降低擴充套件新的治理能力的成本和開銷;

    • 對於業務方:降低閘道器開發的門檻,對於具有一定技術能力的團隊,業務可以根據自身需求特點實現最合適的功能擴充套件,可以提高自身的自主能力;

  • 穩定性:閘道器穩定性的保證是一個很巨集大的問題,除了軟體的質量之外,更多的還要依賴流程的控制以及針對性的技術方案,比如灰度釋出、金絲雀釋出之類的。但是總體來說,就是要經歷生產的檢驗,要有大規模的流量驗證。

  • 視覺化:一個友好、易用的視覺化控制檯,可以實現 API 閘道器的路由配置、服務管理、監控審計的視覺化。

    • 簡化操作:通過平臺產品的封裝,簡化閘道器的操作流程和配置過程,隱藏或者減少底層技術的複雜性,降低 API 閘道器的使用門檻;

    • 實現約束:實現約束,通過產品的封裝和合理的提示,降低在使用 API 閘道器的過程中,使用者犯錯的風險,讓使用者以一種更加正確的姿勢使用閘道器;

    • 監控報警視覺化;

3 為什麼偏偏是 Envoy?

在函谷閘道器的基礎資料面的技術選型當中,網易數帆選擇了新興開源網路代理 Envoy。Envoy 是由 Lyft 開源的一款高效能代理軟體,後來被捐贈給了 CNCF 基金會,是 CNCF 基金會畢業的第三個專案。相比於 Nginx、HAProxy 等經典代理軟體,Envoy 具備豐富的可觀察性和靈活的可擴充套件性,並且引入了基於 API 的動態配置方案 xDS。此外,Envoy 還提供了大量的開箱即用的 Filter 以滿足各種場景下流量治理的需求。

首先,選擇 Envoy 可以使得網易數帆團隊統一微服務架構中東西南北資料面技術棧。Envoy 有典型的兩種工作模式。一種作為中心代理,代理叢集的南北向流量,也就是出入口流量,負責流量分發、流量治理之類的工作的。這種模式下,Envoy 一般就是負載均衡裝置或者是 API 閘道器的基礎資料面,比如 Ambassador,Gloo 都是新興的開源的基於 Envoy 的開源閘道器。另一種模式,就是作為業務程序的 Sidecar。當有業務請求訪問業務的時候,流量會被劫持到 Sidecar Envoy 當中,之後再被轉發給業務程序。類似的,當業務需要訪問其他業務的時候,請求流量也會先被攔截到 Sidecar Envoy,再被轉發到目標服務。這樣,就是在 Envoy Sidecar 中實現一些流量的治理和觀察的功能。這個 Sidecar 的模式就設計到全新的一種微服務架構服務網格了。數帆輕舟團隊和 Envoy 的結緣最初是在服務網格專案當中。在服務網格專案中,發現 Envoy 的豐富功能同樣可以適用於閘道器場景,同時,業界也已經有了 Gloo 這樣的開源閘道器在前。所以也就嘗試使用 Istio 和 Envoy 去構建新的輕舟 API 閘道器。而這樣做也可以保證技術棧的統一,使用 Envoy 來對微服務叢集中南北-東西兩向的流量進行全面的接管。

 

其次,Envoy 豐富的流量治理能力。Envoy 本身就提供了比較豐富的流量治理能力,包括全侷限流、本地限流、服務熔斷、超時控制、策略重試、域管理等等。這些社群提供的七層治理能力讓輕舟 API 閘道器一開始就有一個比較高的起點,可以節省大量的工作量。這些功能基本都是開箱即用,本身控制面的技術選型 Istio 也已經實現了對這些能力的封裝。哪怕不做任何的擴充套件,只是簡單的組合 Istio 和 Envoy 或者組合 Envoy 和裸的配置檔案,也可以實現一個最簡易的微型 API 網關了。

第三,Envoy 提供了開箱即用的可觀察性。社群 Envoy 本身提供了豐富的指標、靈活的日誌、全面的分散式跟蹤支援。

  • 日誌:日誌靈活的配置格式、擴充套件、實現自定義過濾規則等,而且支援多種的輸出方案。

  • 指標:指標也非常的全面,即使現在,我也不敢說了解 Envoy 每一項指標的含義。而且 Envoy 的指標也可以在不侵入 Envoy 的前提下,進一步的擴充套件更多的監控指標;

  • 跟蹤:最後是跟蹤系統部分,Envoy 主要是做採集層的工作。支援 ZipKin、SkyWalking、OpenTracing 等多種的分散式跟蹤系統對接。這些特性保證了使用 Envoy 來構建一套全面的監控告警排障系統是一件相對簡單的事情。

第四,Envoy 強大的可擴充套件性。Envoy 本身也提供了非常好的可擴充套件性,利用它的 L4/L7 的過濾器擴充套件機制,可以在各個層級實現 Envoy 功能的增強。實際上,Envoy 中大量的核心功能都是使用 Filter 來實現的,比如 HTTP 的七層治理能力,其實全都是一個叫做 HTTP Connection Manager 的七層擴充套件外掛。針對其他的協議,一樣可以使用類似的方式來擴充套件支援,比如數帆就額外做了對 FTP 還有 Kafka 的支援。

而且 Envoy 還提供了基於 Lua 和基於 WASM 兩種不同的動態增強擴充套件方法,讓使用者可以在不需要重新構建 Envoy 的前提下,實現 Envoy 的功能增強和擴充套件。利用這種機制,作為一個 API 閘道器基礎設施的提供方,可以簡單的為業務方提供自定義擴充套件的能力。不過後面會講到,目前兩種方案還是有一些侷限,所以數帆還提供了額外的增強。

 

第五,xDS/UPDA 提供的標準資料面代理抽象。Envoy 代理軟體還有一個重要的特性就是 xDS。xDS 的全稱就是 x Discovery Service,是一種動態的配置分發方案。其中 x 表示某種資源,一個埠監聽,一個 Upstream Host,一個 Upstream Cluster 都是一種資源,是真實微服務叢集在 Envoy 中的抽象。Envoy 支援三種不同的 xDS 方案或者說載體:gRPC,檔案,和 Restful API。其中 gRPC 是最常用的一種。就是 Envoy 和控制面之間建立起一個 gRPC 連線。控制組件通過 gRPC 講各種資源通過 ProtoBuf 序列化之後推送給 Envoy。Envoy 解析各項資源,然後動態生效。基於檔案的 xDS 在做本地測試的時候,也比較常用。對於一些個人開發者,如果希望簡單的使用 Envoy 構建一個高效能反向代理,基於檔案的 xDS 方案也是不錯的推薦。像是 LDS,Listener Discovery Service 用於動態的開啟埠監聽;CDS 用來發現新的可以通過 Envoy 代理的服務並抽象為名叫 Cluster 的資源。而 EDS 可以在 Cluster 本身不更新的前提下,更新它的示例列表。個人認為 xDS 最重要的就是兩個特徵。一是動態:所有的配置都是動態的發現、更新和生效的。而且這一過程,配置發現和配置更新的過程不需要 Envoy 主動參與。Envoy 通過將這些責任通過訂閱的方式委託給了更合適的做這件事的控制面元件,比如說 Isito,或者 Gloo 裡面的控制面。二是抽象:xDS 使用 proto 作為配置的載體,使用 proto 物件抽象和封裝一組關聯配置。也就是說,xDS 裡面,動態發現的不是離散的配置項,是一個個資源,一個個物件。當通過 LDS 發現了一個新的 Listener,說明 Envoy 就該開啟一個新的埠監聽了。而 Listener 裡面的具體配置項,都只是在描述這個接下來要建立的埠監聽。

最後一個影響團隊決策的就是 Envoy 開源社群。利用 Envoy 的開源社群和生態,數帆輕舟可以更好的從社群借力。Envoy 是第三個 CNCF 畢業專案,相比於 Nginx 社群,Envoy 的社群明顯更加開放,可以讓人更加放心的貢獻和參與。

4 網易數帆實踐與開源

最後一部分是網易數帆的具體實踐,還有開源相關的工作。數帆微服務的整體架構如圖所示。這個圖,我幾次分享都用到它。簡單,清晰明瞭,而且沒有複雜的技術細節。

 

在最下層,Envoy 作為微服務閘道器、微服務網格的基礎資料面統一了南北東西向的流量治理。再往上,是 Istio 作為的閘道器和網格的控制面。Istio 之上是統一的 API Plane 作為 API 暴露層。最上層,就是視覺化的控制檯。同時,APM,Prometheus,ES 等可觀察性相關的支撐系統一起來構建一整套可觀察體系具體來說,網易數帆做了一下幾個方面的工作。

一,更豐富的七層治理能力。網易數帆實現了更加豐富的七層治理能力,包括流量安全相關的:IP 黑白名單,輕舟認證鑑權,流量穩定性相關的:本地限流、路由級熔斷、動靜態降級,效能相關的快取,跨協議訪問相關的 Dubbo 協議轉換、Web Service 協議轉換等等,來覆蓋更多的業務方需求和場景。

二,基於 Lua 的動態可擴充套件性進一步提升。雖然社群已經提供了基於 Lua 和 WASM 的擴充套件方案,但是還是略有不足之處。其中 WASM 的方案目前算不上成熟,而且效能不如預期,同時相對來說擴充套件的開發、編譯、分發還是較重;而 Lua 雖然做到了極致的靈活,但是隻是簡單的 Lua 指令碼執行,甚至沒有做到擴充套件邏輯和擴充套件配置相分離,所以有兩個方面的缺陷:不易遷移、難以實現較為複雜的功能。為此,網易數帆設計並實現了一個類似於 OpenResty 的 Lua 擴充套件框架 Rider,彌補了現有 Lua 擴充套件的不足。Rider 框架主要包含三個部分:Envoy C++ Filter 部分,Lua SDK 部分,Lua Filter 部分。

三,可觀察性增強。網易數帆另一個非常重要的工作是對 Envoy 的可觀察進行增強,包括:一些元資料的注入,來增強審計日誌;Skywalking Tracer 的實現,來對接分散式跟蹤系統。

 

四,控制檯與監控審計視覺化。網易數帆實現了一個友好的控制檯,來實現服務管理、路由配置、監控審計等一系列功能的視覺化,提高 API 閘道器的易用性。主要的功能包括兩點,前面也提到過:一是簡化閘道器操作,實現功能的約束;二是聚合監控資料,瞭解叢集的狀態。

 

 

五,擁抱開源。整個函谷閘道器都是構建在開源 Envoy 和開源 Istio 的基礎之上的,在使用開源軟體的過程中,我們也在嘗試對社群做回饋。目前,輕舟團隊已經向 Envoy 社群貢獻了超過 10000 行的新增程式碼。

此外,網易數帆也嘗試建立自己的開源社群。所以先後開源了 Slime(智慧服務網格) 以及函谷閘道器。在開源方面,我們還是一個新手,所以可能還有很多不足之處。但是我們絕對是認真的。所以希望大家多多嘗試,提出 issue。

Slime開源地址:https://github.com/slime-io/slime

5 總結

本文簡要介紹了網易數帆在構建函谷閘道器的過程中,所做的一些思考以及工作,希望能給大家帶來一些幫助。限於篇幅,大部分的工作都只能說個大概。如果有興趣的同學,希望可以參與到函谷的開源社群中來,提出更多的問題、意見亦或者純粹的技術討論。

作者簡介:王佰平,網易數帆資深工程師,函谷(Hango)開源專案核心開發者,負責網易數帆輕舟 Envoy 閘道器與輕舟 Service Mesh 資料面開發、功能增強、效能優化等工作,對 Envoy 資料面開發、增強、落地具有豐富的經驗。