您當前的位置:首頁 > 攝影

詳解雲原生全棧監控 | 運維進階

作者:由 雲原生基地 發表于 攝影時間:2022-12-15

前言

當前全球企業雲化、數字化程序持續加速,容器、微服務等雲原生技術在軟體架構中快速滲透,IT 架構雲化、複雜化持續驅動效能監控市場。企業雲化、數字化持續轉型,以及為了考慮系統的彈性、效率,企業軟體開發中大量雲原生技術的應用推動全球 IT 監控市場快速變化,如何全面、有效的對容器、K8s、微服務進行監控是當下雲原生技術面臨的重要課題。

背景和挑戰

雲化產品通常採用服務化框架,由一系列微服務組成,且微服務是可以獨立執行的程序,不同服務可使用不同開發語言,可能分佈部署在幾千臺伺服器上,甚至可能橫跨多個不同的資料中心,服務間使用輕量的通訊機制;服務之間存在複雜的呼叫關係,對運維人員理解系統的行為或分析系統性能帶來巨大挑戰 如:

(1)容器是否正常執行

(2)K8S是否正常執行。

(3)微服務是正常

(5)業務調用出現問題,如何快速找出哪個服務發生失敗?

(6)某個業務呼叫耗時較長,如何快速找到效能瓶頸點?

(7)如何快速獲取某次呼叫的業務日誌進行分析定位?

解決方案

概述

雲原生監控體系包括:Healthchecks、Metrics、Logging、Tracing。Healthchecks:健康檢查可以定期檢查某個應用的存活狀態;Metrics:度量指標監控,在離散的時間點上產生數值點;Logging:日誌監控;Tracing:呼叫鏈監控。

各種監控工具適用場景如下圖所示:

詳解雲原生全棧監控 | 運維進階

健康檢查

微服務架構,為了保證所有服務可用,當服務發生問題時能及時摘除有問題的服務需要定期檢測服務可用性,即健康檢查。通常健康健康檢查包括TCP與HTTP兩種。即定時傳送TCP或HTTP請求,根據響應來確定服務是否可用。一般透過TCP定期請求來判定網路層是否正常,而透過Http請求判斷應用層是否正常。服務要配置好請求介面,檢測服務定期向指定的介面傳送http請求,並根據介面響應碼和響應時間判斷。Spring boot的end port /health可以檢查應用的健康狀態,舉例說,當我們訪問 http://localhost:8088/health 時,可以看到 HealthEndPoint 給我們提供預設的監控結果,包含 磁碟檢測和資料庫檢測。

{

“status”: “UP”,

“diskSpace”: {

“status”: “UP”,

“total”: 398458875904,

“free”: 315106918400,

“threshold”: 10485760

},

“db”: {

“status”: “UP”,

“database”: “MySQL”,

“hello”: 1

}

}

容器監控

容器監控使用Prometheus-cAdvisor,cAdvisor是谷歌專為監控容器效能狀態設計的一個開源工具,cAdvisor提供有Push和Pull兩種獲取效能資料的介面。Push介面指的是由cAdvisor主動將資料週期性的推送到遠端的儲存服務中,Influxdb與cAdvisor的對接就是透過這個介面完成的。而Pull介面則允許外部訪問服務隨時主動從cAdvisor獲取到當時時刻的效能資料,然後自行處理,Prometheus與cAdvisor的對接用的是這種方法。

基於容器的微服務監控和原始的監控是有很大區別的,因為服務的例項生存週期很短,分分鐘可能就會有容器的生滅。微服務的容器與宿主機的監控離不開CPU、記憶體、磁碟、網絡卡這些基礎的效能指標,對於宿主機的監控來說,我們可以依然使用原始的監控方式,每個宿主機安裝一個代理來採集伺服器的效能指標,代理在採集效能指標的時候可以打上時間戳和相應的標籤來區分不同效能指標的資料維度(metric),然後將監控資料彙總到時間序列資料庫,裡面的資料可以對接目前一些開源的元件來進行視覺化的展示,也可以對接報警服務(結合報警服務的報警策略)進行報警。

容器的監控自然就和宿主機不太一樣了,我們不能說給每個容器映象內部都整合一個監控代理(agent),這樣的話侵入性太強,不易於維護。Prometheus有很多的Exporter可以用來採集監控資料,例如我們想採集Kubernetes上所有容器(pod)的效能指標的話,Promethus可以透過直接配置多個Kubernetes ApiServer的Endpoints來監控整個Kubernetes叢集。

K8S監控

K8S叢集層面選擇使用Prometheus。叢集層面的監控又分為Node、K8S基礎元件、K8S資源物件三大類。

1、對於Node的監控,Prometheus提供了node-exporter,可採集到CPU、記憶體、磁碟IO、磁碟使用率、網路包量、頻寬等資料;

2、K8S基礎元件類的kubelet、kube-apiserver、kube-controller-manager 和 kube-scheduler等,都提供了 metrics介面暴露自身的執行時的監控資料,這些資料都可被部署在K8S叢集中的Prometheus 直接拉取到;

3、結合cadvisor 和kube-state-metrics ,可直接採集到K8S中Pod的 CPU、記憶體、磁碟 IO、網路 IO 等資料。由CoreOS開源的Kube-Prometheus專案,極大簡化了Prometheus的安裝部署運維工作。

基於Kubernetes實現的微服務應用級的監控外掛,如下圖:

詳解雲原生全棧監控 | 運維進階

在Kubernetes的master節點,也就是安裝apiserver的那臺伺服器上執行一個監控外掛,該外掛可以透過一個kubernetes提供的官方客戶端來訪問apiserver,首先我們要告知外掛要監控哪個namespace下的哪個service,然後,外掛透過和apiserver進行互動獲取某個service下所有Pods的例項,外掛會併發訪問所有pod提供的/metrics介面(Path可配),並給每個pod的返回資料(json格式,遵守一定的資料格式契約)打上pod_name的標籤來標識每個pod返回的metrics,打上pod_name標籤的同時也會打上service_name的標籤用來區分具體是哪個service的監控資料。

Kubernetes主要提供瞭如下5種服務發現模式和Prometheus進行整合:Node、Pod、Endpoints、Service、Ingress。監控K8S將使用Prometheus federation的形式,k8s叢集外部的Prometheus從k8s叢集中Prometheus拉取監控資料,外部的Prometheus才是監控資料的儲存。k8s叢集中部署Prometheus的資料儲存層可以簡單的使用emptyDir,資料只保留24小時(或更短時間)即可,部署在k8s叢集上的這個Prometheus例項即使發生故障也可以放心的讓它在叢集節點中漂移。

1)建立namespace取名ns-monitor

2)在k8s中部署node-exporter

Node-exporter用於採集kubernetes叢集中各個節點的物理指標,比如:Memory、CPU等。可以直接在每個物理節點是直接安裝,這裡我們使用DaemonSet部署到每個節點上,使用 hostNetwork: true 和 hostPID: true 使其獲得Node的物理指標資訊,配置tolerations使其在master節點也啟動一個pod。

#建立node-exporter。yml檔案

3-1)建立編輯rabc。yml

rbac。yml定義了Prometheus容器訪問k8s apiserver所需的ServiceAccount和ClusterRole及ClusterRoleBinding

3-2)建立編輯configmap。yml 進行configmap中的prometheus的配置檔案

3-3)prometheus-deploy。yml定義Prometheus的部署

3-4)prometheus-svc。yml定義Prometheus的Service

需要將Prometheus以NodePort, LoadBalancer或使用Ingress暴露到叢集外部,這樣外部的Prometheus才能訪問它 。

3-5)使用yml檔案建立物件

kubectl create -f rbac。yml

kubectl create -f configmap。yml

kubectl create -f prometheus-deploy。yml

kubectl create -f prometheus-svc。yml

4)配置配置Prometheus Federation

完成Kubernetes叢集上的Prometheus的部署之後,下面將配置叢集外部的Prometheus使其從叢集內部的Prometheus拉取資料。實際上只需以靜態配置的形式新增一個job就可以。

5)配置pushgateway

日誌監控

Fluentd是一個通用的資訊收集、整理、轉發的流式資料處理工具。預設情況下Docker會將所有容器輸出到系統控制檯的內容重定向到以容器ID命名的一個本地目錄中,只需要定期採集所有這些目錄的內容就能一字不漏的將容器的輸出捕獲出來,這種方式的侵入性很小,但由於是週期性的收集,日誌在匯聚端(例如Kibana)的展示會有一定的延時,延時長度與日誌收集的週期相關。相反的,如果使用Docker的日誌驅動(啟動docker後臺服務時指定引數–log-driver=fluentd)將獲得實時性很好的匯聚端日誌展示,但由於日誌直接傳送到了遠端的Fluentd服務,會使得在本地主機上的docker logs命令失效。

兩種方式的共性在於:不論透過哪一種方式,收集到的日誌都能夠以容器名稱、映象、標籤等對容器使用十分友好的維度進行檢索。Kubernetes 叢集本身不提供日誌收集的解決方案,我們採用fluentd——>kafka——>logstash——>elasticsearch——>kibana的方式,直接在應用程式中將日誌資訊推送到採集後端。

呼叫鏈監控

呼叫鏈定義:在系統完成一次業務呼叫的過程中,把服務之間的呼叫資訊(時間、介面、層次、結果)打點到日誌中,然後將所有的打點資料連線為一個樹狀鏈條就產生了一個呼叫鏈。跟蹤系統把過程中產生的日誌資訊進行分析處理,將業務端到端的執行完整的呼叫過程進行還原,根據不同維度進行統計分析;從而標識出有異常的服務呼叫,能夠快速分析定界到出異常的服務;同時可根據資料統計分析系統性能瓶頸。

Dapper, a Large-Scale Distributed Systems Tracing Infrastructure 描述了其中的原理和一般性的機制。模型中包含的術語也很多,理解最主要的兩個即可:

Trace:一次完整的分散式呼叫跟蹤鏈路。

Span:跨服務的一次呼叫;多個 Span 組合成一次 Trace 追蹤記錄。

下面透過一次使用者服務請求來完成呼叫鏈過程模擬:

詳解雲原生全棧監控 | 運維進階

左圖為一個和5臺伺服器相關的一個服務,包括:前端(A),兩個中間層(B和C),以及兩個後端(D和E)。當一個使用者(這個用例的發起人)發起一個請求時,首先到達前端,然後傳送兩個RPC到伺服器B和C。B會馬上做出反應,但是C需要和後端的D和E互動之後再返還給A,由A來響應最初的請求。右表示對應 Span 的管理關係。每個節點是一個 Span,表示一個呼叫。至少包含 Span 的名、父 SpanId 和 SpanId。節點間的連線下表示 Span 和父 Span 的關係。所有的 Span 屬於一個跟蹤,共用一個 TraceId。從圖上可以看到對前端 A 的呼叫 Span 的兩個子 Span 分別是對 B 和 C 呼叫的 Span,D 和 E 兩個後端服務呼叫的 Span 則都是 C 的子 Span。跟蹤系統根據使用者請求每次生成的全域性唯一的ID(TraceId),TraceId 在span間傳遞,將不同服務的“孤立的”日誌串在一起,重組還原出更多有價值的資訊。如今呼叫鏈系統有很多實現,用的比較多的如 zipkin ,還有已經加入 CNCF 基金會並且用的越來越多的 Jaeger。

呼叫鏈模型格式

為了能將一系列埋點串接成一個完整的呼叫鏈,並區分不同請求的呼叫鏈日誌資訊,同時資訊中需要包含請求狀態與時長,對於不同業務應用可能需要有特殊的資訊記錄到日誌中;所以呼叫鏈日誌資訊(Span)應包含如下內容:

詳解雲原生全棧監控 | 運維進階

一次業務請求呼叫鏈模型:

詳解雲原生全棧監控 | 運維進階

對於Trace而言,最基礎的能力是能夠記錄請求在多個服務之間呼叫的傳播、依賴關係並進行視覺化。而從Trace本身的資料特點而言,它是規則化、標準化且帶有依賴關係的訪問日誌,因此可以基於Trace去計算並挖掘更多的價值。下面是SLS OpenTelemetry Trace的實現架構,核心是透過資料編排計算Trace原始資料並得到聚合資料,並基於SLS提供的介面實現各類Trace的附加功能。例如:

1。依賴關係:這是絕大部分的Trace系統都會附帶的功能,基於Trace中的父子關係進行聚合計算,得到Trace Dependency

2。服務/介面黃金指標:Trace中記錄了服務/介面的呼叫延遲、狀態碼等資訊,基於這些資料可以計算出QPS、延遲、錯誤率等黃金指標。

3。上下游分析:基於計算的Dependency資訊,按照某個Service進行聚合,統一Service依賴的上下游的指標

4。中介軟體分析:Trace中對於中介軟體(資料庫/MQ等)的呼叫一般都會記錄成一個個Span,基於這些Span的統計可以得到中介軟體的QPS、延遲、錯誤率。

告警相關:通常基於服務/介面的黃金指標設定監控和告警,也可以只關心整體服務入口的告警(一般對父Span為空的Span認為是服務入口呼叫)。

Metrics:

通常都是range查詢,每次查詢某一個單一的指標/時間線,或者一組時間線進行聚合,例如統一某個應用所有機器的平均CPU

時序類的查詢一般QPS都較高(主要有很多告警規則),為了適應高QPS查詢,需要把資料的聚合性做好

對於這類資料都會有專門的時序引擎來支撐,目前主流的時序引擎基本上都是用類似於LSM Tree的思想來實現,以適應高吞吐的寫入和查詢(Update、Delete操作很少)

同時可觀測性資料還有一些共性的特點,例如高吞吐寫入(高流量、QPS,而且會有Burst)、超大規模查詢特點、時間訪問特性(冷熱特性、訪問區域性性等)。

業務呼叫鏈路監控

Skywalking是一款比較優秀的開源的應用效能監控工具,支援對分散式系統的監控、跟蹤和診斷。它提供瞭如下的主要功能特性:

詳解雲原生全棧監控 | 運維進階

Service Topology監控

呼叫鏈路監控可以從兩個角度去看待。透過給服務新增探針併產生實際的呼叫之後,我們可以透過Skywalking的前端UI檢視服務之間的呼叫關係。我們簡單模擬一次服務之間的呼叫。新建兩個服務,service-provider以及service-consumer,服務之間簡單的透過Feign Client 來模擬遠端呼叫。

詳解雲原生全棧監控 | 運維進階

從圖中可以看到:

有兩個服務節點:provider & consumer

有一個數據庫節點:localhost【mysql】

一個註冊中心節點

consumer消費了provider提供出來的介面。

一個系統的拓撲圖讓我們清晰的認識到系統之間的應用的依賴關係以及當前狀態下的業務流轉流程。細心的可能發現圖示節點consumer上有一部分是紅色的,紅色是什麼意思呢?

紅色代表當前流經consumer節點的請求有一段時間內是響應異常的。當節點全部變紅的時候證明服務現階段內就徹底不可用了。運維人員可以透過Topology迅速發現某一個服務潛在的問題,並進行下一步的排查並做到預防。

Skywalking Trace監控

Skywalking透過業務呼叫監控進行依賴分析,提供給我們服務之間的服務呼叫拓撲關係、以及針對每個endpoint的trace記錄。

我們在之前看到consumer節點服務中發生了錯誤,讓我們一起來定位下錯誤是發生在了什麼地方又是什麼原因呢?

詳解雲原生全棧監控 | 運維進階

在每一條trace的資訊中都可以看到當前請求的時間、GloableId、以及請求被呼叫的時間。我們分別看一看正確的呼叫和異常的呼叫。

Trace呼叫鏈路監控

詳解雲原生全棧監控 | 運維進階

圖示展示的是一次正常的響應,這條響應總耗時19ms,它有4個span:

span1 /getStore = 19ms 響應的總流轉時間

span2 /demo2/stores = 14ms feign client 開始呼叫遠端服務後的響應的總時間

span3 /stores = 14ms 介面服務響應總時間

span4 Mysql = 1ms 服務提供端查詢資料庫的時間

這裡span2和span3的時間表現相同,其實是不同的,因為這裡時間取了整。

在每個Span中可以檢視當前Span的相關屬性。

元件型別: SpringMVC、Feign

Span狀態: false

HttpMethod: GET

Url:

http://

192。168。16。125:10002/de

mo2/stores

詳解雲原生全棧監控 | 運維進階

這是一次正常的請求呼叫Trace日誌,可能我們並不關心正常的時候,畢竟一切正常不就是我們期待的麼!我們再來看下,異常狀態下我們的Trace以及Span又是什麼樣的呢。

詳解雲原生全棧監控 | 運維進階

發生錯誤的呼叫鏈中Span中的is error標識變為true,並且在名為Logs的TAB中可以看到錯誤發生的具體原因。根據異常情況我們就可以輕鬆定位到影響業務的具體原因,從而快速定位問題,解決問題。透過Log我們看到連線被拒,那麼可能是我們的網路出現了問題(可能性小,因為實際情況如果網路出現問題我們連這個trace都看不到了),也有可能是服務端配置問題無法正確建立連線。透過異常日誌,我們迅速就找到了問題的關鍵。

服務效能監控

服務效能可以實現以下關鍵指標:

1、關鍵業務指標:響應時間、Apex、吞吐率、錯誤率

2、事務:耗時百分比、響應時間、吞吐量、Apdex、錯誤率、呼叫次數

3、資料庫:SQL耗時、平均響應時間、吞吐率、SQL語句執行計劃、程式碼堆疊

4、NoSQL:Memcached/Redis/MogooDB的操作總耗時、平均響應時間、吞吐率

5、外部應用:HTTP/Thrif/Dubbo/Web Service的響應時間佔比、平均響應時間、響應總時間、吞吐率、錯誤率

6、MQ:RabbitMQ/JMS/ActiveMQ生產者、消費者的訊息總數、每分鐘訊息數、平均訊息傳送時間、總流量

7、JVM:記憶體使用量、執行緒、HTTP會話

原文來自:詳解雲原生全棧監控 | 運維進階

標簽: 呼叫  監控  服務  Prometheus  Span