服務網格領域的百花齊放,是否存在一個更優解?

語言: CN / TW / HK

作者@lingsamuel,API7.ai 雲原生技術專家,Apache APISIX Committer。

作者@林志煌,API7.ai 技術工程師,Apache APISIX contributor。

服務網格是一種技術架構,它用於管理微服務系統中各個服務之間的通訊,旨在處理微服務間的流量(也稱為東西向流量)。

在雲原生應用中,一個應用的背後可能存在著成百上千個服務,各個服務可能又有著若干個例項,各個例項的狀態也一直在變化。在如此複雜的服務執行環境中,如何保障使用者的可靠訪問以及維持業務的平穩執行成為一個很大的挑戰,服務網格的治理方案便應運而生。

服務網格就像是微服務間的 TCP/IP,負責服務間的網路呼叫、限流限速、監控等。服務網格目前主要應用在 Kubernetes 平臺上,其最經典的一種實現模式是 Sidecar 模式:將一些通用功能抽象到 Sidecar 容器中,並將 Sidecar 容器與服務容器掛載在同一個 Pod 裡。由於 Sidecar 容器與服務容器並行,且各個 Sidecar 間相互通訊,共同構成了網格形式的網路,因此稱之為服務網格。當然,Sidecar 並非唯一的一種服務網格實現模式,除此之外還有 DaemonSet 模式Ambient mesh 模式

為什麼需要服務網格?

在服務網格流行之前,很多微服務架構的服務治理都是通過微服務框架配合控制平臺實現的,這種方式存在以下幾個問題:

  1. 框架與業務耦合,整體複雜度與運維難度很高,且開發者需要對公共庫有一定的瞭解,沒法只專注於業務實現。
  2. 需要維護多種語言版本的框架,增加了維護的成本。
  3. 微服務框架本身的升級成本比較高,在升級時往往需要進行業務重啟等操作。
  4. 線上存在很多版本的框架,會導致複雜的相容性考慮。 面對以上這些問題,原 Twitter 工程師 Willian Morgan 提出了 Service Mesh 的概念,即服務網格。服務網格通過 Sidecar 模式實現在不侵入業務服務的情況下將基礎設施與業務邏輯解耦,實現跨語言統一更新發布及運維。

服務網格將流量管理、可觀測性和安全通訊等功能下沉到基礎元件,因此開發者無需關心通訊層和服務治理的具體實現,與通訊相關的一切工作直接交給服務網格,讓開發者能夠更關注於業務的開發。基於服務網格的這些特點,前面提到的幾個問題都能夠得到有效解決。

服務網格是如何工作的?

服務網格不會為應用的執行時環境加入新功能,任何架構中的應用還是需要相應的規則來指定請求如何從 A 點到達 B 點。但服務網格的不同之處在於,它從各個服務中提取邏輯管理的服務間通訊,並將其抽象為一個基礎架構層。

目前服務網格大多數採用是資料面 + 控制面的架構模式,如下圖所示:

其中控制面用於管理和配置資料面以及在執行時執行策略。單個網格中控制平面的所有例項共享相同的配置資源。主要聚焦於安全、可觀測性、流量管控等策略的處理和下發,同時還能夠收集和集中資料平面的遙測資料,供運維人員使用。

而資料面通常以代理的形式實現,是由一個個的網路代理 Sidecar 組成,Sidecar 與業務應用例項並行,通過攔截業務資料流以管控業務應用的流量。

在前面的介紹中有提到服務網格是將 Sidecar 設計模式在 Kubernetes 進行實現,通過容器化的方式實現了封裝,Sidecar 主張以額外的容器來擴充套件或增強主容器,這個額外的容器被稱為 Sidecar 容器,它與業務容器在同一個 Pod 中。而服務網格即是一個個 Sidecar 代理所構成的網格式網路。

服務網格的實際應用

在微服務架構中,工程師往往會為對外暴露的服務採取加密或訪問限制的措施以保障服務的安全,但卻忽視了叢集內部的流量通訊安全,所以至今仍有很多微服務應用沒有采取服務間通訊的加密措施,叢集內部的流量以明文的形式進行傳輸,非常容易導致內部流量遭到資料竊聽或是中間人攻擊。

而為了防止叢集內部流量遭到攻擊,通常會使用 mTLS 將通訊資料進行加密。mTLS 可以用於確保服務網格中微服務之間的通訊安全。它使用加密安全技術相互認證各個微服務並加密它們之間的流量。

雖然可以直接在微服務中定義通訊安全策略並執行身份驗證和加密,但在每一個微服務中去單獨實現相同的功能效率是很低的。而且增加功能還需要改動業務程式碼,侵入業務邏輯。且即便完成了功能,後期的升級迭代與測試都需要開發者投入額外精力去維護,無法專注於業務功能的開發。

而使用服務網格,我們就可以在不影響原本業務的情況下零感知的為服務提供 mTLS 通訊。因為在服務網格中,服務通訊相關的功能都被轉移至 Sidecar 代理中實現。在整個實現過程中,業務應用都不會受到影響,降低開發者心智負擔。

當然,服務網格除了可以實現類似 mTLS 這類的內部流量安全配置功能,通過調整控制面的配置還能快速的拓展包括流量管控,可觀測性,協議編解碼等更多功能。

更優的服務網格方案?

雖然服務網格解決了很多微服務架構中的痛點,但它也同時有自己的侷限性,在軟體開發中複雜度是不滅的,只是在不同的部分之間做轉移。我們將服務治理抽離為單獨的一層就要面對流量鏈路的增長以及運維難度的提升,且服務網格需要在雲原生的環境中使用,這對於運維的專業能力及工程實踐經驗有了更高的要求。所以說技術只是用於解決問題的工具,服務網格能帶來的價值還是得從應用的從實際情況出發。

作為 Apache 軟體基金會的頂級專案,Apache APISIX 是一個動態、實時、高效能的雲原生 API 閘道器,提供負載均衡、動態上游、灰度釋出、服務熔斷、身份認證、可觀測性等豐富的流量管理功能。在基於 APISIX 的擴充套件道路上,除了 APISIX Ingress 在雲原生領域被各大廠商開始關注外,基於 APISIX 的服務網格方案也在積極迭代中。

基於 APISIX 的服務網格方案——Amesh

AmeshApache APISIX 的服務網格庫。它適配了 xDS 協議,可以從諸如 Istio 的控制平面中接收資料,並生成 APISIX 所需的資料結構,使得 APISIX 能夠在服務網格領域作為資料面發揮作用。

依靠 Amesh,APISIX 可以工作在服務網格模式下,不使用傳統的 etcd 作為資料中心,而是使用 shdict 與 Amesh 庫直接進行資料交換,避免了額外的效能損耗,使得大規模部署成為可能。

通過使用 Amesh,可以在服務網格領域獲得 APISIX 具備的高效能、豐富的流量管理功能、易擴充套件性等多種優勢。

Amesh 通過適配 xDS 協議,可以讓 APISIX 替代 Istio 所使用的 Envoy 元件來接管叢集流量。在實際使用中,APISIX 將作為 Pod 的 Sidecar 接管網格內的所有流量。目前 Amesh 的架構如下圖所示:

通過架構圖可以看到,通過 xDS 協議,Amesh 可以將 Istio 作為控制面,從 Istio 側獲取配置資訊,並將其轉義為 APISIX 所需的配置。

而網格內部的所有流量都將由 APISIX 接管。其中,APISIX 的配置中心被設定為 Amesh,這使得 APISIX 脫離 etcd 的依賴。Amesh 為 APISIX 提供了一種從 xDS 協議中獲取配置資訊的方式。

此外,Amesh 在 v0.2 中提供了額外的可選控制面元件:amesh-controller。Amesh Controller 增加了 Amesh 專用的 CRD,可以為 APISIX 配置一些 Istio 所不支援的額外功能。額外帶有 amesh-controller 的架構如下圖所示:

正如前文所提到的,Amesh Controller 是可選元件。在未安裝時,Amesh 也能正常使用 Istio 的原生能力提供服務。在安裝了 amesh-controller 後,Amesh 能自動檢測到控制面的加入,並動態地從中獲取配置,而無需重啟。

Amesh controller 為 Amesh 提供了 Istio 無法提供的 APISIX 特有功能。例如在安裝 amesh-controller 後,使用者能為服務配置 APISIX 原生具備的海量外掛,使 APISIX 眾多的外掛在服務網格場景下也能開箱即用,而無需使用者進行自定義的開發。

Amesh 發展狀態

目前 Amesh 專案正在積極開發中。在最近釋出的的 v0.2 版本中,Amesh 新增了可選的控制面 amesh-controller 元件,為 Amesh 提供了 APISIX 所支援的強大的外掛系統,大大增強了 Amesh 的可擴充套件性。

擴充套件能力

在使用 Amesh 時,如果是常規的 Istio 部署,使用者則可以通過 Lua 或 Wasm 來對 Envoy 進行功能擴充套件。

與 Envoy 原生能力相比,APISIX 官方即支援外掛擴充套件能力,維護了 80+ 的外掛可供使用者使用,許多功能已經原生整合。但由於在 Istio 中,不能對這些外掛進行配置,無法直接使用這些外掛所提供的能力。

為此,Amesh v2.0 版本新增了一個控制面元件,即前文提到的 amesh-controller。它為使用者提供了配置 APISIX 外掛的能力,使 APISIX 眾多的外掛在服務網格場景下也能開箱即用,而無需使用者進行自定義的開發。

應用示例

在 Amesh v0.2 版本中,可以通過安裝 amesh-controller 並使用提供的 AmeshPluginConfig CRD 來進行 APISIX 的外掛配置。

例如,我們可以為請求的響應新增特定的 header,這裡可以通過配置 APISIX 的 response-rewrite 外掛實現。

假設我們需要新增的 header 為 X-Header,其值為 AddedHeader,我們可以配置如下的 AmeshPluginConfig,此時請求的響應中就會帶上我們所需的 header。

apiVersion: apisix.apache.org/v1alpha1
kind: AmeshPluginConfig
metadata:
  name: ampc-sample
spec:
  plugins:
    - name: response-rewrite
      config: '{"headers": {"X-Header":"AddedHeader"}}'

總結

隨著雲原生的爆炸式發展及服務網格的不斷優化,未來的服務網格可能會完全取代傳統微服務架構,成為各個企業微服務及雲原生改造的首選架構。雖然現在各種方案都還不太完善,但整體都屬於螺旋上升的狀態。當然,基於 APISIX 的服務網格也正朝著大家心目中的理想型服務網格解決方案奮進,也歡迎各位對 APISIX 服務網格方案感興趣的朋友們進行嚐鮮。