1. 程式人生 > >從零開始入門 K8s | 可觀測性:監控與日誌

從零開始入門 K8s | 可觀測性:監控與日誌

作者 | 莫源  阿里巴巴技術專家

一、背景

監控和日誌是大型分散式系統的重要基礎設施,監控可以幫助開發者檢視系統的執行狀態,而日誌可以協助問題的排查和診斷。

在 Kubernetes 中,監控和日誌屬於生態的一部分,它並不是核心元件,因此大部分的能力依賴上層的雲廠商的適配。Kubernetes 定義了介入的介面標準和規範,任何符合介面標準的元件都可以快速整合。

二、監控

監控型別

先看一下監控,從監控型別上劃分,在 K8s 中可以分成四個不同的型別:

1.資源監控

比較常見的像 CPU、記憶體、網路這種資源類的一個指標,通常這些指標會以數值、百分比的單位進行統計,是最常見的一個監控方式。這種監控方式在常規的監控裡面,類似專案 zabbix telegraph,這些系統都是可以做到的。

2.效能監控

效能監控指的就是 APM 監控,也就是說常見的一些應用效能類的監控指標的檢查。通常是通過一些 Hook 的機制在虛擬機器層、位元組碼執行層通過隱式呼叫,或者是在應用層顯示注入,獲取更深層次的一個監控指標,一般是用來應用的調優和診斷的。比較常見的類似像 jvm 或者 php 的 Zend Engine,通過一些常見的 Hook 機制,拿到類似像 jvm 裡面的 GC 的次數,各種記憶體代的一個分佈以及網路連線數的一些指標,通過這種方式來進行應用的效能診斷和調優。

3.安全監控

安全監控主要是對安全進行的一系列的監控策略,類似像越權管理、安全漏洞掃描等等。

4.事件監控

事件監控是 K8s 中比較另類的一種監控方式。之前的文章為大家介紹了在 K8s 中的一個設計理念,就是基於狀態機的一個狀態轉換。從正常的狀態轉換成另一個正常的狀態的時候,會發生一個 normal 的事件,而從一個正常狀態轉換成一個異常狀態的時候,會發生一個 warning 的事件。通常情況下,warning 的事件是我們比較關心的,而事件監控就是可以把 normal 的事件或者是 warning 事件離線到一個數據中心,然後通過資料中心的分析以及報警,把相應的一些異常通過像釘釘或者是簡訊、郵件的方式進行暴露,彌補常規監控的一些缺陷和弊端。

Kubernetes 的監控演進

在早期,也就是 1.10 以前的 K8s 版本。大家都會使用類似像 Heapster 這樣的元件來去進行監控的採集,Heapster 的設計原理其實也比較簡單。

首先,我們在每一個 Kubernetes 上面有一個包裹好的 cadvisor,這個 cadvisor 是負責資料採集的元件。當 cadvisor 把資料採集完成,Kubernetes 會把 cadvisor 採集到的資料進行包裹,暴露成相應的 API。在早期的時候,實際上是有三種不同的 API:

  • 第一種是 summary 介面;
  • 第二種是 kubelet 介面;
  • 第三種是 Prometheus 介面。

這三種介面,其實對應的資料來源都是 cadvisor,只是資料格式有所不同。而在 Heapster 裡面,其實支援了 summary 介面和 kubelet 兩種資料採集介面,Heapster 會定期去每一個節點拉取資料,在自己的記憶體裡面進行聚合,然後再暴露相應的 service,供上層的消費者進行使用。在 K8s 中比較常見的消費者,類似像 dashboard,或者是 HPA-Controller,它通過呼叫 service 獲取相應的監控資料,來實現相應的彈性伸縮,以及監控資料的一個展示。
 
這個是以前的一個數據消費鏈路,這條消費鏈路看上去很清晰,也沒有太多的一個問題,那為什麼 Kubernetes 會將 Heapster 放棄掉而轉換到 metrics-service 呢?其實這個主要的一個動力來源是由於 Heapster 在做監控資料介面的標準化。為什麼要做監控資料介面標準化呢?
 

  • 第一點在於客戶的需求是千變萬化的,比如說今天用 Heapster 進行了基礎資料的一個資源採集,那明天的時候,我想在應用裡面暴露線上人數的一個數據介面,放到自己的介面系統裡進行資料的一個展現,以及類似像 HPA 的一個數據消費。那這個場景在 Heapster 下能不能做呢?答案是不可以的,所以這就是 Heapster 自身擴充套件性的弊端;

 

  • 第二點是 Heapster 裡面為了保證資料的離線能力,提供了很多的 sink,而這個 sink 包含了類似像 influxdb、sls、釘釘等等一系列 sink。這個 sink 主要做的是把資料採集下來,並且把這個資料離線走,然後很多客戶會用 influxdb 做這個資料離線,在 influxdb 上去接入類似像 grafana 監控資料的一個視覺化的軟體,來實踐監控資料的視覺化。

但是後來社群發現,這些 sink 很多時候都是沒有人來維護的。這也導致整個 Heapster 的專案有很多的 bug,這個 bug 一直存留在社群裡面,是沒有人修復的,這個也是會給社群的專案的活躍度包括專案的穩定性帶來了很多的挑戰。

基於這兩點原因,K8s 把 Heapster 進行了 break 掉,然後做了一個精簡版的監控採集元件,叫做 metrics-server。

上圖是 Heapster 內部的一個架構。大家可以發現它分為幾個部分,第一個部分是 core 部分,然後上層是有一個通過標準的 http 或者 https 暴露的這個 API。然後中間是 source 的部分,source 部分相當於是採集資料暴露的不同的介面,然後 processor 的部分是進行資料轉換以及資料聚合的部分。最後是 sink 部分,sink 部分是負責資料離線的,這個是早期的 Heapster 的一個應用的架構。那到後期的時候呢,K8s 做了這個監控介面的一個標準化,逐漸就把 Heapster 進行了裁剪,轉化成了 metrics-server。

目前 0.3.1 版本的 metrics-server 大致的一個結構就變成了上圖這樣,是非常簡單的:有一個 core 層、中間的 source 層,以及簡單的 API 層,額外增加了 API Registration 這層。這層的作用就是它可以把相應的資料介面註冊到 K8s 的 API server 之上,以後客戶不再需要通過這個 API 層去訪問 metrics-server,而是可以通過這個 API 註冊層,通過 API server 訪問 API 註冊層,再到 metrics-server。這樣的話,真正的資料消費方可能感知到的並不是一個 metrics-server,而是說感知到的是實現了這樣一個 API 的具體的實現,而這個實現是 metrics-server。這個就是 metrics-server 改動最大的一個地方。

Kubernetes 的監控介面標準

在 K8s 裡面針對於監控,有三種不同的介面標準。它將監控的資料消費能力進行了標準化和解耦,實現了一個與社群的融合,社群裡面主要分為三類。

第一類 Resource Metrice

對應的介面是 metrics.k8s.io,主要的實現就是 metrics-server,它提供的是資源的監控,比較常見的是節點級別、pod 級別、namespace 級別、class 級別。這類的監控指標都可以通過 metrics.k8s.io 這個介面獲取到。

第二類 Custom Metrics

對應的 API 是 custom.metrics.k8s.io,主要的實現是 Prometheus。它提供的是資源監控和自定義監控,資源監控和上面的資源監控其實是有覆蓋關係的,而這個自定義監控指的是:比如應用上面想暴露一個類似像線上人數,或者說呼叫後面的這個資料庫的 MySQL 的慢查詢。這些其實都是可以在應用層做自己的定義的,然後並通過標準的 Prometheus 的 client,暴露出相應的 metrics,然後再被 Prometheus 進行採集。

而這類的介面一旦採集上來也是可以通過類似像 custom.metrics.k8s.io 這樣一個介面的標準來進行資料消費的,也就是說現在如果以這種方式接入的 Prometheus,那你就可以通過 custom.metrics.k8s.io 這個介面來進行 HPA,進行資料消費。

第三類 External Metrics

External Metrics 其實是比較特殊的一類,因為我們知道 K8s 現在已經成為了雲原生介面的一個實現標準。很多時候在雲上打交道的是雲服務,比如說在一個應用裡面用到了前面的是訊息佇列,後面的是 RBS 資料庫。那有時在進行資料消費的時候,同時需要去消費一些雲產品的監控指標,類似像訊息佇列中訊息的數目,或者是接入層 SLB 的 connection 數目,SLB 上層的 200 個請求數目等等,這些監控指標。

那怎麼去消費呢?也是在 K8s 裡面實現了一個標準,就是 external.metrics.k8s.io。主要的實現廠商就是各個雲廠商的 provider,通過這個 provider 可以通過雲資源的監控指標。在阿里雲上面也實現了阿里巴巴 cloud metrics adapter 用來提供這個標準的 external.metrics.k8s.io 的一個實現。

Promethues - 開源社群的監控“標準”

接下來我們來看一個比較常見的開源社群裡面的監控方案,就是 Prometheus。Prometheus 為什麼說是開源社群的監控標準呢?

  • 一是因為首先 Prometheus 是 CNCF 雲原生社群的一個畢業專案。然後第二個是現在有越來越多的開源專案都以 Prometheus 作為監控標準,類似說我們比較常見的 Spark、Tensorflow、Flink 這些專案,其實它都有標準的 Prometheus 的採集介面。

 

  • 第二個是對於類似像比較常見的一些資料庫、中介軟體這類的專案,它都有相應的 Prometheus 採集客戶端。類似像 ETCD、zookeeper、MySQL 或者說 PostgreSQL,這些其實都有相應的這個 Prometheus 的介面,如果沒有的,社群裡面也會有相應的 exporter 進行介面的一個實現。

那我們先來看一下 Prometheus 整個的大致一個結構。

上圖是 Prometheus 採集的資料鏈路,它主要可以分為三種不同的資料採集鏈路。

  • 第一種,是這個 push 的方式,就是通過 pushgateway 進行資料採集,然後資料線到 pushgateway,然後 Prometheus 再通過 pull 的方式去 pushgateway 去拉資料。這種採集方式主要應對的場景就是你的這個任務可能是比較短暫的,比如說我們知道 Prometheus,最常見的採集方式是拉模式,那帶來一個問題就是,一旦你的資料宣告週期短於資料的採集週期,比如我採集週期是 30s,而我這個任務可能執行 15s 就完了。這種場景之下,可能會造成有些資料漏採。對於這種場景最簡單的一個做法就是先通過 pushgateway,先把你的 metrics push下來,然後再通過 pull 的方式從 pushgateway 去拉資料,通過這種方式可以做到,短時間的不丟作業任務。

 

  • 第二種是標準的 pull 模式,它是直接通過拉模式去對應的資料的任務上面去拉取資料。

 

  • 第三種是 Prometheus on Prometheus,就是可以通過另一個 Prometheus 來去同步資料到這個 Prometheus。

這是三種 Prometheus 中的採集方式。那從資料來源上面,除了標準的靜態配置,Prometheus 也支援 service discovery。也就是說可以通過一些服務發現的機制,動態地去發現一些採集物件。在 K8s 裡面比較常見的是可以有 Kubernetes 的這種動態發現機制,只需要配置一些 annotation,它就可以自動地來配置採集任務來進行資料採集,是非常方便的。

etheus 提供了一個外接元件叫 Alentmanager,它可以將相應的報警資訊通過郵件或者簡訊的方式進行資料的一個告警。在資料消費上面,可以通過上層的 API clients,可以通過 web UI,可以通過 Grafana 進行資料的展現和資料的消費。

總結起來 Prometheus 有如下五個特點:

  • 第一個特點就是簡介強大的接入標準,開發者只需要實現 Prometheus Client 這樣一個介面標準,就可以直接實現資料的一個採集;
  • 第二種就是多種的資料採集、離線的方式。可以通過 push 的方式、 pull 的方式、Prometheus on Prometheus的方式來進行資料的採集和離線;
  • 第三種就是和 K8s 的相容;
  • 第四種就是豐富的外掛機制與生態;
  • 第五個是 Prometheus Operator 的一個助力,Prometheus Operator 可能是目前我們見到的所有 Operator 裡面做的最複雜的,但是它裡面也是把 Prometheus 這種動態能力做到淋漓盡致的一個 Operator,如果在 K8s 裡面使用 Prometheus,比較推薦大家使用 Prometheus Operator 的方式來去進行部署和運維。

kube-eventer - Kubernetes 事件離線工具

最後,我們給大家介紹一個 K8s 中的事件離線工具叫做 kube-eventer。kube-eventer 是阿里雲容器服務開源出的一個元件,它可以將 K8s 裡面,類似像 pod eventer、node eventer、核心元件的 eventer、crd 的 eventer 等等一系列的 eventer,通過 API sever 的這個 watch 機制離線到類似像 SLS、Dingtalk、kafka、InfluxDB,然後通過這種離線的機制進行一個時間的審計、監控和告警,我們現在已經把這個專案開源到 GitHub 上了,大家有興趣的話可以來看一下這個專案。

那上面這張圖其實就是 Dingtalk 的一個報警圖。可以看見裡面有一個 warning 的事件,這個事件是在 kube-system namespace 之下,具體的這個 pod,大致的一個原因是這個 pod 重啟失敗了,然後大致 reason 就是 backoff,然後具體發生事件是什麼時間。可以通過這個資訊來做到一個 Checkups。

三、日誌

日誌的場景

接下來給大家來介紹一下在 K8s 裡面日誌的一個部分。首先我們來看一下日誌的場景,日誌在 K8s 裡面主要分為四個大的場景:

1. 主機核心的日誌

  • 第一個是主機核心的日誌,主機核心日誌可以協助開發者進行一些常見的問題與診斷,比如說網棧的異常,類似像我們的 iptables mark,它可以看到有 controller table 這樣的一些 message;

 

  • 第二個是驅動異常,比較常見的是一些網路方案裡面有的時候可能會出現驅動異常,或者說是類似 GPU 的一些場景,驅動異常可能是比較常見的一些錯誤;

 

  • 第三個就是檔案系統異常,在早期 docker 還不是很成熟的場景之下,overlayfs 或者是 AUFS,實際上是會經常出現問題的。在這些出現問題後,開發者是沒有太好的辦法來去進行監控和診斷的。這一部分,其實是可以主機核心日誌裡面來檢視到一些異常;

 

  • 再往下是影響節點的一些異常,比如說核心裡面的一些 kernel panic,或者是一些 OOM,這些也會在主機日誌裡面有相應的一些反映。

 

2. Runtime 的日誌

第二個是 runtime 的日誌,比較常見的是 Docker 的一些日誌,我們可以通過 docker 的日誌來排查類似像刪除一些 Pod Hang 這一系列的問題。

3. 核心元件的日誌

第三個是核心元件的日誌,在 K8s 裡面核心元件包含了類似像一些外接的中介軟體,類似像 etcd,或者像一些內建的元件,類似像 API server、kube-scheduler、controller-manger、kubelet 等等這一系列的元件。而這些元件的日誌可以幫我們來看到整個 K8s 叢集裡面管控面的一個資源的使用量,然後以及目前執行的一個狀態是否有一些異常。

還有的就是類似像一些核心的中介軟體,如 Ingress 這種網路中介軟體,它可以幫我們來看到整個的一個接入層的一個流量,通過 Ingress 的日誌,可以做到一個很好的接入層的一個應用分析。

4. 部署應用的日誌

最後是部署應用的日誌,可以通過應用的日誌來檢視業務層的一個狀態。比如說可以看業務層有沒有 500 的請求?有沒有一些 panic?有沒有一些異常的錯誤的訪問?那這些其實都可以通過應用日誌來進行檢視的。

日誌的採集

首先我們來看一下日誌採集,從採集位置是哪個劃分,需要支援如下三種:

  • 首先是宿主機檔案,這種場景比較常見的是說我的這個容器裡面,通過類似像 volume,把日誌檔案寫到了宿主機之上。通過宿主機的日誌輪轉的策略進行日誌的輪轉,然後再通過我的宿主機上的這個 agent 進行採集;

  • 第二種是容器內有日誌檔案,那這種常見方式怎麼處理呢,比較常見的一個方式是說我通過一個 Sidecar 的 streaming 的 container,轉寫到 stdout,通過 stdout 寫到相應的 log-file,然後再通過本地的一個日誌輪轉,然後以及外部的一個 agent 採集;

 

  • 第三種我們直接寫到 stdout,這種比較常見的一個策略,第一種就是直接我拿這個 agent 去採集到遠端,第二種我直接通過類似像一些 sls 的標準 API 採集到遠端。

那社群裡面其實比較推薦的是使用 Fluentd 的一個採集方案,Fluentd 是在每一個節點上面都會起相應的 agent,然後這個 agent 會把資料彙集到一個 Fluentd 的一個 server,這個 server 裡面可以將資料離線到相應的類似像 elasticsearch,然後再通過 kibana 做展現;或者是離線到 influxdb,然後通過 Grafana 做展現。這個其實是社群裡目前比較推薦的一個做法。

四、總結

最後給大家做一下今天課程的總結,以及給大家介紹一下在阿里雲上面監控和日誌的最佳實踐。在課程開始的時候,給大家介紹了監控和日誌並不屬於 K8s 裡面的核心元件,而大部分是定義了一個標準的一個介面方式,然後通過上層的這個雲廠商進行各自的一個適配。

阿里雲容器服務監控體系

監控體系元件介紹

首先,我先給大家來介紹一下在阿里雲容器服務裡面的監控體系,這張圖實際上是監控的一個大圖。

右側的四個產品是和監控日誌相關比較緊密的四個產品:

sls

第一個是 SLS,就是日誌服務,那剛才我們已經提到了在 K8s 裡面日誌分為很多種不同的採集,比如說有核心元件的日誌、接入層的日誌、還有應用的日誌等等。在阿里雲容器服務裡面,可以通過 API server 採集到審計的日誌,然後可以通過類似像 service mesh 或者 ingress controller 採集到接入層的日誌,然後以及相應的應用層採集到應用的日誌。

有了這條資料鏈路之後,其實還不夠。因為資料鏈路只是幫我們做到了一個數據的離線,我們還需要做上層的資料的展現和分析。比如說像審計,可以通過審計日誌來看到今天有多少操作、有多少變更、有沒有攻擊、系統有沒有異常。這些都可以通過審計的 Dashboard 來檢視。

ARMS

第二個就是應用的一個性能監控。效能監控上面,可以通過這個 ARMS 這樣的產品來去進行檢視。ARMS 目前支援的 JAVA、PHP 兩種語言,可以通過 ARMS 來做應用的一個性能診斷和問題的一個調優。

AHAS

第三個是比較特殊的叫 AHAS。AHAS 是一個架構感知的監控,我們知道在 K8s 裡面,很多時候都是通過一些微服的架構進行部署的。微服帶來的問題就是元件會變的非常多,元件的副本處也會變的很多。這會帶來一個在拓撲管理上面的一個複雜性。

如果我們想要看一個應用在 K8s 中流量的一個走向,或者是針對流量異常的一個排查,其實沒有一個很好的視覺化是很複雜的。AHAS 的一個作用就是通過網路棧的一個監控,可以繪製出整個 K8s 中應用的一個拓撲關係,然後以及相應的資源監控和網路的頻寬監控、流量的監控,以及異常事件的一個診斷。任何如果有架構拓撲感知的一個層面,來實現另一種的監控解決方案。

Cloud Monitor

最後是 Cloud Monitor,也就是基礎的雲監控。它可以採集標準的 Resource Metrics Monitoring,來進行監控資料的一個展現,可以實現 node、pod 等等監控指標的一個展現和告警。

阿里雲增強的功能

這一部分是阿里雲在開源上做的增強。首先是 metrics-server,文章開始提到了 metrics-server 做了很多的一個精簡。但是從客戶的角度來講,這個精簡實際上是把一些功能做了一個裁剪,這將會帶來很多不便。比如說有很多客戶希望將監控資料離線到類似像 SLS 或者是 influxdb,這種能力實際上用社群的版本是沒有辦法繼續來做的,這個地方阿里雲繼續保留了常見的維護率比較高的 sink,這是第一個增強。

然後是第二個增強,因為在 K8s 裡面整合的一個生態的發展並不是以同樣的節奏進行演進的。比如說 Dashboard 的釋出,並不是和 K8s 的大版本進行匹配的。比如 K8s 發了 1.12,Dashboard 並不會也發 1.12 的版本,而是說它會根據自己的節奏來去釋出,這樣會造成一個結果就是說以前依賴於 Heapster 的很多的元件在升級到 metrics-server 之後就直接 break 掉,阿里雲在 metrics-server 上面做了完整的 Heapster 相容,也就是說從目前 K8s 1.7 版本一直到 K8s 1.14 版本,都可以使用阿里雲的 metrics-server,來做到完整的監控元件的消費的一個相容。

還有就是 eventer 和 npd,上面提到了 kube-eventer 這個元件。然後在 npd 上面,我們也做了很多額外的增強,類似像增加了很多監控和檢測項,類似像 kernel Hang、npd 的一個檢測、出入網的監控、snat 的一個檢測。然後還有類似像 fd 的 check,這些其實都是在 npd 裡面的一些監控項,阿里雲做了很多的增強。然後開發者可以直接部署 npd 的一個 check,就可以實現節點診斷的一個告警,然後並通過 eventer 離線上的 kafka 或者是 Dingtalk。

再往上是 Prometheus 生態,Prometheus 生態裡面,在儲存層可以讓開發者對接,阿里雲的 HiTSDB 以及 InfluxDB,然後在採集層提供了優化的 node-exporter,以及一些場景化監控的 exporter,類似像 Spark、TensorFlow、Argo 這類場景化的 exporter。還有就是針對於 GPU,阿里雲做了很多額外的增強,類似於像支援 GPU 的單卡監控以及 GPU share 的監控,然後在 Prometheus 上面,我們連同 ARMS 團隊推出了託管版的 Prometheus,開發者可以使用開箱即用的 helm chats,不需要部署 Prometheus server,就可以直接體驗到 Prometheus 的一個監控採集能力。

阿里雲容器服務日誌體系

在日誌上面,阿里雲做了哪些增強呢?首先是採集方式上,做到了完整的一個相容。可以採集 pod log 日誌、核心元件日誌、docker engine 日誌、kernel 日誌,以及類似像一些中介軟體的日誌,都收集到 SLS。收集到 SLS 之後,我們可以通過資料離線到 OSS,離線到 Max Compute,做一個數據的離線和歸檔,以及離線預算。

然後還有是對於一些資料的實時消費,我們可以到 Opensearch、可以到 E-Map、可以到 Flink,來做到一個日誌的搜尋和上層的一個消費。在日誌展現上面,我們可以既對接開源的 Grafana,也可以對接類似像 DataV,去做資料展示,實現一個完整的資料鏈路的採集和消費。

本文總結

  • 首先主要為大家介紹了監控,其中包括:四種容器場景下的常見的監控方式;Kubernetes 的監控演進和介面標準;兩種常用的來源的監控方案;
  • 在日誌上我們主要介紹了四種不同的場景,介紹了 Fluentd 的一個採集方案;
  • 最後向大家介紹了一下阿里雲日誌和監控的一個最佳實踐。

“ 阿里巴巴雲原生微信公眾號(ID:Alicloudnative)關注微服務、Serverless、容器、Service Mesh等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,做最懂雲原生開發者的技術公眾號。”

本文由部落格一文多發平臺 OpenWrite 釋出!