1. 程式人生 > 實用技巧 >三分鐘快速解析Kubernetes微服務監控體系

三分鐘快速解析Kubernetes微服務監控體系

監控系統是運維體系乃至整個軟體產品生命週期中最重要的一環,完善的監控可以幫助我們事前及時發現故障,事後快速追查定位問題。而在以微服務為代表的雲原生架構體系中,系統分為多個層次,服務之間呼叫鏈路複雜,系統中需要監控的目標非常多,如果沒有一個完善的監控系統就難以保證整體服務的持續穩定。

監控物件及分層

在實際場景中監控系統按照監控的物件及系統層次結構,從底向上可以依次劃分為基礎層、中間層、應用層、業務層等多個層面的監控。具體可如圖所示:

基礎層監控就是對主機伺服器(包括宿主機、容器)及其底層資源進行監控,以保證應用程式執行所依賴的基礎環境的穩定執行。基礎層監控主要有兩個方向:

  • 資源利用:是對像I/O利用率、CPU利用率、記憶體使用率、磁碟使用率、網路負載等這樣的硬體資源進行監控。避免因應用程式本身或其它特殊情況引起的硬體資源耗盡而出現的服務故障。

  • 網路通訊:是對伺服器之間的網路狀態進行監控。網路通訊是網際網路的重要基石,如果主機之間的網路出現如延遲過大、丟包率高這樣的網路問題,將會嚴重影響業務。

需要說明的是,在基於Kubernetes容器化技術的新型雲原生基礎設施中,基礎層的監控不僅要對宿主機本身進行監控,也要對Kubernetes叢集狀態及其容器資源使用情況進行監控。這在後面我們構建基於Kubernetes的基礎層監控體系時將會具體介紹。

中間層監控主要是指對諸如Nginx、Redis、MySQL、RocketMQ、Kafka等應用服務所依賴的中介軟體軟體的監控,它們的穩定也是保證應用程式持續可用的關鍵。一般來說特定的中介軟體軟體都會根據自身特點構建針對性的監控體系。

應用層監控這裡就是指對業務性服務程式的監控,一般來說我們對應用程式監控的關注點主要體現在以下幾個方面:

  • HTTP介面請求訪問。包括介面響應時間、吞吐量等;

  • JVM監控指標。對於Java服務,還會重點關注GC時間、執行緒數、FGC/YGC耗時等JVM效能相關的指標;

  • 資源消耗。應用程式部署後會消耗一定的資源,例如應用程式對記憶體、CPU的消耗情況;

  • 服務的健康狀態。例如當前服務是否存活,執行是否穩定等;

  • 呼叫鏈路。在微服務架構中,由於呼叫鏈路變長,還需要重點監控服務之間的呼叫關係和呼叫情況,避免區域性上下游服務之間的鏈路故障引發系統全域性性雪崩;

業務層監控也是監控系統所關注的一個重要內容,在實際場景中如果你只是讓應用程式穩定執行那肯定是遠遠不夠的。因此,我們常常會對具體業務產生的資料進行監控,例如網站系統所關注的PV、UV等引數;後端如交易之類的系統我們則會關注訂單量、成功率等。

業務指標也是體現系統穩定性的核心要素。任何系統,如果出現了問題,最先受到影響的肯定是業務指標。對於核心業務指標的設定因具體的業務和場景而異,所以對於業務層的監控需要構建具備業務特點的業務監控系統。

常見的監控指標型別

在指標類監控系統中,通過統計指標可以感性地認識到整個系統的執行情況。出現問題後,各個指標會首先出現波動,這些波動會反映出系統是那些方面出了問題,從而可以據此排查出現問題的原因。下面我們分別來看下統計指標到底有哪些型別,以及常見的統計指標都有哪些,它是我們進一步理解指標類監控系統的基礎。

從整體上看,常見的Metrics指標型別主要有四類:

  • 計數器(Counter)
  • 測量儀(Gauge)
  • 直方圖(Histogram)
  • 摘要(Summary)

1、計數器(Counter)

計數器是一種具有累加特性的指標型別,一般這個值為Double或者Long型別。例如常見的統計指標QPS、TPS等的值就是通過計數器的形式,然後配合一些統計函式計算得出的。

2、測量儀(Gauge)

表示某個時間點,對某個數值的測量。測量儀和計數器都可以用來查詢某個時間點的固定內容的數值,但和計數器不同,測量儀的值可以隨意變化,可以增加也可以減少。比如獲取Java執行緒池中活躍的執行緒數,使用的是ThreadPoolExecutor中的getActiveCount方法;此外,還有比較常見的CPU使用率、記憶體佔用量等具體指標都是通過測量儀獲取的。

3、直方圖(Histogram)

直方圖是一種將多個數值聚合在一起的資料結構,可以表示資料的分佈情況。比如以常見的響應耗時舉例,可以把響應耗時資料分為多個桶(Bucket),每個桶代表一個耗時區間,例如0~100毫秒、100~500毫秒,以此類推。通過這樣的形式,可以直觀地看到一個時間段內的請求耗時分佈,這將有助於我們理解耗時情況分佈。

4、摘要(Summary)

摘要與直方圖類似,表示的也是一段時間內的資料結果,但是摘要反應的資料內容不太一樣。摘要一般用於標識分位值,分位值其實就是我們常說的TP90、TP99等。例如有100個耗時數值,將所有的數值從低到高排列,取第90%的位置,這個位置的值就是TP90的值,如果這個桶對應的值假設是80ms,那麼就代表小於等於90%位置的請求都≤80ms。

Kubernetes微服務監控體系

前面我們從整體上描述了監控系統分層以及理解指標類監控系統所需要掌握的幾類常見的指標型別。接下來我們重點探討基於Kubernetes的微服務監控體系。

從監控物件及系統分層的角度看,監控系統需要監控的範圍是非常廣泛的,但從微服務監控的角度來說,如果你的微服務部署完全是基於Kubernetes雲原生環境的,那麼我們需要關注的監控物件主要就是Kubernetes叢集本身以及執行其中的微服務應用容器。例如對容器資源使用情況,如CPU使用率、記憶體使用率、網路、I/O等指標的監控。

當然,這並不是說像基礎層的物理機、虛擬機器裝置或者中間層軟體的監控我們不需要關注,只是這部分工作一般會有專門的人員去維護。而如果使用的是雲服務,那麼雲服務廠商大都已經為我們提供了監控支援。此外,對於基礎物理層及大部分中間軟體的監控並不是本文所要表達的重點,所以也就不再做過多的實踐,大家對此有個全域性的認識即可。

而回到以Kubernetes為載體的微服務監控體系,雖然曾經Kubernetes專案的監控體系非常複雜,社群中也有很多方案。但是這套體系發展到今天,已經完全演變成了以Prometheus專案為核心的一套統一方案。在本節的內容中我們就將演示如何圍繞Prometheus來構建針對Kubernetes的微服務監控系統。

1、Prometheus簡介

經過行業多年的實踐和沉澱,目前監控系統按實現方式主要可以分為四類:

1)、基於時間序列的Metrics(度量指標)監控;

2)、基於呼叫鏈的Tracing(鏈路)監控;

3)、基於Logging(日誌)的監控;

4)、健康性檢查(Healthcheck)。而在上述幾種監控方式中Metrics監控是其中最主要的一種監控方式。

簡單理解Metrics的表現形式,就是在離散的時間點上產生的數值點[Time,Value],由某個指標組成的一組[Time,Value]數值點序列也被稱為時間序列,所以Metrics監控也常常被稱為時間序列監控。

如上所述,我們簡單闡述了指標系統的基本特點,而接下來要介紹的Prometheus就是一款基於時間序列的開源Metrics型別的監控系統,它可以很方便地進行統計指標的儲存、查詢和告警。從整體上看Prometheus的系統結構,如下圖所示:

從上圖中可以看出,Prometheus工作的核心,主要是使用Pull(拉取)的模式去收集被監控物件的Metrics資料(監控指標資料),然後由Prometheus伺服器將收到的指標資料進行聚合後儲存到TSDB(時間序列資料庫,例如OpenTSDB、InfluxDB)中,以便後續根據時間自由檢索。

有了這套核心機制,Prometheus剩下的元件就主要是用來配合這套機制執行的了。比如PushGateway,它可以允許被監控物件以Push的方式向Prometheus推送Metrics資料。而Alertmanager,則可以根據Metrics資訊靈活地設定報警。

此外,Prometheus還提供了一套完整的PromQL查詢語言,通過其提供的HTTP查詢介面,使用者可以很方便地將指標資料與Grafana(視覺化監控指標展示工具)結合起來,從而靈活地定製屬於系統自身的關鍵指標監控Dashboard(看板)。

2、Prometheus Operator安裝部署

前面我們簡單介紹了Prometheus監控系統的基本原理,接下來的內容將以實操的方式演示如何使用Prometheus構建一套針對Kubernetes叢集的微服務監控體系。

在實際的應用場景中,針對不同的監控物件Prometheus的部署方式也會有所不同。例如要監控的物件是底層的物理機,或者以物理機方式部署的資料庫等中介軟體系統,那麼這種情況下一般也會將Prometheus監控系統的部署環境放置在物理機下。

而如果針對的是Kubernetes叢集的監控,那麼現在主流的方式是採用Promethues-Operator將Promethues部署到Kubernetes叢集之中,這樣能以更原生的方式實施對Kubernetes叢集及容器的監控。這裡所說的Promethues-Operator 是指專門針對Kubernetes的Promethues封裝包,它可以簡化Promethues的部署和配置。

接下來我們具體演示如何通過Promethues-Operator在Kubernetes中快速安裝部署Promethues,具體步驟如下:

1)、安裝Helm

在本次安裝過程中,將使用到Kubernetes的包管理工具Helm。Helm是Kubernetes的一種包管理工具,與Java中的Maven、NodeJs中的Npm以及Ubuntu的apt和CentOS的yum類似。主要用來簡化Kubernetes對應用的部署和管理。

首先從Github下載相應的Helm安裝包,具體命令參考如下:

#找到Github中Helm相關的釋出包,參考連結如下
https://github.com/helm/helm/releases

#確定好相關版本後,將具體安裝版本下載至某個安裝了kubectl的節點 
wget https://get.helm.sh/helm-v3.4.0-rc.1-linux-amd64.tar.gz

解壓,並將下載的可執行Helm檔案拷貝到資料夾/usr/local/bin下,命令如下:

tar -zxvf helm-v3.4.0-rc.1-linux-amd64.tar.gz 
#將下載的可執行helm檔案拷貝到資料夾/usr/local/bin下
mv linux-amd64/helm /usr/local/bin/

之後執行helm version,如果能看到Helm版本資訊,就說明Helm客戶端安裝成功了,具體如下:

$helm version
version.BuildInfo{Version:"v3.4.0-rc.1", 
GitCommit:"7090a89efc8a18f3d8178bf47d2462450349a004", 
GitTreeState:"clean", GoVersion:"go1.14.10"}

安裝完Helm客戶端後,由於一些公共Kubernetes包是在遠端倉庫中管理的,所以還需要新增helm charts(Helm中的Kubernetes安裝包又叫charts)官方倉庫,命令如下:

$helm repo add stable https://charts.helm.sh/stable

檢視本地helm倉庫是否新增成功,命令如下:

$helm repo list
NAME      URL                          
stable    https://charts.helm.sh/stable

此時,檢視Helm倉庫就能看到各種元件的charts列表了,命令效果如下:

$helm search repo stable

NAME                              CHART VERSION   APP VERSION     DESCRIPTION                                       
stable/acs-engine-autoscaler      2.1.3           2.1.1           Scales worker nodes within agent pools            
stable/aerospike 
...

如上所示,此時通過“helm search”命令就可以檢視到各種stable版本的Kubernetes安裝包了!

2)、Helm搜尋Prometheus-Operator安裝包

在具體安裝Prometheus-Operator之前,我們先用“helm”命令搜尋Prometheus相關的charts包,命令如下:

$ helm search repo prometheus

具體搜尋結果如下圖所示:

如上圖所示,我們可以看到Helm倉庫中可以搜尋到版本為0.38.1的“stable/prometheus-operator”的安裝包。接下來就可以通過helm具體安裝了!

3)、Helm安裝Prometheus-Operator監控系統

接下來啊,通過Helm具體安裝prometheus-operator監控系統,命令如下:

#建立k8s名稱空間
kubectl create ns monitoring

#通過helm安裝promethues-operator監控系統
helm install promethues-operator stable/prometheus-operator -n monitoring

執行安裝命令後,輸出結果如下:

WARNING: This chart is deprecated
manifest_sorter.go:192: info: skipping unknown hook: "crd-install"
manifest_sorter.go:192: info: skipping unknown hook: "crd-install"
manifest_sorter.go:192: info: skipping unknown hook: "crd-install"
manifest_sorter.go:192: info: skipping unknown hook: "crd-install"
manifest_sorter.go:192: info: skipping unknown hook: "crd-install"
manifest_sorter.go:192: info: skipping unknown hook: "crd-install"
NAME: promethues-operator
LAST DEPLOYED: Mon Oct 26 10:15:45 2020
NAMESPACE: monitoring
STATUS: deployed
REVISION: 1
NOTES:
*******************
*** DEPRECATED ****
*******************
* stable/prometheus-operator chart is deprecated.
* Further development has moved to https://github.com/prometheus-community/helm-charts
* The chart has been renamed kube-prometheus-stack to more clearly reflect
* that it installs the `kube-prometheus` project stack, within which Prometheus
* Operator is only one component.

The Prometheus Operator has been installed. Check its status by running:
  kubectl --namespace monitoring get pods -l "release=promethues-operator"

Visit https://github.com/coreos/prometheus-operator for instructions on how
to create & configure Alertmanager and Prometheus instances using the Operator.

執行完安裝命令後,檢視具體的Kubernetes Pods資訊,命令如下:

$ kubectl get po -n monitoring

NAME                                                     READY   STATUS    RESTARTS   AGE
alertmanager-promethues-operator-promet-alertmanager-0   2/2     Running   0          5m42s
prometheus-promethues-operator-promet-prometheus-0       3/3     Running   1          5m31s
promethues-operator-grafana-5df74d9cb4-5d475             2/2     Running   0          6m53s
promethues-operator-kube-state-metrics-89d8c459f-449k4   1/1     Running   0          6m53s
promethues-operator-promet-operator-79f8b5f7ff-pfpbl     2/2     Running   0          6m53s
promethues-operator-prometheus-node-exporter-6ll4z       1/1     Running   0          6m53s
promethues-operator-prometheus-node-exporter-bvdb4       1/1     Running   0          6m53s

如上所示,可以看到Prometheus監控系統相關的元件都以Pod的方式執行在了Kubernetes叢集中。

Prometheus監控效果演示

通過前面的實際操作,我們通過Helm的方式已經將Prometheus Operator安裝包部署在了Kubernetes叢集之中。而此時的Prometheus實際上就已經開始發揮作用,並採集了各類Kubernetes的執行指標資訊。可以通過Promethues內建的監控介面對此進行檢視,具體步驟如下:

檢視Kubernetes中檢視內建監控介面所在的Pod節點,命令如下:

kubectl -n monitoring get svc

使用nodeport方式將promethues-operator內建介面服務暴露在叢集外,並指定使用30444埠,命令如下:

kubectl  patch svc promethues-operator-promet-prometheus -n monitoring -p '{"spec":{"type":"NodePort","ports":[{"port":9090,"targetPort":9090,"nodePort":30444}]}}'
service/promethues-operator-promet-prometheus patched

此時在瀏覽器中輸入Pod節點所在的宿主機IP+埠地址,URL示例如下:

http://10.211.55.11:30444/graph

此時就可以看到Promethues內建的監控視覺化介面了,效果如下圖所示:

而如果此時以PromeQL的方式檢視一個具體指標,以“http_requests_total”為例,展示效果如圖所示:

由此說明,此時Promethues監控系統已經開始執行,並採集了相關Metrics指標資料!

Grafana視覺化監控系統

Grafana是一個強大的跨平臺的開源度量分析和視覺化工具,可以將採集的指標資料進行定製化的圖形介面展示,經常被用作為時間序列資料和應用程式分析的視覺化。Grafana支援多種資料來源,如InfluxDB、OpenTSDB、ElasticSearch以及Prometheus。

前面我們在Kubernetes中安裝部署Prometheus-Operator時,實際上Grafana就已經被整合並運行了,可以通過Kubernetes的相關命令查詢Grafana的實際執行Pod,並將其Web埠對外進行暴露,具體如下:

#檢視服務節點資訊
kubectl -n monitoring get svc

#使用nodeport方式將promethues-operator-grafana暴露在叢集外,指定使用30441埠
kubectl  patch svc promethues-operator-grafana -n monitoring -p '{"spec":{"type":"NodePort","ports":[{"port":80,"targetPort":3000,"nodePort":30441}]}}'

需要注意由於Grafana的應用執行的預設埠為80,為避免實驗環境衝突,這裡對映時將目標容器埠指定為3000,並最終將節點埠對映為30441。完成後,瀏覽器輸入URL:

#IP地址為對映命令執行時所在的節點
http://10.211.55.11:30441

如果對映正常,此時會返回Grafana視覺化圖形介面的登入介面,如圖所示:

這裡預設登入賬號密碼為:admin/prom-operator。輸入後可進入Grafana主介面如下圖所示:

可以看到部署完成的Grafana已經預設內建了許多針對Kubernetes平臺的企業級監控Dashboard,例如針對Kubernetes叢集元件的“Kubernetes/API server”、“Kubernetes/Kubelet”,以及針對Kubernetees計算資源的“Kubernetes/Compute Resources/Pod”、“Kubernetes/Compute Resources/Workload”等等。

這裡我們找一個針對Kubernetes物理節點的“Nodes”監控Dashboard,點選開啟後看到的監控效果如下圖所示:

上圖所示的Dashboard中展示了Kubernetes叢集所在的各物理節點CPU、負載、記憶體、磁碟I/O、磁碟空間、網路傳輸等硬體資源的使用情況。從這些豐富的檢視可以看出Grafana強大的監控指標視覺化能力!

後記

本文給大家從理論到實踐簡單介紹了Kubernetes微服務監控體系的構建步驟,希望能夠對大家學習Kubernetes有所幫助。目前以Kubernetes為代表的容器化技術已經成為現代軟體應用釋出的標準方式,作為一名普通研發人員,對Kubernetes的學習將有助於我們更深入的理解整體軟體系統的構建原理,也是我們進階提升必不可少的知識儲備!

寫在最後

歡迎大家關注我的公眾號【風平浪靜如碼】,海量Java相關文章,學習資料都會在裡面更新,整理的資料也會放在裡面。

覺得寫的還不錯的就點個贊,加個關注唄!點關注,不迷路,持續更新!!!