服務網格和Istio初識-續

語言: CN / TW / HK
    • 4、為什麼服務網格選擇Istio
    • 6、微服務和Istio的選擇側重
    • 10、用什麼姿勢接入 Istio

本文是服務網格和Istio初識的續篇內容,主要是漫談(記錄)一些關於服務網格、 Istio 的一些理論及個人認知

為什麼還要寫這類看似枯燥的文章?我始終認為,學習和實踐應用一門新技術之前,應該做好多方調研,全域性認知,當前有什麼痛點能解決而不是有哪些功能能拿來用等等,到最後不至於僅僅是用了起來而已

1、服務治理的三種形態

服務治理的發展經過了以下三種形態的演進

sdk
sidecar

2、服務網格的特點

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

3、網格帶來的損耗

傳統環境下,服務 A 到服務 B 可以直接通過網路( ip 或服務名)直連

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

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

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

因此最終需要決策的是:

是否願意花費額外的少量資源在這些基礎設施上來換取開發、運維的靈活性、業務的非侵入性和擴充套件性等便利?

4、為什麼服務網格選擇Istio

  • 控制面設計

Istio 作為一種全新的設計,在功能、形態、架構和擴充套件性上提供了遠超服務網格的能力範圍。它基於 xDS 協議提供了一套標準的控制面規範,向資料面傳遞服務資訊和治理規則。 Istio 的早期版本使用 Envoy V1 版本的 API ,即 Restful 方式,其新版本使用 Envoy V2 版本的 API ,即 gRPC 協議。標準的控制面 API 解耦了控制面和資料面的繫結。 NginxnginMeshF5 NetworksAspen Mesh 等多種資料面代理支援 Istio 的控制面,甚至有些老牌微服務 SDK 也開始往 Istio 上整合

  • 資料面設計

Istio 的標準資料面 Envoy 是由 Lyft 內部於 2016 年開發的,比 Linkerd 更早。 20169 月, Envoy 開源併發布了 1.0.0 版本; 20179 月, Envoy 加入 CNCF ,成為第 2Service Mesh 專案; 201811 月, EnvoyCNCF 畢業,這標誌著其趨於成熟。從開發語言上看, Envoy 是使用 C++ 開發的,其效能和資源佔用比用 Rust 開發的 Linkerd Proxy 要更好,更能滿足服務網格中對透明代理的輕量高效能要求;從能力上看, Envoy 提供 L3/L4 過濾器、 HTTP L7 過濾器,支援 HTTP/2HTTP L7 路由及 gRPCMongoDBDynamoDB 等協議,有服務發現、健康檢查、高階 LB 、前端代理等能力,具有極好的 可觀察性、動態配置功能;從架構實現上看, Envoy 是一個可高度定製化的程式,通過 Filter 機制提供了 高度擴充套件性,還支援熱重啟,其程式碼基於模組化編碼,易於測試。除了在 Istio 中應用, Envoy 在其他 Service Mesh 框架中也被廣泛應用,漸漸成為 Service Mesh 的資料平面標準

  • 大廠加持

Istio 由谷歌和 IBM 共同推出,從應用場景的分析規劃到本身的定位,從自身架構的設計到與周邊生態的結合,都有著比較嚴密的論證。 Istio 專案在發起時已經確認了將雲原生生態系統中的容器作為核心打包和執行時,將 Kubernetes 作為管理容器的編排系統,需要一個系統管理在容器 平臺上執行的服務之間的互動,包括控制訪問、安全、執行資料收集等,而 Istio 正是為此而生的;另外, Istio 成為架構的預設部分,就像容器和 Kubernetes 已經成為雲原生架構的預設部分一樣

另外一點,很多的公有云廠商在提供 kubernetes 容器服務時也內建了 Istio 功能或者二次開發(包裝)了 Istio ,例如阿里雲的 asm

5、Istio與kubernetes

IstioKubernetes 從設計理念、使用體驗、系統架構甚至程式碼風格等小細節來看,關係都非常緊密。更細粒度的proxy提供更多更細粒度的能力

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

  • 資料面

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

  • 統一服務發現

Istio 的服務發現機制非常完美地基於 Kubernetes 的域名訪問機制構建而成,省去了再搭一個類似 Eureka 的註冊中心的麻煩,更避免了在 Kubernetes 上執行時服務發現數據不一致的問題

儘管 Istio 強調自己的可擴充套件性的重要性在於適配各種不同的平臺,也可以對接其他服務發現機制,但在實際場景下,通過深入分析 Istio 幾個版本的程式碼和設計,便可以發現其重要的能力都是基於 Kubernetes 進行構建的

  • 基於 Kubernetes CRD 描述規則

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

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

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

最後,看看微服務、容器、 KubernetesIstio 四者的關係

6、微服務和Istio的選擇側重

微服務是架構風格、方法論, Istio 是一套完整的實踐

但是,回到我在本文開頭提到的一點觀念, Istio 是用來解決問題的,並不是微服務理論的一種落地,在實際專案中拿著微服務的細節列表來硬套 Istio 的功能,比如要求 Istio 治理的服務必須實現微服務的服務註冊的一些細節,就明顯不太適當

7、Istio的侵入性

從單個應用來看, Sidecar 與應用程序的解耦帶來的應用完全無侵入、開發語言無關等特點解除了開發語言的約束,從而極大降低了應用開發者的開發成本。這種方式也經常被稱為一種應用的基礎設施層,類比 TCP/IP 網路協議棧,應用程式像使用 TCP/IP 一樣使用這個通用代理: TCP/IP 負責將位元組碼可靠地在網路節點間傳遞, Sidecar 則負責將請求可靠地在服務間進行傳遞。 TCP/IP 面向的是底層的資料流, Sidecar 則可以支援多種高階協議( HTTPgRPCHTTPS 等),以及對服務執行時進行高階控制,使服務變得可監控、可管理

從全域性來看,在多個服務間有複雜的互相訪問時才有服務治理的需求。即我們關注的是這些 Sidecar 組成的網格,對網格內的服務間訪問進行管理,應用還是按照本來的方式進行互相訪問,每個應用程式的 Inbound 流量和 Outbound 流量都要經過 Sidecar 代理,並在 Sidecar 上執行治理動作

Sidecar 是網格動作的執行體,全域性的管理規則和網格內的元資料維護通過一個統一的控制面實現,只有資料面的 Sidecar 和控制面有聯絡,應用感知不到 Sidecar ,更不會和控制面有任何聯絡,使用者的業務和控制面徹底解耦

8、Istio用在哪

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

9、Istio做了什麼

以前後端分離的服務為例

前端 服務的程式碼中通過域名訪問 後端 服務,在兩個服務中都不用包含任何服務訪問管理的邏輯。 Istio 在其中都做了什麼(可以做些什麼)

  • 自動通過服務發現獲取服務例項列表,並根據負載均衡策略選擇一個服務例項
  • 對服務雙方啟用雙向認證和通道加密
  • 如果某個服務例項連續訪問出錯,則可以將該例項隔離一段時間,以提高訪問質量
  • 設定最大連線數、最大請求數、訪問超時等對服務進行保護
  • 限流
  • 對請求進行重試
  • 修改請求中的內容
  • 將一定特徵的服務重定向
  • 灰度釋出
  • 自動記錄服務訪問資訊
  • 記錄呼叫鏈,進行分散式追蹤
  • 根據訪問資料形成完整的應用訪問拓撲
  • ……

所有這些功能,都不需要使用者修改程式碼,使用者只需在 Istio 的控制面配置即可,並且動態生效

對業務程式碼完全沒有侵入性

10、用什麼姿勢接入 Istio

雖然 Istio 能解決那麼多的問題,但是引入 Istio 並不是沒有代價的。最大的問題是 Istio 的複雜性,強大的功能也意味著 Istio 的概念和元件非常多,要想理解和掌握 Istio ,併成功在生產環境中部署需要非常詳細的規劃。一般情況下,叢集管理團隊需要對 kubernetes 非常熟悉,瞭解常用的使用模式,然後採用逐步演進的方式把 Istio 的功能分批掌控下來

  • 第一步,自然是在測試環境搭建一套 Istio 的叢集,理解所有的核心概念和元件。瞭解 Istio 提供的介面和資源,知道它們的用處,思考如何應用到自己的場景中,然後是熟悉 Istio 的原始碼,跟進社群的 issues ,瞭解目前還存在的 issuesbug ,思考如何規避或者修復。這一步是基礎,需要積累到 Istio 安裝部署、核心概念、功能和缺陷相關的知識,為後面做好準備

  • 第二步,可以考慮接入 Istio 的觀察性功能,包括 loggingtracingmetrics 資料。應用部署到叢集中,選擇性地(一般是流量比較小,影響範圍不大的應用)為一些應用開啟 Istio 自動注入功能,接管應用的流量,並安裝 prometheuszipkin 等監控元件,收集系統所有的監控資料。這一步可以試探性地瞭解 Istio 對應用的效能影響,同時建立服務的效能測試基準,發現服務的效能瓶頸,幫助快速定位應用可能出現的問題。此時,這些功能可以是對應用開發者透明的,只需要叢集管理員感知,這樣可以減少可能帶來的風險

  • 第三步,為應用配置 timeout 超時引數、自動重試、熔斷和降級等功能,增加服務的容錯性。這樣可以避免某些應用錯誤進行這些配置導致問題的出現,這一步完成後需要通知所有的應用開發者刪除掉在應用程式碼中對應的處理邏輯。這一步需要開發者和叢集管理員同時參與

  • 第四步,和 ingresshelm 、應用上架等相關元件和流程對接,使用 Istio 接管應用的升級釋出流程。讓開發者可以配置應用灰度釋出升級的策略,支援應用的藍綠髮布、金絲雀釋出以及 AB 測試

  • 第五步,接入安全功能。配置應用的 TLS 互信,新增 RBAC 授權,設定應用的流量限制,提升整個叢集的安全性。因為安全的問題配置比較繁瑣,而且優先順序一般會比功能性相關的特性要低,所以這裡放在了最後

當然這個步驟只是一個參考,需要根據自己的情況、人力、時間和節奏來調整,找到適合的方案

11、Istio不是銀彈

Istio 的架構在資料中心和叢集管理中非常常見,每個 agent 分佈在各個節點上(可以是伺服器、虛擬機器、pod、容器)負責接收指令並執行,以及彙報資訊;控制中心負責匯聚整個叢集的資訊,並提供 API 讓使用者對叢集進行管理。 kubernetes 也是類似的架構, SDN(Software Defined Network) 也是如此。相信以後會有更多類似架構的出現,這是因為資料中心要管理的節點越來越多,我們需要把任務執行分佈到各節點( agent 負責的功能),同時也需要對整個叢集進行管理和控制( control plane 的功能),完全去中心化的架構是無法滿足後面這個要求的

Istio 的出現為負責的微服務架構減輕了很多的負擔,開發者不用關心服務呼叫的超時、重試、 rate limit 的實現,服務之間的安全、授權也自動得到了保證;叢集管理員也能夠很方便地釋出應用(AB 測試和灰度釋出),並且能清楚看到整個叢集的執行情況

但是這並不表明有了 Istio 就可以高枕無憂了, Istio 只是把原來分散在應用內部的複雜性統一抽象出來放到了統一的地方,並沒有讓原來的複雜消失不見。因此我們需要維護 Istio 整個叢集,而 Istio 的架構比較複雜,尤其是它一般還需要架在 kubernetes 之上,這兩個系統都比較複雜,而且它們的穩定性和效能會影響到整個叢集。因此再採用 Isito 之前,必須做好清楚的規劃,權衡它帶來的好處是否遠大於額外維護它的花費,需要有相關的人才對整個網路、 kubernetesIstio 都比較瞭解才行