Service Mesh與Istio簡述

Service Mesh 的演化歷程

一個服務從項目一開始,通常會是一個簡單的單體應用,一個應用提供 了所需的所有服務,所有模塊都包含在這個應用裏面,隨着需求的迭代,這個應用的模塊數量越來越龐大,功能集成也越來越多,模塊與模塊之間在應用內強耦合, 以致於到後期可能改一個小東西就可能會影響整個應用,導致線上事故。

發展到這個階段,一般就要進行服務拆分了,從業務上進行劃分,把完成同 類功能的應用放到一組,通常情況下拆分之後業務與業務之間會有相互調用的需求,原先基於單個應用下的模塊與模塊之間的直接調用現在變成服務與服務之間的 RPC 調用,基於這個前提,在網絡層面就衍生出了幾個當前 OSI 7 層網絡模型無法支持的更高維度的問題。

服務註冊與服務發現

服務之間要實現相互調用,首先必須先找到對方,類似於 DNS 查找,通過名稱查找到具體端點(IP+端口號),所以首先需要一個類似 DNS 的服務,充當註冊中 心,功能上面要求一個服務上面或者銷燬的時候,註冊中心要能夠感知到這個事件,以便在第二步:服務發現的時候能夠準確拿到可用的目的端點,通常的流程如下 所示:

  • 被調方向註冊中心註冊自己的地址

  • 調用方向註冊中心詢問被調方的服務地址列表3. 向被調方發起請求最直接的辦法,就是搞個DNS服務器,用來充當註冊中心,但是DNS通常會有緩存,更新不會實時,而且服務註冊除了“註冊”這個動作,還需要有“銷燬”的動作,否則一個節點掛了,DNS上面還保留着這個節點的信息,調用方發起調用將會失敗,總體上DNS並不能完美勝任這種工作,需要想辦法另外去解決。

負載均衡

上圖可以看到,被調方這個服務下可以有多個實例,分佈在不同的主機上運行,現實中爲了避免單點故障,基本上都會佈置多個實例同時提供服務,這就導致調用方拿到的服務地址不是一條,而是一組列表,而怎麼樣從這組列表中選出一個端點來發起請求呢,這就需要調用方有負載均衡的能力,比如rr輪詢,random隨機訪問。

熔斷限流

微服務的集羣下,每個服務負責不同的功能,一條請求進來可能會穿越多個微服務,而如果在這當中,某些微服務出現性能瓶頸,比如一些處理流程比較慢的服務,當併發請求量上來之後,可能就直接被打掛了,而這個服務恰好是一個關鍵路徑,導致前端所有請求都報錯,這時候就需要有一種保護機制,能夠在適當的時候對某些步驟進行降級操作,比如某個服務達到性能瓶頸之後進行熔斷,不讓請求進來,服務入口直接拒絕訪問,等到這個服務恢復可用的時候再把它加進來。

安全

如果在一個不信任的集羣中,服務與服務之間可能還需要加密通信,這意味着雙方要進行身份認證、密鑰交換,身份認證需要一個權威的安全中心來頒發證書,否則可能會有中間人竊聽,這些主要看業務需要的安全等級。

以上這些問題,統稱服務治理,基本上服務治理經過了三個階段

  • 第一階段,在應用程序中包含治理邏輯


這個階段,應用本身除了業務代碼之外,還加進了治理邏輯部分的代碼,應用本身親自來解決服務發現、負載均衡等等問題,這種方式存在以下問題:

  • 業務代碼與治理邏輯強耦合,意味着開發者在實現業務的同時還必須去關心這些治理的問題,無法開發純粹的業務代碼

  • 存在大量重複的代碼,集羣內的所有服務的業務代碼都得實現這樣一套治理邏輯,維護困難,搞不好一齣bug還得所有服務都得改一遍

  • 第二階段,獨立出治理邏輯SDK

爲了解決耦合的問題,業務嘗試把這些邏輯抽象出來,獨立成一個SDK庫,由業務代碼去調用,對業務來說相當於一個黑盒子,總體上,代碼邏輯上面能夠做到業務與治理分離,但是引入SDK又有了新的問題。

  • 語言強綁定,SDK需要與語言適配,每種語言都得實現一套相同功能的SDK

  • SDK版本不易管理,SDK本身也會有升級迭代的過程,而業務開發通常是惰性的,不要指望業務會主動去升級SDK,這就導致集羣內會有各種各樣版本的SDK,功能不夠統一,對SDK維護者來說不好管理

  • 仍然有代碼級的侵入,雖然說獨立成SDK,但是業務代碼本身還需要跟SDK進行適配,這種情況下,服務治理無法完全對業務透明

  • 第三階段,獨立出治理邏輯進程

從第一階段和第二階段的經驗可以總結出,如果要想讓業務玩得爽,必須儘量把服務治理這塊邏輯不斷地下沉,最好能夠實現對業務完全透明,比如說,業務完全不需要加任何特殊邏輯,直接向某個服務名發起http請求,然後獲得預期的返回這是最好的。

舉 例來說,就像tcp的發展歷程一樣,從最早的時候,tcp/ip還沒被制定出來,機器與機器之間的連接可能就直接通過一條網絡直連(甚至都沒有網線這種東 西,直接就用一條RS232串口線連接),A機器發出的數據流由B機器直接接收,後來,有了更遠距離的通信,網絡問題開始浮現出現,比如說數據可能會延 遲、可能會丟包、包序可能是亂的,更甚者如果兩臺機器性能不一致,一端拼命地發數據,一端來不及收數據等等,這時候就需要某種策略來確定來至少解決以下幾 個問題。

  • 雙方需要有一個應答邏輯來確定對端到底有沒有收到數據

  • 需要有一個超時重啓機制來確認網絡中有沒有發生丟包,不能讓人無限等待下去

  • 需要有一個擁塞控制機制,來確認發送方到達能以多大的速度向對方發數據

  • 需要保證數據包順序

這是不是很像tcp解決的問題?是的,因爲這種機器間通信的需求太普遍了,所以制定了tcp/ip協議,把他變成網絡通信的基礎設施,業務層不再需要親自去 解決這種網絡治理問題,這其實就是一種邏輯層次的下沉,業務不斷往上層發展,基礎設施不斷下沉,向上層屏蔽治理的細節。

那微服務時代的服務治理邏輯有沒有機會下沉成基礎設施,讓應用層不再需要去關心這些東西呢,目前沒有看到OSI 7層模型有繼續升高的想法,那就讓治理邏輯人爲地下沉,盡最大可能地向業務層屏蔽底層細節。

這就是第三階段的發展方向:治理邏輯獨立進程

通過把治理邏輯的代碼獨立出來變成一個進程,負責劫持業務進程的出入流量,並負責實現服務治理邏輯,對業務進程來說,它完全不知道這個治理進程的存在,這個旁路進程就是SideCar,也稱爲proxy代理。

如果我們把集羣內的所有proxy管理起來,服務間通信完全由proxy來負責,並有一個控制中心來負責控制這些proxy,實現一張服務治理的網,這種形式就叫Service Mesh 服務網格。


Service Mesh解決了以下問題:

  • 對業務層完全透明,感知不到網格的存在

  • 網格上的控制中心和應用節點上的proxy共同完成服務治理:服務註冊、服務發現、服務熔斷、負載均衡等功能,甚至能夠實現動態路由分發、監控、調用鏈跟蹤等高級功能

Istio架構

Istio 就是當前Service Mesh形態上比較熱門的實現方案,由Google推出,所以Istio能夠實現跟K8s深度結合,由於師出同門,所以Istio的路線就是能依賴K8s 的功能就儘量複用K8s的,基於K8s的生態去構建一個Service Mesh服務,當然Istio也可以跟基本平臺進行結合,只不過跟K8s是配合得最好的,下面是Istio官網首頁的圖


總結出以下四種功能

流量管理

  • 實現負載均衡,動態路由,同時能夠支持灰度發佈、故障注入等高級的治理能力。

可觀察性

  • 接 管了應用的流量,那就可以實現對流量的監控,基本訪問日誌及流量維度的各種監控是基本功能,另外還支持調用鏈跟蹤,Istio可以給流經prox的請求打 上span跟蹤ID,然後Istio接上一個有跟蹤能力的後端比如zipkin啥的,就可以馬上實現調用鏈跟蹤,不需要業務層介入開發。

策略執行

  • 能夠實現熔斷限流等訪問策略

安全

  • 通信安全

基本上在微服務上面所要解決的關於服務治理的需求,Istio都能夠支持。


在架構上面,Istio跟K8s一樣,分爲兩層,底層控制面,上層數據面。

數據面會在服務創建的時候自動向一個Pod裏面注入Istio的prox容器(使用的是Envoy組件),這個注入過程業務層是無感知的,這個Proxy容器會通過iptables轉發的辦法把出入流量從Pod的業務容器中劫持。

再說控制面,這個是Istio的控制中心,主要由Pilot(控制器),Citadel(負責安全相關的功能)、Galley(負責各種配置)組成,舊版本 中還有一個Mixer組件,主要負責遙測採集,proxy會向Mixer上報各種指標,Mixer來控制策略,由於會有性能瓶頸,這個組件在新版 Istio中已經被廢棄,相關能力下放到數據面的Proxy來完成。


對K8s來說,Istio是以插件的形式對K8s的一種功能補齊,K8s本身只實現了運維部署、基本的服務發現等基礎層,Istio則是在其之上,業務層之下,處於中間的平臺層,實現了以上的服務治理能力。

Istio的服務治理規則


提供了四種邏輯模型

  • Gateway: 作爲一個集羣的入口網關,外部流量通過這個網關來訪問內部服務

  • VitualService: 制定路由規則,比如根據路徑分發,根據Http cookies匹配分發等,可以理解爲Nginx下的server配置,server下你可以有各種location匹配規則

  • DestinationRule: 訪問策略的規則,比如過濾目標節點,設置負載均衡模式等,可以理解爲Nginx下的upstream配置,server.location匹配到規則後就 會向指定的upstream發起請求,而DestinationRule就相當於upstream下的各種控制規則,比如定義後端服務列表,定義最大連接 數等

  • ServiceEntry,這個是集羣內服務請求外部服務的出口網關,當然也可以不用這個東西,直接由Proxy發起連接

以上,基於VitralService+DestinationRule的規則,可以實現各種訪問形式,比如藍綠部署,金絲雀部署,A/B test等。

Istio具備監控能力,後端可以接各種監控系統,比如promethus,實現監控告警,而無需業務層介入。

Istio的服務發現依賴於K8s,Isito會通過list/wath監聽來自KubeAPIServer的事件,所以Istio不需要實現服務註冊。

原文:https://segmentfault.com/a/1190000039688546

推薦

容器中的網絡延遲相較於宿主機到底高多少?

Kubernetes入門培訓(內含PPT)

本文分享自微信公衆號 - 雲原生技術愛好者社區(programmer_java)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章