Service Mesh Webinar 是由 ServiceMesher 社區和 CNCF 聯合發起的線上直播活動,活動將不按期舉行,爲你們帶來 Service Mesh 領域的知識和實踐分享。
本文根據5月28日晚 Service Mesh Webinar#1 多點生活平臺架構組研發工程師陳鵬,線上主題分享《多點生活在 Service Mesh 上的實踐 -- Istio + Mosn 在 Dubbo 場景下的探索之路》整理,文末包含本次分享的視頻回顧連接以及 PPT 下載地址。html
隨着多點生活的業務發展,傳統微服務架構的面臨升級困難的問題。在雲原生的環境下,Service Mesh 能給咱們帶來什麼好處。如何使用社區解決方案兼容現有業務場景,落地成符合本身的 Service Mesh 成爲一個難點。git
今天主要給你們分享一下 Service Mesh 的一些技術點以及多點生活在 Service Mesh 落地過程當中適配 Dubbo 的一些探索。github
首先咱們從三個方面入手:web
說到爲何須要改造,應該先說一下 Service Mesh 和傳統微服務架構的一些特色。json
微服務通常有這些模塊:數組
這些模塊在傳統的微服務架構中有的是和 SDK 結合在一塊兒,有的是一個獨立的中間件。安全
特色:網絡
正是因爲技術多樣性,個人微服務系統可使用不一樣的語言進行開發,好比我一個商城系統,訂單系統使用 Java 開發,庫存系統使用 Go 開發,支付系統使用 Python 開發,微服務之間經過輕量級通訊機制協做,好比:HTTP/GRPC 等。好比目前多點使用的 Dubbo(服務治理框架),隨着多點生活的業務發展,目前遇到最棘手的問題就是中間件在升級過程當中,推動很慢,須要業務方進行配合,接下來咱們看看 Service Mesh。架構
優勢:負載均衡
缺點:
看了 Service Mesh 的優缺點,若是咱們 Mesh 化了以後就能夠解決咱們目前的痛點,升級中間件只須要從新發布一下 Sidecar 就行了,不一樣語言開發的微服務系統能夠採用一樣的服務治理邏輯,業務方就能夠嘗試更多的技術。
在談 Dubbo 場景下的改造以前咱們先介紹一下 Istio 相關的技術點,而後結合 Dubbo 場景應該如何進行適配
MCP(Mesh Configuration Protocol)提供了一套用於訂閱(Watch)、推送(Push)的 API,分爲 Source 和 Sink 兩個角色。
MCP 的訂閱、推送流程圖:
爲了和實際狀況結合,咱們就以 MCPServer 做爲 Source,Pilot 做爲 Sink 來介紹訂閱、推送流程,其中 MCP 通訊過程當中所傳輸的「資源」就是 Istio 定義的 CRD 資源,如:VirtualService、DestinationRules 等。
configSources
的一個數組配置(Istio 1.5 以後沒有這個配置,須要本身添加)、存放的是 MCP Server 的地址;這樣的訂閱、推送流程就保證了 MCPServer 和 Pilot 資源的一致。MCPServer 只能經過 MCP 協議告訴 Pilot 資源發生變化了麼?固然不是,MCPServer 可使用建立 CR 的方式,Pilot 經過 Kubernetes 的 Informer 機制也能感知到資源發生變化了,只是經過 MCP 傳輸的資源在 Kubernetes 裏面看不到,只是存在於 Pilot 的內存裏面,固然也能夠經過 Pilot 提供的 HTTP debug 接口(istiod_ip:8080/debug/configz)來查。
https://github.com/champly/mcpserver 提供了一個 MCPServer 的一個 demo,若是須要更加細緻的瞭解 MCP 原理能夠看一看。
更多 debug 接口能夠查看: https://github.com/istio/istio/blob/5b926ddd5f0411aa50fa25c0a6f54178b758cec5/pilot/pkg/proxy/envoy/v2/debug.go#L103
Pilot 負責網格中的流量管理以及控制面和數據面以前的配置下發,在 Istio 1.5 以後合併了 Galley、Citadel、Sidecar-Inject 和 Pilot 成爲 Istiod。咱們這裏說的是以前 Pilot 的功能,源碼裏面 pilot-discovery 的內容。
Sidecar 經過動態獲取服務信息、對服務的發現 API 被稱爲 xDS。
Pilot 資源類型發生變化須要下發的 xDS 資源對照:
資源名稱 | CDS | EDS | LDS | RDS |
---|---|---|---|---|
Virtualservices | ✔ | ✔ | ||
Gateways | ||||
Serviceentries | ✔ | ✔ | ✔ | ✔ |
Destinationrules | ✔ | ✔ | ✔ | |
Envoyfilters | ✔ | ✔ | ✔ | ✔ |
Sidecars | ✔ | ✔ | ✔ | ✔ |
ConfigClientQuotaspecs | ✔ | ✔ | ||
ConfigClientQuotaspecbindings | ✔ | ✔ | ||
Authorizationpolicies | ✔ | |||
Requestauthentications | ✔ | |||
Peerauthentications | ✔ | ✔ | ✔ | |
Other | ✔ | ✔ | ✔ | ✔ |
以上內容是根據 源碼 整理的
MOSN 是一款使用 Go 語言開發的網絡代理軟件,做爲雲原生的網絡數據平面,旨在爲服務提供多協議、模塊化、智能化、安全的代理能力。MOSN 是 Modular Open Smart Network 的簡稱。MOSN 能夠與任何支持 xDS API 的 Service Mesh 集成,亦能夠做爲獨立的4、七層負載均衡,API Gateway,雲原生 Ingress 等使用。
MOSN:https://github.com/mosn/mosn
配置文件:
其中 address
就是 MOSN 監聽的地址。
filter_chains 在 MOSN 裏面的 network chains
,實現的還有:
和 network chains
同級的還有 listener chains
、stream chains
, 其中listener chains
目前只有 original_dst
實現。stream chains
能夠對請求中的
進行 BeforeRoute
AfterRoute
這些關鍵步驟進行修改請求信息。
全部的 filter
都只有兩種返回結果:
filter
那就執行後續 filter
;filter
就再也不繼續執行了;看圖中的配置信息 config
的內容, downstream_protocol
和 upstream_protocol
這裏若是配置不一致,就須要協議轉換。好比 HTTP1
轉換爲 HTTP2
,MOSN 就會先把 HTTP1
轉換爲 common
的中間協議,而後再把 common
轉換爲 HTTP2
,這樣就實現了協議之間的轉換。若是須要本身實現其餘協議轉換,那麼只須要編寫轉換 common
的內容和 common
轉換爲當前協議的內容便可實現協議之間的互轉。
咱們再來看 filters
裏面的 proxy
,這個就是一個會通過路由的代理,配置信息裏面配置了router_config_name
,就是要路由的router
名字。
根據 listener
裏面的 proxy
的配置信息裏面的 router_config_name
會找到一個 router
,如上圖所示。而後就會根據請求裏面的 domains
去匹配 virtual_hosts
, 這裏的 domains
裏面在 HTTP
裏面就會是 host
,當在 Dubbo 協議裏面咱們能夠把 service
(有些地方叫作 interface、target,咱們這裏統一叫 service) 放到 x-mosn-host
這個 MOSN 的 Header
裏面,MOSN 就能夠根據這個去匹配 domains
。
而後匹配到一個 virtual_hosts
以後,就會獲得對應的 routers
,這裏又會根據 match
裏面的匹配規則進行匹配,HTTP
協議裏面能夠根據 path
、queryparam
、header
等信息進行匹配,具體匹配規則經過 VirtualService 下發,若是是 Dubbo 協議,那麼能夠套用 HTTPRoute
規則,而後把 Dubbo 的 attachment
解析出來看成 header
去用,目前 MOSN 沒有解析 attachment
,咱們本身實現了一個。
匹配到了以後會獲得一個 route
,圖中所示只有一個 cluster_name
,若是是有多個 subset
(DestinationRule 定義),那麼就會有 weighted_cluster
,裏面會有 cluster_name
和 weight
構成的對象的數組,例如:
"route":{ "weighted_clusters":[ { "cluster":{ "name":"outbound|20882|green|mosn.io.dubbo.DemoService.workload", "weight":20 } }, { "cluster":{ "name":"outbound|20882|blue|mosn.io.dubbo.DemoService.workload", "weight":80 } } ], "timeout":"0s", "retry_policy":{ "retry_on":true, "retry_timeout":"3s", "num_retries":2 } }
其中 weight
之和必須爲 100(Istio 定義的),必須是非負數的整數。
下面有一些 timeout
、retry_policy
服務策略。
匹配上了以後會獲得一個cluster_name
,而後咱們再看 cluster
在 routers
裏面匹配出來的 cluster_name
做爲 key
在 cluster
裏面會找到這麼一個對象。
其中 lb_type
就是節點的負載均衡策略,目前 MOSN 支持:
hosts
裏面的 address
裏面也能夠配置權重,這個權重必須是大於 0 或小於 129 的整數。能夠經過 Istio 1.6 裏面的 WorkloadEntry
來配置權重。而後根據負載均衡策略拿到 host
以後直接請求到對應的節點。
這就完成了流量的轉發。接下來咱們看看 Dubbo 場景下應該如何改造。
全部的改造方案裏面都是要把 SDK 輕量化,關於服務治理的邏輯下沉到 Sidecar,咱們在探索的過程當中有三種方案。
這個方案是 Istio+Envoy 的方案,是參考的華爲雲的方案: https://support.huaweicloud.com/bestpractice-istio/istio_bestpractice_3005.html
這種方案若是須要解析更多的 Dubbo 內容,能夠經過 WASM 擴展。
這種方案的話就不須要 Istio。
這種方案就是咱們如今採用的方案,包括:
咱們有一個理念就是若是能經過標準的 CRD 最好,若是描述不了的話咱們就經過 EnvoyFilter 進行修改。這裏特別說一下,咱們一開始也有一個誤區就是 EnvoyFilter 是做用於 Envoy,其實不是的,是對生成好的 xDS 資源進行 ADD, MERGE 等操做,目前只能夠修改 LDS、RDS、CDS,這個修改也是有必定侷限性的。若是 EnvoyFilter 修改不了某些特定的場景(好比 Istio 1.6 以前的 ServiceEntry 裏面的 Endpoint 不能單獨爲每一個實例指定不一樣的端口),那麼咱們只能修改 pilot-discovery 的代碼,xDS 是不會做任何修改的。按照這個理念,咱們開始探索如何改造。
首先有三個端口須要說明一下:
步驟:
這個只是經過靜態配置實現的,若是 provider 這些信息如何經過 Pilot 下發呢?
MOSN 自己支持 xDS API,配置信息能夠經過 xDS 下發,而不是靜態配置。咱們有一個對接配置中心,註冊中心的程序咱們叫 Adapter,這個主要獲取註冊中心的服務信息,而後根據配置中心的服務治理策略(好比流程比例,還有一些咱們內部的一些單元的信息)構建出 Istio 支持的 CR,而後建立 CR,Pilot 本身感知 CR 變化 或者 經過 MCP 把這些信息直接發送給 Pilot,觸發 Pilot 的資源變化,而後 Pilot 根據資源的變化去下發一些 xDS 資源,Sidecar 收到資源變化後,就能夠動態調整路由策略,從而達到服務治理的目的。
最終架構圖如圖所示:
註冊(灰色部分):
配置下發(藍色部分):
服務請求(黃色部分):
以上就完成了服務註冊、發現、治理的全部邏輯。
Istio 1.6 以後能夠經過 WorkloadEntry + ServiceEntry 這兩種 CRD 資源來描述集羣外的服務,當實例上線或者下線的時候就會直接觸發 EDS 增量下發。
首先要說明一下:
具體操做能夠按照 mosn-tutorial,裏面的istio-mosn-adapt-dubbo
。即便你沒有 Kubernetes 環境也能夠嘗試的,後期這個會移植到 MOSN 官網,敬請期待。
mosn-tutorial:https://github.com/mosn/mosn-tutorial
以上就是本期分享的所有內容,感謝你們的收看。
陳鵬,多點生活平臺架構組研發工程師,開源項目與雲原生愛好者。有多年的網上商城、支付系統相關開發經驗,2019年至今從事雲原生和 Service Mesh 相關開發工做。
PPT 下載:https://github.com/servicemesher/meetup-slides/tree/master/2020/05/webinar
視頻回顧:https://www.bilibili.com/video/BV15k4y1r7n8