Kubernetes 已經成為事實上的編排平臺的領導者,下一代分散式架構的王者,其在自動化部署、擴展性、以及管理容器化的應用中已經體現出獨特的優勢,在企業中應用落地已經成為一種共識。感謝本次技術內容提供者青雲QingCloud 軟體工程師黃廣喆、霍秉傑

1、背景及介紹

監控系統是整個企業 IT 架構中的重中之重,小到故障排查、問題定位,大到業務預測、運營管理,都離不開穩定可靠的監控系統。在雲原生時代,傳統的監控方案已難以滿足一些監控場景,比如跨主機資源對象的持續數據收集和監控。

為瞭解決這些痛點,Prometheus 項目應運而生。Prometheus 是雲原生領域最受認可的時間序列監控解決方案,在 2016 年加入 CNCF 基金會後,成為繼 K8S 後第二個畢業項目。Prometheus 已經成為雲原生監控領域的事實標準。

相比於傳統的監控,Prometheus 有以下幾個優勢:

  • 高效存儲引擎

Prometheus 把用戶關心的監控場景以時序數據的形式進行採集、存儲和處理到時序資料庫。相比關係資料庫,監控數據存儲在基於時間序列的資料庫內,便於對已有數據進行新的聚合,在高並發的情況下,讀寫性能是遠高過傳統的關係型資料庫的

Prometheus 2.0 版本重構了底層時序存儲引擎。目前,單個 Prometheus 伺服器可以做到每秒存儲百萬條指標數據,同時佔用磁碟空間也很小。(Prometheus 會將所有採集到的樣本數據以時間序列(time-series)的方式保存在內存資料庫中,並且定時保存到硬碟上)

  • 強大的查詢能力:PromQL

Prometheus 有獨立的 PromQL 查詢語言,另外還提供了很多內置的基於時間的處理函數,降低數據聚合的難度。

  • 面向服務的架構

Prometheus 採用拉模型收集時序數據,數據拉取行為是由服務端來決定的。服務端可以通過某種服務發現機制來自動發現監控對象。而對於推模型的監控系統,客戶端需要負責在服務端上進行註冊及監控數據推送,這在微服務架構裏實現起來比較難的。當大量客戶端向服務的主動推送數據時,服務端的壓力較大。

  • 與 K8S 天然集成

K8S 本身的指標也是以 Prometheus 格式暴露出來的。

  • 逐步完善的生態

OpenMetrics:Prometheus 的數據格式逐漸成為一種標準。OpenMetrics 正在從 Prometheus 的數據格式中分離出來,逐漸成為監控數據格式的國際標準

Thanos:支持數據存儲的可伸縮,彌補 Prometheus 數據持久化方面的不足Prometheus

Prometheus Operator:簡化 Prometheus 配置管理

也許我們現在看這些 feature 覺得理所當然,但是當時 Prometheus 發布的時候,是非常吸引人的。

2、Prometheus 的架構

Prometheus 如何工作?我們能用 Prometheus 做些什麼?

首先,用戶編寫客戶端程序,為需要監控的服務生成相應的指標並暴露給 Prometheus 伺服器。Prometheus 通過 HTTP 協議週期性抓取被監控組件的狀態,任意組件只要提供對應 /metrics 介面就可以接入監控。不需要任何其他的集成過程,這樣做非常適合做虛擬化環境監控系統。

對於不適合自己編寫客戶端程序的場景,比如第三方應用監控、物理節點監控、K8S 集羣監控,Prometheus 提供了 exporter 來暴露第三方應用指標,比如 mysql exporter。還有我們使用比較多 node exporter 和 kube-state-metrics exporter,這些都是 Prometheus 官方在維護。

Prometheus 把監控數據存儲在本地的時序資料庫中,缺少數據副本,這是 Prometheus 在數據持久化方面做的不足的地方。這是因為 Prometheus 開發團隊聚焦核心,只開發單節點的 Prometheus。但 Prometheus 也提供 remote_write 的方式,支持將數據存儲到其他時序資料庫中。比較常見的持久化方案有:Cortex、InfluxDB、Thanos

Prometheus 支持通過 Kubernetes、靜態文本、Consul、DNS 等多種服務發現方式來指定抓取目標的監控數據。最後,用戶編寫 PromQL 語句查詢數據並進行可視化。

3、Prometheus+K8S

Prometheus 在 K8S 部署的架構圖

這張圖是我們在 K8S 容器平臺上部署 Prometheus 的架構。左下角 Prometheus 可以從 Kubernetes 集羣的各個組件中採集監控數據,比如 kubelet 中自帶的 cadvisor 提供的容器相關指標數據,API Server 提供 QPS 數據等。

上面兩個 Prometheus 副本提供 HA 的能力,以負載均衡的方式對外提供 API。數據可視化界面和告警模塊會用到Prometheus 提供的監控 API,中間的 Prometheus Operator,提供自動化管理和配置 Prometheus。

我們來看一下 Prometheus 的數據模型:

Prometheus 採用的是時序數據模型 time-series,時序數據是按照時間戳序列存放。每一條時間序列由指標名稱 metric name 和一組標籤 labelset 命名。對於相同的度量名稱,通過不同標籤列表的結合, 會形成特定的度量維度實例。這裡是實時採集 node exporter 指標的一個例子,自增 counter 類型的指標,反應節點各 CPU 不同模式下的運行時間。

總結來說,time-series 中的每一行數據稱為一個 sample ,sample 由以下三部分組成:

  • 指標(metric) :metric name 和描述當前樣本特徵的 labelset

  • 時間戳(timestamp):一個精確到毫秒的時間戳。(截圖中因為獲取的是即時指,沒有列印時間戳)

  • 樣本值(value):一個 float64 的浮點型數據表示當前樣本的值。

Prometheus有四種類型的時序數據,分別是:Counter,只增不減;Gauge,可增可減;Histogram和Summary, 主用用於統計和分析樣本的分佈情況。

Prometheus 有自己特定的查詢語句 PromQL。我們以 node CPU 指標為例,來實現一個複雜的查詢:分節點,CPU 用量的計算。

CPU 用量是 node_cpu_seconds_total 指標數據每秒的增量。

下面這個 PromQL 的 irate 函數表示:3 分鐘內使用模式下,最後兩次採樣點, CPU 的時間增量,除以採樣間隔時間,再用 sum 函數對同一個節點,不同 CPU 進行聚合,可以得到分節點 CPU 用量。

sum by(instance) (irate(node_cpu_seconds_total{job="node-exporter",mode="used"}[3m]))

另外,kube-state-metrics exporter 的指標 kube_pod_info 提供 pod 所在節點信息。我們還可以維度擴展,讓數據以 node id 的形式分類展示

sum by(node) (irate(node_cpu_seconds_total{job="node-exporter",mode="used"}[3m]) * on (pod, namespace) group_left (node) kube_pod_info)

對於有大量 PromQL 經常需要計算的時候可以把PromQL 語句寫成 recording rules。通過合理設置 recording rules 的數量,減少內存、硬碟資源的消耗。

4、Prometheus 配置管理

Prometheus 配置管理是很麻煩的,需要手動。Prometheus 配置分兩種:

  • 不可變的啟動參數

包括最大連接數、數據存儲路徑、數據最大保留時長。對 Prometheus 不可變參數進行升級,我們需要手動移除已經運行的 Pod 實例,從而讓 Kubernetes 可以使用最新的配置文件創建 Prometheus。

  • Prometheus 採集參數配置

包括監控對象的列表、recording rules 等。修改這類配置需要在修改後,手動調用 reload 介面。

對於較少 Prometheus 實例,可以手動修改配置。如果實例的數量更多時,通過手動的方式部署和升級 Prometheus 過程繁瑣並且效率低下。我們可以使用 Prometheus Operator 以聲明式配置的方式實現自動化配置管理。

5、Operator 模式

為了簡化這類應用程序的管理複雜度,K8S 社區引入了 Operator 的概念 。Operator 作為控制器持續的觀察配置信息。每當配置信息修改,Operator 控制器會去和當前配置信息比較。並自動把指定資源更新到對應狀態。

這種方式我們成為聲明式配置,用戶只需要關心應用程序的最終狀態,其它的都通過 Kubernetes 和 Operator 控制器來幫助我們完成,通過這種方式可以大大簡化應用的配置管理複雜度。

Operator 的關鍵是 CRD(即自定義資源),是包含 Prometheus 配置信息的抽象。Prometheus 監控相關的 CRD 有三種:Service Monitor,負責管理監控目標,去定位exporter 。Prometheus 記錄不可變的啟動參數,PrometheusRules 記錄 recording rules 等。

上圖是 Prometheus Operator 官方提供的架構圖,其中 Operator 是最核心的部分,作為一個控制器,它會持續觀察 Prometheus、ServiceMonitor、以及 PrometheusRules 3 個 CRD 資源對象,並維持 Prometheus Server 的狀態。

其中創建的 Prometheus 這個 CRD 是作為 Prometheus Server 存在,而 ServiceMonitor 負責定位 exporter,exporter 前面我們已經學習了,是專門用來提供 metrics 數據介面的 客戶端程序,Prometheus 通過 ServiceMonitor 提供的 監控對象列表去 pull 數據的,這樣我們要在集羣中監控什麼數據,就變成了直接去操作 Kubernetes 集羣的 CRD 資源對象,方便了很多。

我們也在為 Prometheus 開源社區作貢獻。

多租戶監控也是我們在研發中瞭解到的客戶需求。原生 Prometheus HTTP API 沒有體現多租戶。在 KubeSphere? 產品中,我們封裝了一層,把資源按層級下分(如namespace、node、pod、container),通過請求的認證鑒權,區分不同租戶的許可權,限制資源訪問層級。(感興趣的朋友可以訪問 docs.kubesphere.io/adva 進一步瞭解 KubeSphere? 的多租戶架構)

6、總結

總結一些Prometheus優化建議:

  • Drop 掉無用指標:在採集時設置無用指標不採集,以減少計算量和空間用量;
  • query、storage 調參:合理設置 Prometheus 啟動參數、包括最大連接量、數據最大存儲時間等。
  • 多個 Prometheus 實例,分工抓取不同目標;
  • 將經常使用、計算繁瑣的 PromQL 寫成 Recording Rules;
  • 推薦使用 Prometheus Operator 來自動化管理配置信息。

7 月 25 日, 秉承科技前沿與企業實踐並重的 CIC 大會再度來襲,為大家奉上一場科技盛宴。依舊硬核依舊信息過載,乾貨滿滿,絕對讓你不虛此行。長按識別下面二維碼,即刻報名!


推薦閱讀:
相關文章