一致性可觀測的雲原生途徑
這一篇我們將透過Service Mesh的視角來看如何達成統一可視性的雲原生途徑。我們會分為三個概念分別是,雲原生,可觀察性(observability) 與一致性可觀測(uniform observability)。
在第一個概念中我們通過描述雲原生的各個面向來檢視雲原生的無定形概念。之後我們將考量監控雲端服務的行為和觀測的服務屬性之間的區別。最後,我們考量了autogenerated telemetry的力量,它可以提供對我們正在運行的服務的"普遍性與一致性"的洞察力。 由於Service Mesh是雲原生的產物,所以讓我們從定義雲原生的真正含義開始看起。
雲原生(Cloud Native)意味著甚麼?
Cloud native包含兩個部分: 技術(technology)與流程(process)。這兩部分都需由機器與人的效率來達成,雲原生技術橫跨了應用程式架構、 封裝(packaging)、與基礎設施。 而雲原生流程則包含了軟體的整個生命週期。經常(但並不是全部),雲原生流程是會減少傳統組織的功能和生命週期步驟(architecture/QA/security/documentation/development/operation等等)變成只有兩個個別主要功能: development(開發)與operation(維運)。這兩個主要功能通常會運用 DevOps 實踐與文化。雲原生軟體通常會是(但不是永遠是) CdaS(continuously delivered as a service)。
雲原生應用程式通常都運作在雲端環境中(Public or private)。最少,它們運行在programmatically addressable的基礎架構之上。意思是,就算我們的應用程式是可以lifting and shifiting到雲端也不代表我們的應用程式是雲原生。
以下是雲原生應用程式會有的一些特徵
- 它們運行在programmatically addressable infrastructure,而且通過跨運算、網路和儲存等系統的一層或多層抽象與物理資源動態分離
- 它們是分佈式和去中心化的,重點通常是應用程式的行為方式,而不是它在何處運行。 它們會考量到軟體生命週期事件以允許rolling update,在不中斷服務的情況下順利升級服務.
- 它們是有韌性與可擴充性, 旨在冗餘運作而不會出現單點故障並持續運作。
- 它們可以通過它們自己的工具和(或)由底層提供的工具觀測到。 考慮到動態特性,分佈式系統相對更難做inspection和debug,因此必須考慮可觀測性。
雲原生之路
對於大多數組織而言,雲原生之路是將雲原生原則應用於現有服務、通過改造或重寫應用程式來應對的演進過程。幸運的是在雲原生原則和工具袃現在的IT世界已經是普遍並被大家所接受。 無論我們的雲原生旅程是需要處理現有服務還是編寫新的服務集合。 Service Meshes提供了可視性的價值 — — 其價值是隨著我們擁有和運行的服務數量的增加而增加。 Service Meshes是container orchestration部署之後的下一個邏輯步驟。下 圖勾勒出各種Cloud native路徑
由於某些Service Meshes比其他service meshes更容易部署,而某些service meshes比其他service meshes提供更多價值,根據我們部署的service meshes,我們可能需要一定數量的微服務才能使部署service meshes是效益的。 隨著時間的推移,Service Meshes(及其擴展)將減輕開發人員常見的Application-level 的考量(例如,成本核算和價格規劃),因為Service Mesh只是提供這些無處不在的關注點。
根據團隊的經驗水平和特定專案,雲原生之路將使用軟體開發流程、 維運實踐、應用程式基礎設施(Application infrastructure)、 封裝(packaging)和runtimes的不同組合。 展示雲原生特性的應用程式和團隊使用下圖中其中顯示的一種、多種組合或所有的方法。
封裝與佈署(Packaging and Deployment)
雲原生技術通常採用
- 微服務(通過service endpoint進行)
- 內建的容器(通過scheduler進行)
- 增強函數(通過event notification進行)
的以上形式。工程師對高效利用機器和交付速度的需求推動了程式封裝模式的演變。雲原生之路推動了越來越小的單元部署。通過高度資源隔離的啟用。通過虛擬化和容器化的隔離提供了更高的效率水準,因為更小的封裝可以使服務器更緊密地裝箱(bin-packed)。
封裝進化的每個階段,從裸機到虛擬機,再到容器,再到單一核心( unikernels) 最後到函數(functions),當以部署的數量來衡量時,都看到了不同程度的使用。 當一些封裝的類型為可移植性(portability)、互操作性(interoperability)、隔離性、效率等提供了更好的保證。 例如,容器提供比虛擬機更高程度的可移植性和互操作性。 儘管它們是輕量(lightweight)、隔離的和無限制的擴展,但函數卻在可移植性方面受到影響,在各種類型的封裝中可能展現出最高程度的lock-in。 無論選擇何種封裝— — 無論是直接部署服務在OS、在VM、或在容器、單一核心還是函數上 — — Service Meshes都可以提供連線、控制、可觀測性與安全。
應用程式架構
比它們採取的形式更重要的是雲原生應用程式架構所顯示的特徵。雲原生的核心是諸如短暫性(ephemerality)、主動調度的工作負載、與明確描述的dependencies的loose coupling、 event driven、horizontally以及乾淨分離的stateless和stateful服務等特性。雲原生應用程式通常體現了一種架構方法,該方法通常是宣告式(declarative),並將韌性、可用性和可觀察性作為前期設計考慮。
雲原生技術使組織能夠構建和運行可擴展的應用程序是動態環境,例如公共雲、私有云和混合雲。在這裡,這些應用程式以宣告式API 為中心,以與基礎設施交互。這些技術使loosely coupled的系統具有韌性、可管理和可觀測。 Istio 和其他開源Service meshes提供了專為雲原生應用程式設計的下一代網路。
開發與維運流程
開發人員和維運人員的體驗也是雲原生設計和流程理念的核心,它促進了代碼和組件的重複使用以及高度的自動化。當與IaC結合時,維運人員會積極自動化部署、監控和擴展雲原生應用程式及其基礎設施的方法。當與強大的自動化結合時,微服務使工程師能夠以最少的工作量頻繁且可預測地進行高強度變更,通常使用多個CI/CD流水線來構建和部署微服務。
高度精細的可觀測性是SRE工程師監控和管理系統和服務的重點。 Istio 生成與跨meshes發送的request相關的mertics、logs和traces,促進服務的檢測,以便在不更改代碼的情況下完成metrics建立和logs/traces產生。 Istio 和一般的service meshes,在 Dev 和 Ops 之間插入一個專用的infra layer,因為他們需要新的應用程式構建來控制網路流量、shaping、影響存取控制以及哪些服務與downstream services對話。 Dev 和 Ops 的decoupling是提供自主獨立交互的關鍵。
雲原生基礎設施
公有雲、混合雲和私有雲顯然是雲原生定義的核心。簡而言之,雲端就是由軟體所定義的基礎設施。使用 API 作為基礎設施的介面 是一個主要的雲端概念。原生整合工作負載使用這些 API(或這些 API 的抽象),而不是不了解其基礎設施的非原生工作負載。隨著“雲原生”定義的演化,雲端服務本身也在演進。從廣義上講,雲端服務已經從 IaaS 發展到託管服務,再到serverless產品,鑑於大多數 FaaS的運算在容器內執行,這些 FaaS 平台可以在Service Meshes上運行並受益於可觀測性。
雲原生技術和流程從根本上提高了機器效率和資源利用率,同時降低了與維護和運營相關的成本,並顯著提高了應用程式的整體敏捷性和可維護性(以上是的理想狀況)。儘管使用container orchestrator解決了一層基礎設施需求,但它並不能滿足所有應用程式或服務等級的要求。Server meshes為雲原生應用程式未滿足的服務等級需求提供了一層解決方案。
甚麼是可觀測性(observability)?
我們使用的任何新術語的正確定義不僅對促進通用命名法和避免爭論很重要。IT產業內已經有了一堆討論了可觀測性與監控系統的研討會。澄清一下,讓我們將monitoring(動詞)視為執行的功能跟活動;而observability(名詞)是系統的屬性。
當談到系統的可觀測性時,我們描述了系統為我們提供信號監控的程度和方式。觀測軟體通常用於capture和expose information(telemetry/measurements) ,使我們能夠對複雜的軟體進行推斷。
相反,monitoring是觀測和檢察系統及其組件隨時間推移的行為和輸出,評估系統狀態的行為。我們監控系統的能力通過其觀測到的屬性(observability)的數量而得到提高。監控判斷狀態是否為真(例如,系統是否服務效能降級)。
將monitorability(名詞)視為monitorable的條件;被monitor的能力。Monitoring正在鎖定故障,通常通過polling observable endpoints。簡單地說,早期監控系統將正常運行時間作為衡量恢復能力的關鍵指標。現代監控工具面向top-level services指標,例如latency、(request失敗的比率)、流量(按 Web 服務的requests per second)和飽和度(資源利用程度的衡量)。現代監控系統通常會注入用於識別異常行為、預測capacity breaches等的分析。Service meshes通過gererate、aggregation和telemetry推斷來提供observability和monitoring之間的橋樑。各種service meshes都將監控工具作為一種功能或簡單的附加組件。
是開發人員用observability,維運人員用minitoring嗎?也許吧,但這不是重點。在service meshes出現之前,不清楚誰負責使system observable並對其進行監控。對於由誰負責定義服務等級 和交付服務等級目標的問題,大多數團隊給出了不同的答案。諸如此類的責任往往是分散的。Service meshes通過在lower-layer infrastructure和較higher-layer Application layer之間引入management layer — — Layer 5(OSI model) — — 來decouple開發和維運團隊。
Pillars of Telemetry
可觀測性可以包括events和errors形式的logs; 以spans和annotations的形式的traces; 和直方圖、儀表、摘要和計數器形式的metrics.如下圖所示
Logs
Logs為metrics等資料提供了額外的資料來源,它們非常適合debugging,因此我們常常很難調整哪些logs要保存下來和哪些logs最終需要全部刪除時這兩者間取得正確的平衡。 但是,logs在效能方面代價通常很高,因為它們往往需要有大的空間來儲存log資料。 儘管結構化logs沒有基於string-based的logs操作所固有的缺點,但它仍然佔用更多的存儲空間並且查詢和處理速度較慢(從log監控供應商的定價模型中可以明顯看出)。 log記錄的一些最佳實踐包括強制執行quota和log generation的動態調整率。
Metrics
與logs不同,metrics具有固定的overhead,並且對 alerts有用的。 總而言之,logs和metrics可以深入了解單個系統,但它們很難了解會穿越多個系統的request的lifetime。 這在分佈式系統中很常見。 metrics可以是強大的,並且在aggregate後會得到一些見解 — — 非常適合識別已知和未知。 考慮到它們針對存儲進行了優化並通過long-term retenion啟用歷史趨勢,metrics的這種高壓縮率會推動它們佔用更小的空間。
Traces
Tracing允許你在跨各種service處理request segments時細緻化的track request(跨度)。 後面很難介紹,因為(除其他原因外)應用程式使用的第三方函式庫也需要量測。 分佈式追踪可能代價很高; 因此,大多數service mesh tracing systems採用各種形式的取樣來僅抓取一部分觀察到的traces。 對traces進行取樣後,performance overhead和storage costs會降低,但是具有可視性(visibility)。 取樣率與抓取traces的頻率(通常表示為相對於服務請求量的百分比)進行平衡。
結合Telemetry Pillars
最大可視性系統利用每個內部信號,包括synthetic checks, end-user experience monitoring(real user monitoring)和分佈式debug工具。 仍然需要black-box testing和synthetic checks,因為它們是對你可能沒有觀察到的所有內容的端到端驗證。
下圖顯示如何在生產環境中收集telemetry是cost、storage和performance(CPU、memory和request latency)overhead與資訊收集的價值之間的折衷,通常是在它修復緩慢或錯誤的responses方面的呈現度或有用程度。
可以說,metrics提供了最佳的ROI。 鑑於某些service mesh有助於分佈式tracing,我們可能會爭辯說分佈式tracing以最少的投資提供了最大的價值回報(相對於提供的見解水準)。 理想情況下,我們的監控方案允許我們調整要收集詳細資訊級別和取樣率,以控制你的overhead costs與所需的可觀測性。
許多組織現在習慣於使用單獨的監控解決方案進行分佈式tracing。 logging, security,access control,等。 service meshes集中並協助解決這些可觀測挑戰,Istio 根據發送到service meshes的request生成並發送多個telemetry信號.
為什麼可觀測性是分佈式系統中的關鍵?
在運行分佈式系統時將logs、metrics和traces匯總和關聯在一起的能力是我們推斷應用程式在其運行的不同基礎設施中發生的事情的能力的關鍵。在運行分佈式系統時,我們了解會發生故障並且可以佔這些known-unknowns的一定比例。我們不會事先知道發生故障的所有方式(unknown-unknowns);因此,我們的系統必須是可細致化的(和debuggable),以便我們可以對用程式的行為提出新的問題和原因(處於基礎設施的背景脈絡下)。在眾多可用signals中,哪些signals最需要監控?
作為service owner,我們需要探索這些複雜且相互關聯的系統,並解釋由我們的監控方案提供的telemetry引起的異常情況。Service mesh通過內部觀察和外部監控的結合來闡明服務操作,否則我們對整個系統可能會是盲目的。
監控是我們執行的一項活動,只需觀察一段時間內系統的狀態即可。 可視察性(可觀察的條件)是衡量一個系統的內部狀態可以從其外部輸出的知識中推斷出來的程度; 衡量事物可觀察程度的一種度量。
與其嘗試通過將Infrastructure logic寫入應用程序代碼來克服分佈式系統的問題,我們還可以使用service mesh來應對這些挑戰。 Service mesh有助於確保服務管理的職責是集中的,避免用一堆有的沒的監控系統,並使可視性在整個服務中無處不在和一致的。
Service Mesh的一致可觀測性
洞察力(可視性)是人們部署Service Mesh的首要原因。Service Mesh不僅提供了一定程度的即時洞察力,而且還統一且無處不在。我們可能已經習慣於擁有用於分佈式traces、logs、security、access control、metrics等的單獨監控解決方案。Service mesh通過生成metrics、logs和穿越mesh的request trace來集中並協助整合這些單獨的管理平台。利用從data plane自動生成的跨度metrics,Istio 提供了分佈式traces的baseline,以便可視化dependcy、request volume和故障率。 Istio 的default attribute template 按版本、來源和時間發出全域的request volume、全域的success rate和單個服務response的metrics。當metrics在我們的cluster中無處不在時,它們會帶來新的見解,並使開發人員不必編寫代碼來發布這些metrics。
洞察力的普遍性和統一性(以及對請求行為的控制)的重要性通過使用client library所產生的挑戰得到了很好的說明。
Client Libraries
client libraries(有時稱為微服務框架)是測試日的首選工具,適合希望將韌性注入其微服務的開發人員。有許多流行的特定於語言的client libraries提供彈性功能,例如time out的request或在服務未及時回應時back off和retry。
隨著微服務在雲原生設計中站穩腳跟,client libraries變得流行起來。作為一種避免必須在每個服務中重寫相同基礎架構和操作邏輯的手段。微服務框架的一個問題是它們將相同的基礎設施和維運問題與我們的代碼結合在一起。這會導致我們的服務中出現代碼重複以及不同client libraries提供的內容及其行為方式不一致。如下圖所示,當運行同一個函式庫或不同函式庫的多個版本時,讓服務團隊更新他們的函式庫可能是一個艱鉅的過程。當這些分佈式系統問題被嵌入到我們的服務代碼中時,我們需要讓我們的工程師更新和更正他們的函式庫(其中可能有幾個,用於不同程度)。部署一致且最新的版本可能需要一些時間。實現和強制執行一致性具有挑戰性。
與監控系統的接口
從應用程式的角度來看,Service mesh主要提供services-to-services通信的black-box監控(從外部觀察系統),去除white-box監控(觀察內部系統 — — 從內向外報告測量結果)。應用程式作為微服務需要負責關注的責任。包含data plane的proxy被很好地定位(transparently, in-band)以生成metrics、logs和traces,提供統一的和貫穿整個mesh的可觀察性。 Istio 提供adapters來轉換此telemetry並將其傳輸到我們選擇的監控系統。
在對交付速度、潛在的全球規模和明智的資源利用的需求的推動下,雲原生應用程式在共享的基礎設施上作為不可變的、隔離的、短暫的packages 或image運行。
Client libraries和微服務框架帶來了挑戰。 Service mesh將這些關注點轉移到服務代理中並與Appplication code decouple。
我們的應用程式在生產環境中是否易於監控?許多應用程式是,但遺憾的是,有些應用程式的可觀測性是事後才考慮的。理想情況下,我們應該提前考慮可觀測性,因為這是大規模運行應用程式的一個重要因素,就像backups, security, audit等。通過這種方式,我們可以有意識地進行權衡。無論是否在我們的環境中預先考慮了可觀察性,Service mesh都提供了很多價值。
Telemetry是有成本的。我們應該使用各種技術和演算法來收集最有洞察力的訊號。