天天看點

Istio與Mcp Server伺服器講解與搭建示範

作者:諧雲
Istio與Mcp Server伺服器講解與搭建示範

01

Istio與外部注冊中心

Istio為何需要對接外部注冊中心

Istio 對 Kubernetes 具有較強的依賴性:

1.服務發現就是基于 Kubernetes 實作的,如果要使用 Istio,首先需要遷移到 Kubernetes 上,并使用 Kubernetes 的服務注冊發現機制。

2.對于大量現存的微服務項目來說,這個前提條件并不成立。對于存量的微服務存在一下幾種情況:

  • 第一種情況:微服務項目暫時遷移到 Kubernetes 上;
  • 第二種情況:雖然采用了 Kubernetes 來進行部署和管理,但還是使用了 Consul,Eureka 等其他服務注冊解決方案或者自建的服務注冊中心。

02

Istio服務模型

Istio與Mcp Server伺服器講解與搭建示範

Pilot

管理服務網格内部的服務和流量政策:

Pilot 将服務資訊和路由政策轉換為 xDS 接口的标準資料結構,下發到資料面的 Envoy。但 Pilot 自身并不負責網格中的服務注冊。

Pilot 中管理的服務資料有兩處資料來源:

Service Registry:來源于各個服務系統資料庫,例如 Kubernetes 中的 Service 和 Consul Catalog 中注冊的服務。Istio 通過特定的擴充卡連接配接這些服務系統資料庫,由擴充卡将服務系統資料庫中的私有服務模型轉換為 Istio 内部支援的标準服務模型。

Config Storage:來源于各種配置資料源中的獨立服務,通過 Istio 定義的 ServiceEntry2 和WorkloadEntry資源類型加入到 Pilot 的内部服務模型中。

03

Istio 對接外部注冊中心

Istio與Mcp Server伺服器講解與搭建示範

自定義 Service Registry 擴充卡

這種內建方式的業務流程參見圖中的藍色箭頭。該方案需要編寫自定義的 MCP Server 從第三方系統資料庫中擷取服務和服務執行個體,然後轉換為 ServiceEntry 和 WorkloadEntry 資源,通過 MCP 協定提供給 Pilot 中的 MCP config Controller。

采用這種方式,需要在 istio configmap 中通過 configSources 參數設定自定義 MCP Server 的位址。

修改完成後需重新開機istiod.

自定義 MCP Server

如圖中紅色箭頭所示,我們可以編寫一個自定義的擴充卡來內建第三方服務系統資料庫。該自定義擴充卡從第三方服務系統資料庫中擷取服務和服務執行個體,轉換為 Pilot 内部的标準模型,內建到 Service Controller 中。自定義擴充卡需要實作 serviceregistry.Instance 接口。該方式的原理和 Consul Service Registry 的适配是類似的,可以參照 Consul Service Registry 的适配代碼進行編寫。

實施該方案需要熟悉 Pilot 内部服務模型和 Service Registry 适配相關 Istio 源碼,并且需要将自定義擴充卡代碼和 Pilot 代碼一起編譯生成定制的 Pilotd 二進制執行檔案。該方案的問題是和 Istio 代碼耦合較強,後續 Istio 版本更新時可能需要修改擴充卡代碼并重新編譯。

向 API Server 寫入

該內建方式的業務流程如圖中綠色箭頭所示。我們隻需要編寫一個獨立的服務,該服務從第三方法服務系統資料庫中擷取服務和服務執行個體資料,然後轉換為 Istio 的 ServiceEntry 和 WorkloadEntry 資源,通過 Kubernetes API Server 的接口寫入到 API Server 中。Pilot 中自帶的 Kube Config Controller 會監聽 Kubernetes API Server 中和 Istio 相關的資源對象的變化,并将 ServiceEntry 和 WorkloadEntry 轉換為 Pilot 的内部服務模型。

04

MCP

MCP是基于訂閱的配置分發API。配置消費者(即sink)請求更新來自配置生産者(即source)的資源集合。添加,更新或删除資源時,source會将資源更新推送到sink。如果sink接受,則回複ACK,如果被拒絕則是NACK,例如因為資源無效。一旦對先前的更新進行了ACK/NACK,則source可以推送其他更新。該source一次隻能運作一次未完成的更新(每個集合)。

就消息交換而言,ResourceSource和ResourceSink在語義上是等效的。唯一有意義的差別是誰啟動連接配接并打開grpc流。

istio 1.9 變化

注意:istio 1.9 之後移除了mcp 使用mcp over xds,具體參考設計文檔

Istio 1.9 在對接第三方注冊中心方面,有兩個需要注意的地方:

  • istio 1.8 不再 in-tree 支援 consul 作為外部注冊中心 :加上之前版本移除了對于euraka的支援。截止1.8,所有通過 in-tree 方式支援外部注冊中心的代碼徹底被移除。
  • istio1.9 不再支援MCP的方式對接外部注冊中心,改為 MCP-over-XDS的方式:新的方式雖然叫mcp over xds,但本質上沒有使用之前的mcp協定。這意味着istio 1.9 中不能使用之前社群開源的一些 mcp 實作。

05

MCP-over-XDS 對接第三方注冊中心

編寫 MCP-over-XDS server。然後将該server的位址配置到pilot 的configSource 參數中。pilot 啟動的時候,就會向目的 MCP-over-XDS server 發起訂閱請求,并建立 grpc 連結。MCP-over-XDS server 讀取 注冊中心的資料,并轉換為ServiceEntry,然後 push 給 pilot。pilot接受到資料後,會對比記憶體中的資料,保證資料一緻。

Istio與Mcp Server伺服器講解與搭建示範

其中 MCP-over-XDS server 主要包含兩部分:

  • 一部分是Service watcher,用于監聽服務注冊中心,一旦有服務變更,就需要觸發一次MCP推送,将最新的服務資訊同步給istio。
  • 另一部分是XDS grpc server,用于向istiod推送MCP協定的資料

要對接一個服務注冊中心,隻需實作Registry接口即可

Istio與Mcp Server伺服器講解與搭建示範

接口包含3個方法:

1. AppendServiceChangeHandler:添加“服務更新時需要觸發的回調函數”,也就是說,在發現該注冊中心的服務變更時,需要觸發serviceChanged回調函數

2. Run:運作service watcher,開始監聽注冊中心

3. ServiceEntries:傳回目前注冊中心中的所有服務,以istio ServiceEntry的形式輸出

觸發XDS grpc server推送MCP的時機有2類:

1. istiod啟動時,會向mcp server發送一個初始(initial)請求,擷取目前注冊中心的所有服務服務資訊

2. 注冊中心的服務變更時

在發生上述事件後,grpc server會調用Service watcher的ServiceEntries方法,擷取到最新的服務資訊,并用MCP協定包裝,最終作為XDS協定的payload發送給istiod。

推送的過程存在一個防抖機制(參考istio推送XDS的過程),目的是為了避免頻繁的服務更新導緻多次MCP推送。防抖會将短時間内的多次更新事件合并為一次,減輕推送壓力。

繼續閱讀