1,Istio 概述
🚩聊聊微服務設計
似乎用上 Kubernetes ,就是微服務系統了。
碰到很多人或公司盲目崇拜 Kubernetes ,一直喊着要上 Kubernetes,但是本身既沒有技術儲備,也沒有規劃方案。想着上了 Kubernetes 之後,就會變成分佈式、高性能、高逼格的微服務系統。
從經驗來看,很多公司用上 Kubernetes 之後,並不會顯著改善舊系統的缺點,而由於項目中充斥着大量泥球般混亂的代碼、隨意使用數據庫事務、幾百行代碼的函數、過度引用其它項目的接口等,無論在 Kubernetes 上放置多少個應用實例,速度總是提示不起來。
其實這種情況是挺常見的,例如你公司的項目,跟我公司的項目。
在筆者經歷當中,碰到過很多中小公司開始從單體系統轉型爲使用 Kubernetes 設施的系統,然而大多數對 Kubernetes 的使用侷限於表面,下面來聊聊幾種常見的情況。
🥇只使用 Kubernetes 部署容器,
只使用 Kubernetes 部署容器,其它方面幾乎沒有變化。
此類系統加入了 Jenkins 構建 CICD 容器,構建後部署到 Kubernetes 中,但是未考慮容錯處理、內外部系統通訊、沒有使用可觀察性系統(監控、日誌、鏈路追蹤),也沒有服務發現和負載均衡。整套系統僅僅是拆分成了多個服務部署,服務之間的通訊使用固定地址寫死配置文件,或者應用修改配置很麻煩。
此類系統唯一亮點是使用了 Kubernetes,可能還用上了 Redis、Mongodb 之類的數據存儲系統。
可是,由於缺少合理的架構設計,系統雖然拆分出來了,其帶來的好處只不過是研發小組可以包乾一個項目,方便管理研發工作。
爲了應對子服務通訊需要,只能不斷在用戶中心或其它服務增加一大套 API,以便子服務能夠獲取需要的信息。可是其拆分後帶來的弊端更多,服務拆分造成了數據隔離(一般是同一個數據庫引擎,使用不同的數據庫名稱),每個服務都有自己的數據庫,這個時候,他們還往往忽略了分佈式下的可能會出現的數據一致性問題、分佈式事務問題等。
由於其缺乏足夠的基礎設施支撐,當服務通訊出現錯誤時排查問題也會變得十分困難,該項目組可能需要跟不同的小組協調排查,有可能爲了一個問題修改十多次代碼,不斷重新部署不斷追加日誌,以便查找問題修復 bug。
🥈開始使用一些中間件,完善基礎設施
爲了解決微服務系統中的一些問題,研發團隊引入了一些中間件。
數據同步:爲了解決數據隔離問題,引入了 Canal 此類數據庫同步工具,例如將用戶中心的用戶表同步到下游,子服務可以直接在自己的數據庫 join 數據,聚合信息變得更加容易。爲了更加容易查詢聚合數據,還將 Mysql 數據消費後同步到 ES、Kafka 等系統進行二次處理。
自動化部署與持續集成:微服務的部署實現自動化,以減少人工干預和錯誤。
監控與日誌:集羣中使用了分佈式監控和日誌記錄,以便於跟蹤和診斷問題。【Istio 可以幫到您】
服務發現與負載均衡:使用了 Consul 等服務註冊和發現中間件,解決了服務通訊地址耦合配置的問題,無需人工維護服務地址列表,還帶有健康檢查、負載均衡等功能。【Istio 可以幫到您】
配置管理:使用 Nacos、 Apollo 等配置中心,能夠動態變更服務的配置。
服務劃分不合理:在微服務架構中,將系統拆分成多個獨立的服務是至關重要的,然而服務劃分不合理可能導致服務過度拆分或功能耦合。
數據一致性:由於微服務使用獨立的數據存儲,可能導致數據一致性問題。
高度耦合:服務間過度耦合可能導致修改一個服務會影響到其他服務,降低了系統的可維護性。
難以診斷與監控:由於微服務的分佈式特性,系統出現問題時可能難以診斷和監控。【Istio 可以幫到您】
安全性問題:微服務間的通信可能導致安全性問題,大多數系統沒有考慮到外部通訊鑑權、內部系統通訊鑑權的問題。【Istio 可以幫到您】
此類系統可以解決在服務通訊和服務故障中出現的一些問題,也提供減輕研發人員負擔的中間件。
但是此類系統,可能還有很多問題。筆者下面說說所接觸到的實際例子。
首先是代碼耦合了太多組件。例如爲了支持鏈路追蹤、日誌收集,代碼中引用了很多相關的類庫並且需要進行復雜的配置。
其實這些組件是可以下沉到基礎設施的,這也正是筆者編寫 Istio 教程的原因。
.NET 中的 ABP 框架也許正是被批評的對象之一,因爲 ABP 真的太 “重” 了,想想 ABP 這麼多的組件,每個模塊都需要添加代碼配置使用,項目光是配置這些模塊、擴展服務就得寫多少代碼,學習成本得有多高。
想想,項目這麼多模塊和配置,能記得多少,每次新建一個項目都要從別的項目那裏複製一堆配置和代碼過去,累不。
此外,微服務之間通過網絡通信,沒有好的故障處理方案,也是一個常見的情況。微服務通訊可能會出現網絡延遲和故障,需要採取設施使用超時、重試、熔斷等容錯策略來降低網絡問題的影響。
實際情況下,大多數研發團隊並不會處理這些問題,一個子服務直接發出 HTTP 請求,如果請求失敗就直接拋出異常,或者使用的方法是在代碼中加入一些組件,當請求失敗時程序自動處理故障,如重試、熔斷等。
例如 C# 可以使用 Polly 組件,配置對 HTTP 請求的超時、重試等策略。可是配置是寫死在代碼中的,如果需要變化就需要修改代碼,而且研發人員不一定能夠預先配置好足有優秀的參數。多加一個組件,程序的 “重量” 增加一分,維護難度也會加大。
所以說,要設計一套微服務系統並不容易。
❓我爲什麼要學 Istio
首先是,Istio 能夠將很多配置下沉到基礎設施層面,我們的項目代碼可以減少很多組件、代碼和配置。
熟話說得好,架構設計決定了系統的上限,而實現細節決定了系統的下限。
想想,如果你使用 ABP 來開發業務,當你打開項目代碼時,裏面的配置還記得清楚嗎?每次新建項目,都要從舊項目抄一堆代碼和配置,還需要在各種中間件中增加相當多的配置。筆者看過不少使用 ABP 編寫的項目,裏面的配置實在太多了。況且涉及的依賴包很多,不同的項目模塊更新時也很容易碰到組件版本不一致導致的衝突。
前面說了,微服務通訊時,需要自動故障修復,能夠自動重試、熔斷,並且還需要支持服務的健康檢查以及負載均衡。如果這些都在代碼中配置,每個項目都需要重複勞動一次。
所以,我學習 Istio 主要原因有三點:
- 將代碼中的東西丟到基礎設施中去,減少代碼量和複雜的配置。
- 可以學習到很多微服務設計思想。
- 更加合理地在 Kubernetes 上設計系統架構。
當然,按照公司的體量和業務支撐需求,並不一定用得上 Istio,而本身 Istio 也挺重的,學起來難度不比 Kubernetes 低。
在寫本文之前,跟一個大佬聊天,他說大多數公司用不上 Istio,而用得上的公司會選擇自研。其實用不用得上並不重要,重要的是你可以從學習 Isito 的時候,瞭解很多設計思想,瞭解 Istio 的這些組件解決了什麼樣的問題。之後,除了使用 Isito ,我們也可以使用其它方法來解決這些問題。
💡所以,Istio 是什麼
Istio 是一個與 Kubernetes 緊密結合的服務網格(Service Mesh),用於服務治理。
注意,Istio 是用於服務治理的,主要有流量管理、服務間安全、可觀測性這幾種功能。在微服務系統中,會碰到很多棘手的問題,Istio 只能解決其中一小部分。
服務治理有三種方式,第一種是每個項目中包含單獨的治理邏輯,這樣比較簡單;第二種是將邏輯封裝到 SDK 中,每個項目引用 SDK 即可,不增加或只需要少量配置或代碼即可;第三種是下沉到基礎設施層。Istio 便是第三種方式。
Istio 對業務是非侵入式的,完全不需要改動項目代碼。
Istio 三個主要功能
接下來介紹一下 Istio 的三個主要能力。
⏩流量管理
流量管理包括以下功能:
- 動態服務發現
- 負載均衡
- TLS 終端
- HTTP/2 與 gRPC 代理
- 熔斷器
- 健康檢查
- 基於百分比流量分割的分階段發佈
- 故障注入
- 豐富的指標
⏩可觀測性
Istio 支持 Jaeger、Zipkin、Skywalking 等鏈路追蹤中間件,支持 Prometheus 收集指標數據,然後日誌功能沒有上面亮點,只是記錄了請求的 HTTP 地址之類。Istio 的可觀測性幫助我們瞭解應用程序的性能和行爲,使得故障檢測、性能分析和容量規劃變得更加簡單。
⏩安全性能
主要特點是可以實現零信任網絡中的服務之間通訊加密。Istio 通過自動爲服務之間的通信提供雙向 TLS 加密來增強安全性,同時 Istio 還提供了強大的身份驗證、授權和審計功能。
Istio 原理
Istio 可以的作用原理是攔截 Kubernetes 部署 Pod 的事件,然後從 Pod 中注入一個名爲 Envoy 的容器,這個容器會攔截外部到業務應用的流量。由於所有流量都被 Envoy “劫持” 了,所以 Istio 可以對流量進行分析例如收集請求信息,以及一系列的流量管理操作,也可以驗證授權信息。當 Envoy 攔截流量並執行一系列操作之後,如果請求沒問題,就會轉發流量到業務應用的 Pod 中。
當然,由於 Envoy 需要攔截流量之後轉發給業務應用,這樣就多了一層轉發,會導致系統響應速度會有所下降,但是增加的響應時間幾乎可以忽略不計。
每個 Pod 都有一個 Envoy 負責攔截、處理和轉發進出 Pod 的所有網絡流量,這種方式被稱爲 Sidecar。
以下是 Istio Sidecar 的一些主要功能:
-
流量管理:Envoy 代理可以根據 Istio 配置的路由規則(如 VirtualService 和 DestinationRule)實現流量的轉發、分割和鏡像等功能。
-
安全通信:Envoy 代理負責在服務之間建立安全的雙向 TLS 連接,確保服務間通信的安全性。
-
遙測數據收集:Envoy 代理可以收集關於網絡流量的詳細遙測數據(如延遲、成功率等),並將這些數據上報給 Istio 的遙測組件,以便進行監控和分析。
-
策略執行:Envoy 代理可以根據 Istio 配置的策略規則(如 RateLimit 和 AuthorizationPolicy)執行限流、訪問控制等策略。
由於 Pod 是通過 Envoy 暴露端口的,所有進出口流量都需要經過 Envoy 的檢查,所以很容易判斷訪問來源,如果請求方不是在 Istio 中的服務,那麼 Envoy 便會拒絕訪問。
在 Istio 中,Envoy 這一塊稱爲數據平面,而負責管理集羣的 istiod 組件稱爲控制平面。
注意,這裏是 istiod ,是 Istio 負責管理集羣的一種組件。
對 Istio 的介紹就到這裏爲止,在後面的章節中,我們會通過實際使用 Istio ,來進一步深入瞭解 Istio 的功能和原理。