1. 程式人生 > 其它 >第1篇----Istio原理篇

第1篇----Istio原理篇

Istio是什麼

◎ Istio是一個用於服務治理的開放平臺。
◎ Istio是一個Service Mesh形態的用於服務治理的開放平臺。
◎ Istio是一個與Kubernetes緊密結合的適用於雲原生場景的Service Mesh形態的用於服務治理的開放平臺。

這裡的關鍵字“治理”不侷限於“微服務治理”的範疇,任何服務,只要服務間有訪問,如果需要對服務間的訪問進行管理,就可以使用 Istio。根據 Istio 官方的介紹,服務治理涉及連線(Connect)、安全(Secure)、策略執行(Control)和可觀察性(Observe).

◎ 連線:Istio 通過集中配置的流量規則控制服務間的流量和呼叫,實現負載均衡、熔斷、故障注入、重試、重定向等服務治理功能。
◎ 安全:Istio 提供透明的認證機制、通道加密、服務訪問授權等安全能力,可增強服務訪問的安全性。
◎ 策略執行:Istio 通過可動態插拔、可擴充套件的策略實現訪問控制、速率限制、配額管理、服務計費等能力。
◎ 可觀察性:動態獲取服務執行資料和輸出,提供強大的呼叫鏈、監控和呼叫日誌收集輸出的能力。配合視覺化工具,可方便運維人員瞭解服務的執行狀況,發現並解決問題。

通過示例看看Istio能做什麼

簡單起見,這裡以一個天氣預報應用中forecast服務對recommendation服務的訪問為例。

這個示例對兩個服務的業務程式碼沒有任何要求,可以用任何語言開發。在這個示例中,forecast服務是用Node.js開發的,recommendation服務是用Java開發的。在forecast服務的程式碼中通過域名訪問recommendation服務,在兩個服務中都不用包含任何服務訪問管理的邏輯。

我們看看Istio在其中都做了什麼:
◎ 自動通過服務發現獲取recommendation服務例項列表,並根據負載均衡策略選擇一個服務例項;
◎ 對服務雙方啟用雙向認證和通道加密;
◎ 如果某個服務例項連續訪問出錯,則可以將該例項隔離一段時間,以提高訪問質量;
◎ 設定最大連線數、最大請求數、訪問超時等對服務進行保護;

◎ 限流;
◎ 對請求進行重試;
◎ 修改請求中的內容;
◎ 將一定特徵的服務重定向;
◎ 灰度釋出;
◎ 自動記錄服務訪問資訊;
◎ 記錄呼叫鏈,進行分散式追蹤;
◎ 根據訪問資料形成完整的應用訪問拓撲;
◎ ……

所有這些功能,都不需要使用者修改程式碼,使用者只需在 Istio 的控制面做些配置即可,並且動態生效。以灰度發現為例,在 Istio 中是通過簡單配置實現灰度釋出的,其核心工作是實現兩個版本同時線上,並通過一定的流量策略將部分流量引到灰度版本上。我們無須修改程式碼,只要簡單寫一個配置就可以對任意一個服務進行灰度釋出了:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: recommendation
spec:
  hosts:
  - recommendation
  http:
  - match:
    - headers:
        cookie:
          exact: "group=dev"
    route:
    - destination:
        name: v2
  - route:
    - destination:
        name: v1

Istio採用了與Kubernetes類似的語法風格,其功能大意:將 group是 dev的流量轉發到 recommendation服務的 v2版本,其他使用者還是訪問 recommendation服務的 v1版本,從而達到從 v1版本中切分少部分流量到灰度版本 v2的效果。對Istio提供的功能都進行類似配置即可,無須修改程式碼,無須額外的元件支援,也無須其他前置和後置操作。

Istio與服務治理

Istio是一個服務治理平臺,治理的是服務間的訪問,只要有訪問就可以治理,不在乎這個服務是不是所謂的微服務,也不要求跑在其上的程式碼是微服務化的。單體應用不滿足微服務的若干哲學,用Istio治理也是完全可以的。

關於微服務

Martin Fowler對微服務的描述是“微服務是以一組小型服務來開發單個應用程式的方法,每個服務都執行在自己的程序中,服務間採用輕量級通訊機制(通常用 HTTP 資源API)。

但是,微服務化也給開發和運維帶來很大的挑戰,因為微服務化僅僅是一種分而治之的方法,業務本身的規模和複雜度並沒有變少,反而變多。

在分散式系統中,網路可靠性、通訊安全、網路時延、網路拓撲變化等都成了我們要關注的內容。另外,微服務機制帶來了大量的工作,比如服務如何請求目標服務,需要引入服務發現和負載均衡等,以及對跨程序的分散式呼叫棧進行分散式呼叫鏈追蹤,等等。總之,簡單的事情突然變得複雜了。

這就需要一些工具集來做一些通用的工作,包括服務註冊、服務發現、負載均衡等。

Istio不只解決了微服務問題

微服務作為一種架構風格,說到底是一套方法論;與之對應的 Istio 等服務網格則是一種完整的實踐,Istio 更是一款設計良好的具有較好整合及可擴充套件能力的可落地的服務治理工具和平臺。

所以,微服務是一套理論,Istio是一種實踐。但是,Istio是用來解決問題的,並不是微服務理論的一種落地,在實際專案中拿著微服務的細節列表來硬套 Istio 的功能,比如要求Istio治理的服務必須實現微服務的服務註冊的一些細節,就明顯不太適當。

從場景來看,Istio管理的物件大部分是微服務化過的,但這不是必需的要求。對於一個或多個大的單體應用,只要存在服務間的訪問要進行治理,Istio也適用。實際上,傳統行業的使用者業務需要在容器化後進行服務治理,Istio是使用者非常喜歡的形態,因為不用因為服務治理而修改程式碼,只需將業務搬到 Istio 上即可,如果需要將業務微服務化,則可以漸進式進行。

從能力來看,Istio對服務的治理不只包含在微服務中強調的負載均衡、熔斷、限流這些一般治理能力,還包含諸多其他能力,例如提供可插拔的服務安全、可擴充套件的控制策略、服務執行可觀察性等更廣泛的治理能力。在 Istio 中提供的是使用者管理運維服務需要的能力,而不是在微服務教科書中定義的能力。

所以,過多地談論Istio和微服務的關係,倒不如多關注Istio和Kubernetes的結合關係。

Istio與服務網格

服務網格的特點:
◎ 基礎設施:服務網格是一種處理服務間通訊的基礎設施層。
◎ 雲原生:服務網格尤其適用於在雲原生場景下幫助應用程式在複雜的服務拓撲間可靠地傳遞請求。
◎ 網路代理:在實際使用中,服務網格一般是通過一組輕量級網路代理來執行治理邏輯的。
◎ 對應用透明:輕量網路代理與應用程式部署在一起,但應用感知不到代理的存在,還是使用原來的方式工作。

當然,正所謂沒有免費的午餐,這種形態在服務的訪問鏈路上多引入的兩跳也是不容迴避的問題。

從forecast服務到recommendation服務的一個訪問必須要經過forecast服務的 Sidecar攔截 Outbound流量執行治理動作;再經過 recommendation服務的 Sidecar攔截Inbound流量,執行治理動作。這就引入兩個問題:

◎ 增加了兩處延遲和可能的故障點;
◎ 多出來的這兩跳對於訪問效能、整體可靠性及整個系統的複雜度都帶來了新的挑戰。

網格提供商提供的方案一般是這樣解決的:通過保證轉發代理的輕量和高效能降低時延影響,尤其是考慮到後端實際使用的應用程式一般比代理更重,疊加代理並不會明顯影響應用的訪問效能;另外,對於這些高效能的代理,只要消耗足夠的資源總能達到期望的效能,特別是雲原生場景下服務的彈性特點使得服務例項的彈性擴充套件變得非常方便,通過擴充套件例項數量總是能得到期望的訪問效能。

Istio是Kubernetes的好幫手

從場景來看,Kubernetes已經提供了非常強大的應用負載的部署、升級、擴容等執行管理能力。Kubernetes 中的 Service 機制也已經可以做服務註冊、服務發現和負載均衡,支援通過服務名訪問到服務例項。

從微服務的工具集觀點來看,Kubernetes本身是支援微服務的架構,在Pod中部署微服務很合適,也已經解決了微服務的互訪互通問題,但對服務間訪問的管理如服務的熔斷、限流、動態路由、呼叫鏈追蹤等都不在Kubernetes的能力範圍內。那麼,如何提供一套從底層的負載部署執行到上層的服務訪問治理端到端的解決方案?目前,最完美的答案就是在Kubernetes上疊加Istio這個好幫手。

Kubernetes的Service基於每個節點的Kube-proxy從Kube-apiserver上獲取Service和Endpoint 的資訊,並將對 Service 的請求經過負載均衡轉發到對應的 Endpoint 上。但Kubernetes只提供了4層負載均衡能力,無法基於應用層的資訊進行負載均衡,更不會提供應用層的流量管理,在服務執行管理上也只提供了基本的探針機制,並不提供服務訪問指標和呼叫鏈追蹤這種應用的服務執行診斷能力。

Istio複用了Kubernetes Service的定義,在實現上進行了更細粒度的控制。Istio的服務發現就是從 Kube-apiserver中獲取 Service和 Endpoint,然後將其轉換成 Istio服務模型的 Service 和 ServiceInstance,但是其資料面元件不再是 Kube-proxy,而是在每個 Pod 裡部署的 Sidecar,也可以將其看作每個服務例項的 Proxy。這樣,Proxy 的粒度就更細了,和服務例項的聯絡也更緊密了,可以做更多更細粒度的服務治理。通過攔截Pod的Inbound流量和Outbound流量,並在Sidecar上解析各種應用層協議,Istio可以提供真正的應用層治理、監控和安全等能力。

Istio和Kubernetes從設計理念、使用體驗、系統架構甚至程式碼風格等小細節來看,關係都非常緊密,甚至有人認為 Istio 就是 Kubernetes團隊開發的 Kubernetes可插拔的增強特性。

Kubernetes是Istio的好基座

Istio最大化地利用了Kubernetes這個基礎設施,與之疊加在一起形成了一個更強大的用於進行服務執行和治理的基礎設施,並提供了更透明的使用者體驗。

1.資料面
資料面Sidecar執行在Kubernetes的Pod裡,作為一個Proxy和業務容器部署在一起。在服務網格的定義中要求應用程式在執行的時候感知不到Sidecar的存在。而基於Kubernetes的一個 Pod 多個容器的優秀設計使得部署運維對使用者透明,使用者甚至感知不到部署 Sidecar的過程。使用者還是用原有的方式建立負載,通過 Istio 的自動注入服務,可以自動給指定的負載注入Proxy。如果在另一種環境下部署和使用Proxy,則不會有這樣的便利。

2.統一服務發現
Istio的服務發現機制非常完美地基於Kubernetes的域名訪問機制構建而成,省去了再搭一個類似 Eureka 的註冊中心的麻煩,更避免了在 Kubernetes 上執行時服務發現數據不一致的問題。儘管 Istio 強調自己的可擴充套件性的重要性在於適配各種不同的平臺,也可以對接其他服務發現機制,但在實際場景下,通過深入分析 Istio 幾個版本的程式碼和設計,便可以發現其重要的能力都是基於Kubernetes進行構建的。

3.基於Kubernetes CRE描述規則
Istio的所有路由規則和控制策略都是通過 Kubernetes CRD實現的,因此各種規則策略對應的資料也被儲存在 Kube-apiserver 中,不需要另外一個單獨的 APIServer 和後端的配置管理。所以,可以說Istio的APIServer就是Kubernetes的APIServer,資料也自然地被存在了對應Kubernetes的etcd中。

Istio非常巧妙地應用了Kubernetes這個好基座,基於Kubernetes的已有能力來構建自身功能。Kubernetes裡已經有的,絕不再自己搞一套,避免了資料不一致和使用者使用體驗的問題。

Istio不僅資料面Envoy跑在Kubernetes的Pod裡,其控制面也執行在Kubernetes叢集中,其控制面元件本身存在的形式也是Kubernetes Deployment和Service,基於Kubernetes擴充套件和構建。

Istio+Kubernetes的方案與將SDK開發的微服務部署在Kubernetes上的方案的比較

總結

Istio、微服務、容器與Kubernetes的關係