Dubbo 3.0 前瞻之對接 Kubernetes 原生服務

Kubernetes 是當前全球最流行的容器服務平臺,在 Kubernetes 集羣中,Dubbo 應用的部署方式每每須要藉助第三方註冊中心實現服務發現。 Dubbo 與 Kubernetes 的調度體系的結合,可讓本來須要管理兩套平臺的運維成本大大減低,並且 Dubbo 適配了 Kubernetes 原生服務也可讓框架自己更加融入雲原生體系。基於 Dubbo 3.0 的全新應用級服務發現模型能夠更容易對齊 Kubernetes 的服務模型。apache

 

1.開篇:Dubbo 雲原生之路編程

2.Dubbo 3 前瞻之應用級服務發現緩存

3.Dubbo 3.0 前瞻之:重塑 Spring Cloud 服務治理安全

4.Dubbo 3.0 前瞻之:經常使用協議對比及 RPC 協議新形態探索網絡

5.2020雙11,Dubbo 3.0 在考拉的超大規模實踐架構

6.Dubbo 3.0 前瞻系列:服務發現支持百萬集羣,帶來可伸縮微服務架構框架

7. Dubbo 3.0 前瞻系列:Dubbo 版 Swagger 來啦!Dubbo-Api-Docs 發佈運維

 

Kubernetes Native Service

 

 

在 Kubernetes 中,Pod 是能夠在 Kubernetes 中建立和管理的、最小的可部署的計算單元。一般一個 Pod 由一個或多個容器組成,應用則部署在容器內。ide

對於一組具備相同功能的 Pod,Kubernetes 經過 Service 的概念定義了這樣一組 Pod 的策略的抽象,也便是 Kubernetes Service。這些被 Kubernetes Service 標記的 Pod 通常都是經過 Label Selector 決定的。函數

在 Kubernetes Service 內,服務節點被稱爲 Endpoint,這些 Endpoint 也就是對應提供服務的應用單元,一般一對一對應了 Pod。

所以,咱們能夠將微服務中的應用自己使用 Service 來進行調度,而微服務間的調用經過 Service 的一系列機制來實現服務發現,進而將微服務整合進 Kubernetes Service 的體系中。

Dubbo 應用級服務發現

在 Dubbo 體系結構內,爲了更好地符合 Java 開發人員的編程習慣,Dubbo 底層以接口粒度做爲註冊對象。可是這個模型對如今主流的 Spring Cloud 註冊模型和 Kubernetes Service 註冊模型有很大的區別。

目前在非 Dubbo 體系外的註冊模型主要是以服務粒度做爲註冊對象,爲了打通 Dubbo 與其餘體系之間的註冊發現壁壘,Dubbo 在 2.7.5 版本之後引入了服務自省的架構,主要經過元數據服務實現從服務粒度到接口粒度的過渡。在 2.7.5 版本之後到 3.0 版本,服務自省模型進行了不少方面的優化,而且在生產環境下進行了驗證。

元數據服務

元數據服務主要是存儲了服務(Instance)與接口(Interface)的映射關係,經過將本來的寫入到註冊中心的接口信息抽象到元數據進行存儲,一方面能夠大大減小注冊中心存儲的數據量、下降服務更新時集羣的網絡通訊壓力,另外一方面,實現了註冊中心層面只存儲應用粒度信息的目標,對齊了其餘註冊模型。

在服務自省模型中,服務提供者不只僅往註冊中心寫入當前實例的信息,還須要往(本地或者遠程的)元數據服務寫入暴露的服務 URL 信息等;而對於服務消費者,在從註冊中心獲取實例信息後,還須要(經過 RPC 請求內建或者中心化配置中心獲取)元數據服務獲取服務提供者的服務 URL 信息等來生成接口粒度體系下的接口信息。

Revision 信息

Revision 信息是元數據服務引入的一種數據緩存機制,對於同一組應用不少狀況下暴露的接口其實都是同樣的,在進行服務(Instance)與接口(Interface)映射的時候會有許多重複的冗餘數據,所以可使用相似對元數據信息進行 MD5 計算的方式來對實例自己加上版本號,若是多個實例的版本號一致能夠認爲它們的元數據信息也一致,那麼只須要隨機選擇一臺來獲取元數據信息便可,能夠實現把通行量從一組實例都須要通訊到只須要與一個實例通訊的壓縮。

如上圖所示,服務消費者註冊中心的工做機制能夠總結爲:

  1. 服務消費者向註冊中心獲取服務實例列表
  2. 註冊中心向服務消費者返回服務實例信息,在實例列表中包括了服務提供者向註冊中心寫入的 Revision 參數
  3. 服務消費者根據獲取到實例信息的 Revision 參數進行分組,分別從每組實例中隨機選擇一臺獲取元數據服務
  4. 服務消費者經過 RPC 發起調用或者經過配置中心獲取獲得指定實例的元數據信息
  5. 服務消費者根據獲取到的元數據信息組建接口粒度的服務信息

關於應用級服務發現更多的信息能夠參考 Dubbo 邁出雲原生重要一步 - 應用級服務發現解析

對接實現方式

本次實現的與 Kubernetes 對接的方式有兩種,一種是經過 Kubernetes API Client 的形式獲取信息,另一種是經過 DNS Client 的形式獲取。

Kubernetes API Client

Kubernetes 控制平面的核心是 API Server,API Server 提供了 HTTP API,以供用戶、集羣中的不一樣部分和集羣外部組件相互通訊。對於 Dubbo 來講,經過使用 Kubernetes API Client 即可以作到與 Kubernetes 控制平面通訊。

Provider 側細節

根據前文說到 Dubbo 應用級服務發現模型,對於 Provider 側在應用啓動、接口更新時須要向註冊中心寫入 Revision 信息,所以大體的邏輯如上圖所示。

Label 標籤做爲 Selector 與 Service 進行匹配,Annotation 中則主要存儲了 Revision 等信息,其中 Revision 信息須要由 Dubbo 應用主動向 Kubernetes API Server 發起更新請求寫入,這也對應了服務註冊的流程。

在目前版本的實現中,Kubernetes Service 的建立工做是交由運維側實現的,也便是 Label Selector 是由運維側去管理的,在 Dubbo 應用啓動前就已經配置完畢了,Service 的名字也便是對應接口註解中的 Services 字段(對於不依賴任何第三方配置中心的須要在接口級別手動配置此字段)。

Consumer 側細節

對於 Consumer 側的邏輯大體上與應用級服務發現的模型設計的同樣,在經過 API 獲取到服務信息後經過獲取對應 Pod 的 Annotation 信息補齊 ServiceInstance  信息,後續邏輯與服務自省一致。

優缺點

  1. 須要指出的是,讓應用自己直接與 Kubernetes 管理平臺的 API 交互自己就存在必定安全隱患,若是配置不當有必定可能性致使拖垮整個 Kubernetes 集羣。
  2. 當應用大量更新時會給 Kubernetes API Server 帶來必定壓力
  3. 本方案直接將 Dubbo 的服務發現過程對接到 Kubernetes 集羣的管理上,能夠在 Kubernetes 環境下進一步簡化管理的複雜度

DNS Client

Kubernetes DNS 是 Kubernetes 提供的一種經過 DNS 查詢的方式獲取 Kubernetes Service 信息的機制,經過普通的 DNS 請求就能夠獲取到服務的節點信息。

全去中心化的元數據服務

因爲 DNS 協議自己限制,目前並無一個統一的較爲簡單的方式向 DNS 附加更多的信息用於寫入 Revision 信息。對於 DNS 的實現方案咱們將元數據服務進行了改造,使其再也不強依賴往註冊中心寫入 Revision 信息,實現只須要知道 Dubbo 應用的 IP 便可以實現正常的服務發現功能。

改造後的元數據服務能夠分爲兩大功能,一個是基於 revision 的獲取 URL 信息等的能力,另一個是獲取對應 revision 的能力。Dubbo 服務消費者在經過註冊中心獲取到實例 IP 後會主動去與每個實例的元數據服務進行鏈接,獲取 revision 信息後,對於 revision 信息一致的實例隨機選擇一個去獲取完整的元數據信息。

因爲 Revision 信息採用了點對點的方式獲取,當這個信息更新時要及時通知給消費者端進行更新。在當前版本的實現中,咱們依賴了 參數回調 機制實現服務者主動推送給消費者。將來會基於 3.0 的全新 Triple 協議,實現流式推送。

Provider 側細節

與 Kubernetes API Client 實現方式相似的,組建服務的過程均須要由運維側進行,在服務提供者啓動的時候會進行元數據信息本地緩存、對外暴露元數據服務接口的機制。

這裏須要特別注意的是,爲了使服務發現過程與業務服務自己解耦,元數據服務接口與業務接口對應的端口能夠不一致,在使用 DNS 實現方案的時候全集羣全部應用的元數據服務端口都須要統一, 經過 metadataServicePort 參數進行配置。這樣亦能夠適配那些不支持經過 SRV 獲取端口的 DNS。

Consumer 側細節

對於 DNS 註冊中心來講,獲取實例的流程主要經過向 DNS 發起 A (或 AAAA)查詢請求來獲取,而 Kubernetes DNS 也提供了 SRV 記錄請求來獲取服務的信息。

結合前文說到的全去中心化的元數據服務機制,Consumer 會去主動鏈接獲取到的每個實例的元數據服務,獲取對應的 Revision 信息,同時以參數回調的形式向提供者提交回調函數用於更新本地信息。

在獲取到 Revision 信息以後,對於具備相同 Revision 信息的實例,Dubbo 會隨機選擇其中一個獲取完整元數據信息,至此完成服務發現的全過程。

優缺點

  1. 本方案與前一種方案對比起來避免了 Kubernetes API 的直接交互,避免了交互的安全問題
  2. 因爲 DNS 沒有像 API Watch 的通知機制,只能採用輪詢的方式判斷服務的變動,在沒有應用變動時集羣內仍有必定量的 DNS 網絡查詢壓力
  3. 本方案設計的時候目標是對任何只要可以經過 A (或 AAAA)查詢獲取到 Dubbo 應用自己的 IP 的 DNS 均可以適配,對 Kubernetes DNS 並非強依賴關係

總結

本次 Dubbo 對接 Kubernetes 原生服務是 Dubbo 往雲原生化發展的一次嘗試,將來咱們將基於 xDS 協議實現與 Service Mesh 控制平面的交互,相關功能正在緊鑼密鼓的籌劃中。同時,在將來 Dubbo 3.0 的發版上,Java 社區和 Dubbo-go 社區將同步發版,本次 Kubernetes 的功能也將對齊上線。

做者信息:

江河清,Github 帳號 AlbumenJ,Apache Dubbo Contributor。在讀本科生,目前主要參與 Dubbo 社區雲原生 Kubernetes 和 Service Mesh 模塊對接。

相關文章
相關標籤/搜索