1 關於雲原生
雲原生計算基金會(Cloud Native Computing Foundation, CNCF)的官方描述是:
雲原生是一類技術的統稱,透過雲原生技術,我們可以構建出更易於彈性擴充套件、極具分散式優勢的應用程式。這些應用可以被執行在不同的環境當中,比如說 私有云、公有云、混合雲、還有多雲場景。雲原生包含了 容器、微服務(涵蓋服務網格)、Serverless、DevOps,API管理、不可變基礎架構等能力。透過雲原生技術構建出來的應用程式,對
底層基礎架構的耦合很低,易於遷移,可以充分地利用雲所提供的能力,因此雲原生應用的研發、部署、管理相對於傳統的應用程式更加高效和便捷。
1.1 微服務
微服務是一種架構模式,是面向服務的體系結構(SOA)軟體架構模式的一種演變,
它提倡將單一應用程式劃分成一組鬆散耦合的細粒度小型服務,輔助輕量級的協議,互相協調、互相配合,為使用者提供最終價值。
具有 單一職責、輕量級通訊、獨立性、程序隔離、混合技術棧和混合部署方式、簡化治理 等特點。
1.2 DevOps
DevOps 作為一種工程模式,本質上是透過對開發、運維、測試,配管等角色職責的分工,實現工程效率最大化,進而滿足業務的需求。
1.3 持續交付
在不影響使用者使用服務的前提下頻繁把新功能釋出給使用者使用,要做到這點比較難。需要強大的流量管理能力,動態的服務擴縮容為平滑釋出、ABTesting提供保障。
1.4 容器化
容器化的好處在於運維的時候不需要再關心每個服務所使用的技術棧了,每個服務都被無差別地封裝在容器裡,可以被無差別地管理和維護,現在比較流行的技術是docker和k8s。
2 關於ServiceMesh
2.1 什麼是ServiceMesh
ServiceMesh 是最新一代的微服務架構,作為一個基礎設施層,能夠與業務解耦,主要解決複雜網路拓撲下微服務與微服務之間的通訊,其實現形態一般為輕量級網路代理,並與應用SideCar部署,同時對業務應用透明。
如果從一個單獨鏈路呼叫可以得到以下的結構圖:
如果我們從一個全域性視角來看,綠色的為應用服務,藍色的為SideCar,就會得到如下部署圖:
2.2 相較傳統微服務的區別
以SpringCloud與Dubbo為代表的微服務開發框架非常受歡迎。但我們發現,他有優秀的服務治理能力,也有明顯的痛點:
1. 侵入性強。 想要整合SDK的能力,除了需要新增相關依賴,業務層中入侵的程式碼、註解、配置,與治理層界限不清晰。可以想想Dubbo、SpringCloud 等的做法
2. 升級成本高。 每次升級都需要業務應用修改SDK版本,重新進行功能迴歸測試,並對每一臺服務進行部署上線,與快速迭代開發相悖。
3. 版本碎片化嚴重。 由於升級成本高,而中介軟體版本更新快,導致線上不同服務引用的SDK版本不統一、能力參差不齊,造成很難統一治理。
4. 中介軟體演變困難。 由於版本碎片化嚴重,導致中介軟體向前演進的過程中就需要在程式碼中相容各種各樣的老版本邏輯,帶著"枷鎖”前行,無法實現快速迭代。
5. 內容多、門檻高。 依賴元件多,學習成本高。
6. 治理功能不全。 不同於RPC框架,SpringCloud作為治理全家桶的典型,也不是萬能的,諸如協議轉換支援、多重授權機制、動態請求路由、故障注入、灰度釋出等高階功能並沒有覆蓋到。
2.3 ServiceMesh的價值 — 賦能基礎架構
- 統一解決多語言框架問題,降低開發成本
- 降低測試成本,提升質量
- 控制邏輯集中到控制面
- 為新架構演進提供支援,如Serverless
- 網格半覆蓋 轉 統一覆蓋(彌補service-center並逐漸過度)
- 完整的閉環微服務統籌和管理能力
2.4 ServiceMesh的價值 — 賦能業務
- 框架與業務解耦,減少業務限制。
- 簡化服務所依賴SDK版本管理。
- 依託熱升級能力,版本召回週期短。
- SDK瘦身,減少業務依賴衝突。
- 豐富的流量治理、安全策略、分散式Trace、日誌監控,下沉服務治理底座,讓業務專注業務。
3 ServiceMesh 核心能力
3.1 流量治理
微服務應用最大的痛點就是處理服務間的通訊,而這一問題的核心其實就是流量管理。
3.1.1 請求路由
將請求路由到服務的版本,應用根據 HTTP 請求 header 的值、Uri的值 路由流量到不同的地方。匹配規則可以是流量埠、header欄位、URI等內容。
RuleMatch參考
3.1.2 流量轉移
當微服務的一個版本逐步遷移到另一個版本時,我們可以將流量從舊版本遷移到新版本。如下圖,使用weight引數進行權重分配,
這個很典型的應用場景就是灰度釋出或者ABTesting。
3.1.3 負載均衡
同3.1.2的圖,Service B 有多個例項,所以可以另外製定負載均衡策略。
負載均衡策略支援簡單的負載策略(ROUND_ROBIN、LEAST_CONN、RANDOM、PASSTHROUGH)、一致性 Hash 策略和區域性負載均衡策略。
3.1.4 超時
對上游的請求設定,設定一個一定時長(0.5s)的超時,請求超過這個時間不響應,可以直接fallback。目標還是過載保護。
3.1.5 重試
當請求在固定的時間內沒有返回正確值的時候,可以配置重試次數。設定如果服務在 1 秒內沒有返回正確的返回值,就進行重試,重試的條件為返回碼為5xx,重試 3 次。
分散式環境下,重試是高可用的重要技術,重試方案慎用。
retries:
attempts: 3
perTryTimeout: 1s
retryOn: 5xx
3.1.6 熔斷/限流/降級
熔斷的策略比較多,可以配置 最大連線數、連線超時時間、最大請求數、請求重試次數、請求超時時間等,我們都可以給他熔斷掉,fallback回去。
但是目前看,Istio 對更靈活、更細粒度的限流、降級等能力支援的還不夠好,合理應該有漏斗池演算法(如阿里開源限流框架Sentinel)或者令牌桶演算法(如 Google Guava 提供的限流工具類 RateLimiter)這樣的靈活做法。
但是可以採用其他方式處理,比如可以透過流量轉發將部分流量流動到預設服務去,該服務啟用預設的fallback,但是需要控制好取樣時間、熔斷半開的策略。
3.1.7 離群檢測(Outlier Detection)
當叢集中的服務故障的時候,其實我們最優先的做法是先進行離群,然後再檢查問題,處理問題並恢復故障。所以,能否快速的離群對系統的可用性很重要。
Outlier Detection 允許你對上游的服務進行掃描,然後根據你設定的引數來判斷是否對服務進行離群。
下面的配置表示每秒鐘掃描一次上游主機,連續失敗 2 次返回 5xx 錯誤碼的所有主機會被移出負載均衡連線池 3 分鐘,上游被離群的主機在叢集中佔比不應該超過10%。
但無論比例多少,只要你叢集下的服務例項>=2個,都將彈出至少1個主機。它有很詳細的配置,參考這邊。
注意:3分鐘之後回群,如果再被離群,則為上次離群時間+本次離群時間,即 3+3;預設超過50%(可調整比例)被離群,進入恐慌模式。
outlierDetection:
consecutiveErrors: 2
interval: 1s
baseEjectionTime: 3m
maxEjectionPercent: 10
3.1.8 故障注入
就是用來模擬上游服務對請求返回指定異常碼時,當前的服務是否具備處理能力。系統上線前,可以配置注入的httpStatus和比例,來驗證下游服務對故障的處理能力。
3.1.9 流量映象(Mirroring)
這個也叫做影子流量。是指透過一定的配置將線上的真實流量複製一份到映象服務中去,可以設定流量比例,只轉發不響應。
個人覺得這個還是比較有用的,好處是 完整的線上正式環境模擬、流量分析、壓力測試;全真的線上問題再現,方便問題排查。
3.2 可觀察性
3.2.1 監控與視覺化
Prometheus(標配,預設抓取指標資料)、kiali監控(服務檢視,Istion鏈路的可觀察性) 、Grafana(BI報表)(資料面、控制面、xDS Service 各健康指標)
後續章節會逐一展開...
3.2.2 訪問日誌
ELK、EFK (Envoy記錄AccessLog,包含SideCard的InBound、OutBound記錄)
後續章節會詳細展開...
3.2.3 分散式追蹤
本質上查詢多個HTTP請求之間的相關性的一種方法是使用相關性ID。該ID應該傳遞給所有請求,以便跟蹤平臺知道哪些請求屬於同一請求。如下圖:
儘管Istio利用Envoy的分散式跟蹤功能提供開箱即用的跟蹤整合,但是其實這是一個誤解,我們的應用程式需要做一些工作。應用程式需要傳播以下header:
- x-request-id
- x-b3-traceid
- x-b3-spanid
- x-b3-parentspanid
- x-b3-sampled
- x-b3-flags
- x-ot-span-context
Istio Sidecar內的Envoy代理接收這些標頭,並將它們傳遞給配置的tracing系統。所以實際上,Istio中服務追蹤預設只會追蹤到2級,
例如A -> B -> C, 在Istio中會出現2條追蹤鏈路:A -> B 和B -> C,而不會出現我們期望的A -> B -> C的形式,如果想要服務串聯起來,需要對服務間呼叫進行改造,
在Istio中應用程式透過傳播http header來將span關聯到同一個trace。
3.3 安全機制
- Service Mesh可以在服務間通訊中引入雙向TLS加密,確保資料在傳輸過程中不被篡改和竊聽。控制平面負責管理和分發證書,Sidecar Proxy在通訊過程中進行加密和解密操作。
- 透過引入身份認證和訪問控制策略,可以細粒度地控制哪些服務可以訪問其他服務。
3.4 策略執行
Service Mesh透過在每個服務例項旁邊部署Sidecar Proxy,實現了對服務間通訊的透明代理。這些代理負責攔截出入的所有流量,並根據控制平面下發的配置和策略執行相應的操作。具體工作原理如下:
3.4.1 服務發現:
當一個服務例項啟動時,它會向服務註冊中心註冊自己的資訊。控制平面負責管理這些服務例項資訊,並將更新的服務列表分發給所有Sidecar Proxy。
3.4.2 流量管理:
當一個服務需要與另一個服務通訊時,流量首先經過本地的Sidecar Proxy。代理根據配置的路由規則和負載均衡策略,將流量轉發到目標服務例項。
控制平面可以動態更新這些路由規則,實現藍綠部署、金絲雀釋出等高階流量管理功能。
3.4.3 安全認證:
Service Mesh可以在服務間通訊中引入雙向TLS加密,確保資料在傳輸過程中不被篡改和竊聽。控制平面負責管理和分發證書,Sidecar Proxy在通訊過程中進行加密和解密操作。
透過引入身份認證和訪問控制策略,可以細粒度地控制哪些服務可以訪問其他服務。
3.4.4 可觀察性:
Service Mesh中的代理會收集每個請求的日誌、監控資料和追蹤資訊,並將這些資料傳送到可觀察性元件進行處理和儲存。
運維人員可以透過控制平面提供的介面和儀表盤,實時監控服務間的流量情況、延遲、錯誤率等指標,並進行故障排查和效能最佳化。
4 總結
Service Mesh相比傳統微服務框架以下幾方面有明顯優勢:
- 解耦應用程式和通訊邏輯
- 提供增強的服務治理能力
- 提高可觀察性和可除錯性
- 支援多語言和協議以
- 提高系統可靠性和可擴充套件性