歡迎光臨
每天分享高質量文章

Prometheus 入門與實踐

隨著容器技術的迅速發展,Kubernetes 已然成為大家追捧的容器叢集管理系統。Prometheus 作為生態圈 Cloud Native Computing Foundation(簡稱:CNCF)中的重要一員,其活躍度僅次於 Kubernetes,現已廣泛用於 Kubernetes 叢集的監控系統中。本文將簡要介紹 Prometheus 的組成和相關概念,並實體演示 Prometheus 的安裝,配置及使用,以便開發人員和雲平臺運維人員可以快速的掌握 Prometheus。
Prometheus 簡介

Prometheus 是一套開源的系統監控報警框架。它啟發於 Google 的 borgmon 監控系統,由工作在 SoundCloud 的 Google 前員工在 2012 年建立,作為社群開源專案進行開發,並於 2015 年正式釋出。2016 年,Prometheus 正式加入 Cloud Native Computing Foundation,成為受歡迎度僅次於 Kubernetes 的專案。
作為新一代的監控框架,Prometheus 具有以下特點:
  • 強大的多維度資料模型:

    • 時間序列資料透過 metric 名和鍵值對來區分。

    • 所有的 metrics 都可以設定任意的多維標簽。

    • 資料模型更隨意,不需要刻意設定為以點分隔的字串。

    • 可以對資料模型進行聚合,切割和切片操作。

    • 支援雙精度浮點型別,標簽可以設為全 unicode。

  • 靈活而強大的查詢陳述句(PromQL):在同一個查詢陳述句,可以對多個 metrics 進行乘法、加法、連線、取分數位等操作。

  • 易於管理: Prometheus server 是一個單獨的二進位制檔案,可直接在本地工作,不依賴於分散式儲存。

  • 高效:平均每個取樣點僅佔 3.5 bytes,且一個 Prometheus server 可以處理數百萬的 metrics。

  • 使用 pull 樣式採集時間序列資料,這樣不僅有利於本機測試而且可以避免有問題的伺服器推送壞的 metrics。

  • 可以採用 push gateway 的方式把時間序列資料推送至 Prometheus server 端。

  • 可以透過服務發現或者靜態配置去獲取監控的 targets。

  • 有多種視覺化圖形介面。

  • 易於伸縮。

需要指出的是,由於資料採集可能會有丟失,所以 Prometheus 不適用對採集資料要 100% 準確的情形。但如果用於記錄時間序列資料,Prometheus 具有很大的查詢優勢,此外,Prometheus 適用於微服務的體系架構。
Prometheus 組成及架構

Prometheus 生態圈中包含了多個元件,其中許多元件是可選的:
  • Prometheus Server:用於收集和儲存時間序列資料。

  • Client Library: 客戶端庫,為需要監控的服務生成相應的 metrics 並暴露給 Prometheus server。當 Prometheus server 來 pull 時,直接傳回實時狀態的 metrics。

  • Push Gateway:主要用於短期的 jobs。由於這類 jobs 存在時間較短,可能在 Prometheus 來 pull 之前就消失了。為此,這次 jobs 可以直接向 Prometheus server 端推送它們的 metrics。這種方式主要用於服務層面的 metrics,對於機器層面的 metrices,需要使用 node exporter。

  • Exporters:用於暴露已有的第三方服務的 metrics 給 Prometheus。

  • Alertmanager:從 Prometheus server 端接收到 alerts 後,會進行去除重覆資料,分組,並路由到對收的接受方式,發出報警。常見的接收方式有:電子郵件,pagerduty,OpsGenie, webhook 等。

    一些其他的工具。

圖 1 為 Prometheus 官方檔案中的架構圖:
圖 1. Prometheus 架構圖
從上圖可以看出,Prometheus 的主要模組包括:Prometheus server,exporters,Pushgateway,PromQL,Alertmanager 以及圖形介面。
其大概的工作流程是:
  1. Prometheus server 定期從配置好的 jobs 或者 exporters 中拉 metrics,或者接收來自 Pushgateway 發過來的 metrics,或者從其他的 Prometheus server 中拉 metrics。

  2. Prometheus server 在本地儲存收集到的 metrics,並執行已定義好的 alert.rules,記錄新的時間序列或者向 Alertmanager 推送警報。

  3. Alertmanager 根據配置檔案,對接收到的警報進行處理,發出告警。

  4. 在圖形介面中,視覺化採集資料。

Prometheus 相關概念

下麵將對 Prometheus 中的資料模型,metric 型別以及 instance 和 job 等概念進行介紹,以便讀者在 Prometheus 的配置和使用中可以有一個更好的理解。
資料模型
Prometheus 中儲存的資料為時間序列,是由 metric 的名字和一系列的標簽(鍵值對)唯一標識的,不同的標簽則代表不同的時間序列。
  • metric 名字:該名字應該具有語意,一般用於表示 metric 的功能,例如:http_requests_total, 表示 http 請求的總數。其中,metric 名字由 ASCII 字元,數字,下劃線,以及冒號組成,且必須滿足正則運算式 [a-zA-Z_:][a-zA-Z0-9_:]*。

  • 標簽:使同一個時間序列有了不同維度的識別。例如 http_requests_total{method=”Get”} 表示所有 http 請求中的 Get 請求。當 method=”post” 時,則為新的一個 metric。標簽中的鍵由 ASCII 字元,數字,以及下劃線組成,且必須滿足正則運算式 [a-zA-Z_:][a-zA-Z0-9_:]*。

  • 樣本:實際的時間序列,每個序列包括一個 float64 的值和一個毫秒級的時間戳。

  • 格式:{=, …},例如:http_requests_total{method=”POST”,endpoint=”/api/tracks”}。


四種 Metric 型別
Prometheus 客戶端庫主要提供四種主要的 metric 型別:

Counter
一種累加的 metric,典型的應用如:請求的個數,結束的任務數, 出現的錯誤數等等。
例如,查詢 http_requests_total{method=”get”, job=”Prometheus”, handler=”query”} 傳回 8,10 秒後,再次查詢,則傳回 14。

Gauge
一種常規的 metric,典型的應用如:溫度,執行的 goroutines 的個數。
可以任意加減。
例如:go_goroutines{instance=”172.17.0.2″, job=”Prometheus”} 傳回值 147,10 秒後傳回 124。

Histogram
可以理解為柱狀圖,典型的應用如:請求持續時間,響應大小。
可以對觀察結果取樣,分組及統計。
例如,查詢 http_request_duration_microseconds_sum{job=”Prometheus”, handler=”query”} 時,傳回結果如下:
圖 2. Histogram metric 傳回結果圖

Summary
  • 類似於 Histogram,典型的應用如:請求持續時間,響應大小。

  • 提供觀測值的 count 和 sum 功能。

  • 提供百分位的功能,即可以按百分比劃分跟蹤結果。

instance 和 jobs
instance:一個單獨 scrape 的標的, 一般對應於一個行程。
jobs:一組同種型別的 instances(主要用於保證可擴充套件性和可靠性),例如:
清單 1. job 和 instance 的關係
jobapi-server

    instance 1: 1.2.3.4:5670
    instance 2: 1.2.3.4:5671
    instance 3: 5.6.7.8:5670
    instance 4: 5.6.7.8:5671

當 scrape 標的時,Prometheus 會自動給這個 scrape 的時間序列附加一些標簽以便更好的分別,例如: instance,job。
下麵以實際的 metric 為例,對上述概念進行說明。
圖 3. Metrics 示例
如上圖所示,這三個 metric 的名字都一樣,他們僅憑 handler 不同而被標識為不同的 metrics。這類 metrics 只會向上累加,是屬於 Counter 型別的 metric,且 metrics 中都含有 instance 和 job 這兩個標簽。
Node exporter 安裝

為了更好的演示 Prometheus 從配置,到監控,到報警的功能,本實體將引入本機 ubuntu server 的監控。由於 Prometheus 主要用於監控 web 服務,如果需要監控 ubuntu server,則需要在本機上安裝 node exporter。 Node exporter 主要用於暴露 metrics 給 Prometheus,其中 metrics 包括:cpu 的負載,記憶體的使用情況,網路等。
安裝 node export 首先需要從 github 中下載最新的 node exporter 包,放在指定的目錄並解壓安裝包,在本實體中,放在 /home/lilly/prom/exporters/ 中。
清單 2. 安裝 Node exporter
cd /home/lilly/prom/exporters/
wget https://github.com/prometheus/node_exporter/releases/download/v0.14.0/node_exporter-0.14.0.linux-amd64.tar.gz
tar -xvzf node_exporter-0.14.0.linux-amd64.tar.gz

為了更好的啟動和停止 node exporter,可以把 node exporter 轉換為一個服務。
清單 3. 配置 node exporter 為服務
vim /etc/init/node_exporter.conf
 #Prometheus Node Exporter Upstart script
 start on startup
 script
 /home/lilly/prom/exporters/node_exporter/node_exporter
 end script

此時,node exporter 已經是一個服務,可以直接用 service 命令進行啟停和檢視。
清單 4. 檢視 node exporter 狀態
root@ubuntu1404-dev:~/alertmanager# service node_exporter start
node_exporter start/running, process 11017
root@ubuntu1404-dev:~/alertmanager# service node_exporter status
node_exporter start/running, process 11017
此時,node exporter 已經監聽在 9100 埠。
root@ubuntu1404-dev:~/prom# netstat -anp | grep 9100
tcp6       0      0 :::9100                 :::*                    LISTEN      155/node_exporter

當 node exporter 啟動時,可以透過 curl http://localhost:9100/metrics 或者在瀏覽器中檢視 ubuntu server 裡面的 metrics,部分 metrics 資訊如下:
清單 5. 驗證 node exporter

root@ubuntu1404-dev:~/prom# curl http://localhost:9100/metrics
……
# HELP node_cpu Seconds the cpus spent in each mode.
# TYPE node_cpu counter
node_cpu{cpu="cpu0",mode="guest"0
node_cpu{cpu="cpu0",mode="idle"30.02
node_cpu{cpu="cpu0",mode="iowait"0.5
node_cpu{cpu="cpu0",mode="irq"0
node_cpu{cpu="cpu0",mode="nice"0
node_cpu{cpu="cpu0",mode="softirq"0.34
node_cpu{cpu="cpu0",mode="steal"0
node_cpu{cpu="cpu0",mode="system"5.38
node_cpu{cpu="cpu0",mode="user"11.34
# HELP node_disk_bytes_read The total number of bytes read successfully.
# TYPE node_disk_bytes_read counter
node_disk_bytes_read{device="sda"5.50009856e+08
node_disk_bytes_read{device="sr0"67584
# HELP node_disk_bytes_written The total number of bytes written successfully.
# TYPE node_disk_bytes_written counter
node_disk_bytes_written{device="sda"2.0160512e+07
node_disk_bytes_written{device="sr0"0
# HELP node_disk_io_now The number of I/Os currently in progress.
# TYPE node_disk_io_now gauge
node_disk_io_now{device="sda"0
node_disk_io_now{device="sr0"0
# HELP node_disk_io_time_ms Total Milliseconds spent doing I/Os.
# TYPE node_disk_io_time_ms counter
node_disk_io_time_ms{device="sda"3484
node_disk_io_time_ms{device="sr0"12
……
# HELP node_memory_MemAvailable Memory information field MemAvailable.
# TYPE node_memory_MemAvailable gauge
node_memory_MemAvailable 1.373270016e+09
# HELP node_memory_MemFree Memory information field MemFree.
# TYPE node_memory_MemFree gauge
node_memory_MemFree 9.2403712e+08
# HELP node_memory_MemTotal Memory information field MemTotal.
# TYPE node_memory_MemTotal gauge
node_memory_MemTotal 2.098388992e+09
……
# HELP node_network_receive_drop Network device statistic receive_drop.
# TYPE node_network_receive_drop gauge
node_network_receive_drop{device="docker0"0
node_network_receive_drop{device="eth0"0
node_network_receive_drop{device="eth1"0
node_network_receive_drop{device="lo"0

Prometheus 安裝和配置

Prometheus 可以採用多種方式安裝,本文直接用官網的 docker image(prom/prometheus)啟動一個 Prometheus server, 並配置相應的靜態監控 targets,jobs 和 alert.rules 檔案。
啟動 Prometheus 容器,並把服務系結在本機的 9090 埠。命令如下:
清單 6. 安裝 Prometheus
docker run -d -p 9090:9090 \
            -v $PWD/prometheus.yml:/etc/prometheus/prometheus.yml \
            -v $PWD/alert.rules:/etc/prometheus/alert.rules \
            --name prometheus \
            prom/prometheus \
            -config.file=/etc/prometheus/prometheus.yml \
            -alertmanager.url=http://10.0.2.15:9093

其中 Prometheus 的配置檔案 prometheus.yml 內容為:
清單 7. Prometheus.yml 配置檔案
global:                  # 全域性設定,可以被改寫
  scrape_interval:     15# 預設值為 15s,用於設定每次資料收集的間隔

  external_labels:   # 所有時間序列和警告與外部通訊時用的外部標簽
    monitor: 'codelab-monitor'

rule_files: # 警告規則設定檔案
  - '/etc/prometheus/alert.rules'

# 用於配置 scrape 的 endpoint  配置需要 scrape 的 targets 以及相應的引數
scrape_configs: 
  # The job name is added as a label `job=` to any timeseries scraped from this config.
  - job_name: 'prometheus'  # 一定要全域性唯一, 採集 Prometheus 自身的 metrics

    # 改寫全域性的 scrape_interval
    scrape_interval: 5s

    static_configs:  # 靜態標的的配置
      - targets: ['172.17.0.2:9090']

  - job_name: 'node'  # 一定要全域性唯一, 採集本機的 metrics,需要在本機安裝 node_exporter

    scrape_interval: 10s

    static_configs:
      - targets: ['10.0.2.15:9100']  # 本機 node_exporter 的 endpoint

alert 規則檔案的內容如下:
清單 8. alert.rules 配置檔案
# Alert for any instance that is unreachable for >5 minutes.
ALERT InstanceDown   # alert 名字
  IF up == 0           # 判斷條件
  FOR 5m             # 條件保持 5m 才會發出 alert
  LABELS { severity = "critical" }  # 設定 alert 的標簽
  ANNOTATIONS {             # alert 的其他標簽,但不用於標識 alert
    summary = "Instance {{ $labels.instance }} down",
    description = "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes.",
  }

當 Prometheus server 起來時,可以在 Prometheus 容器的日誌中看到:
清單 9. Prometheus 日誌
time="2017-09-05T08:18:02Z" level=info msg="Starting prometheus (version=1.7.1, branch=master, 
revision=3afb3fffa3a29c3de865e1172fb740442e9d0133)"
 source="main.go:88" 
time="2017-09-05T08:18:02Z" level=info msg="Build context (go=go1.8.3, user=root@0aa1b7fc430d, date=20170612-
11:44:05)"
 source="main.go:89" 
time="2017-09-05T08:18:02Z" level=info msg="Host details (Linux 3.19.0-75-generic #83~14.04.1-Ubuntu SMP Thu Nov 
10 10:51:40 UTC 2016 x86_64 71984d75e6a1 (none))"
 source="main.go:90" 
time="2017-09-05T08:18:02Z" level=info msg="Loading configuration file /etc/prometheus/prometheus.yml" 
source="main.go:252" 
time="2017-09-05T08:18:03Z" level=info msg="Loading series map and head chunks..." source="storage.go:428" 
time="2017-09-05T08:18:03Z" level=info msg="0 series loaded." source="storage.go:439" 
time="2017-09-05T08:18:03Z" level=info msg="Starting target manager..." source="targetmanager.go:63" 
time="2017-09-05T08:18:03Z" level=info msg="Listening on :9090" source="web.go:259"

在瀏覽器中訪問 Prometheus 的主頁 http://localhost:9091, 可以看到 Prometheus 的資訊如下:
圖 4. Prometheus 狀態資訊
為了保證 Prometheus 確實從 node exporter 中收集資料,可以在 Graph 頁面中搜索 metric 名字,如 node_cpu 並點選 Execute,可以在 console 中看到 metric 如下。
圖 5. Prometheus 中 metric 查詢結果 console 輸出示例
其中第一條為來自 node exporter 的 metric,此時 ubuntu server 上 goroutines 的個數為 13。點選 Graph 可以觀察 metrics 的歷史資料。如下圖所示:
圖 6. Prometheus 中 metric 查詢結果 Graph 輸出示例

Alertmanager 安裝和配置

當接收到 Prometheus 端傳送過來的 alerts 時,Alertmanager 會對 alerts 進行去重覆,分組,路由到對應整合的接受端,包括:slack,電子郵件,pagerduty,hitchat,webhook。
在 Alertmanager 的配置檔案中,需要進行如下配置:
清單 10. Alermanager 中 config.yml 檔案
root@ubuntu1404-dev:~/alertmanager# cat config.yml
global:
    resolve_timeout: 5m
route:
    receiver: 'default-receiver'
    group_wait: 30s
    group_interval: 1m
    repeat_interval: 1m
    group_by: ['alertname']

    routes:
    - match:
        severity: critical
      receiver: my-slack

receivers:
- name: 'my-slack'
  slack_configs:
  - send_resolved: true
    api_url: https://hooks.slack.com/services/***
    channel: '#alertmanager-critical'
    text: "{{ .CommonAnnotations.description }}"


- name: 'default-receiver'
  slack_configs:
  - send_resolved: true
    api_url: https://hooks.slack.com/services/***
    channel: '#alertmanager-default'
    text: "{{ .CommonAnnotations.description }}"

建立好 config.yml 檔案後,可以直接用 Docker 啟動一個 Alertmanager 的容器,如下:
清單 11. 安裝 Alertmanager
docker run -d -p 9093:9093 
                 –v /home/lilly/alertmanager/config.yml:/etc/alertmanager/config.yml \
                 --name alertmanager \
                 prom/alertmanager

docker ps | grep alert
d1b7a753a688        prom/alertmanager   "/bin/alertmanager -c"   25 hours ago        Up 25 hours         
0.0.0.0:9093->9093/tcp   alertmanager

當 Alertmanager 服務起來時,可以透過瀏覽器訪 Alertmanager 的主頁 http://localhost:9093,其狀態資訊如下:
圖 7. Alertmanager 狀態資訊
在 alerts 的頁面中,我們可以看到從 Prometheus sever 端發過來的 alerts,此外,還可以做 alerts 搜尋,分組,靜音等操作。
圖 8. Alertmanager 報警頁面
Prometheus 實體演示

下麵將透過一個具體的實體來演示 Prometheus 的使用。在 alert.ruels 中定義了 alert 觸發的條件是 up 為 0。下麵,手動停止 node exporter 服務。
清單 12. 停止 node exporter 服務
root@ubuntu1404-dev:~/prom# service node_exporter stop
node_exporter stop/waiting
root@ubuntu1404-dev:~/prom# service node_exporter status
node_exporter stop/waiting

此時,Prometheus 中查詢 metric up,可以看到此時 up{instance=”10.0.2.15″,job=”node”} 的值為 0,如下所示:
圖 9. Metric up 的傳回值(停)
此時,Alerts 頁面中顯示 InstanceDown,狀態為 PENDING。因為 alert 規則中定義需要保持 5 分鐘,所以在這之前,alerts 還沒有傳送至 Alertmanager。
圖 10. Alert Pending 介面
5 分鐘後,狀態由 PENDING 變為 FIRING,於此同時,在 Alertmanager 中可以看到有一個 alert。
圖 11. Alert Firing 介面
圖 12. Alertmanager 警報介面
在 Alertmanager 的配置檔案中定義,當 severity 為 critical 的時候,往 Alertmanager-critical channel 中傳送警告,且每隔兩分鐘重覆傳送。如下圖所示。
圖 13. Slack 告警介面
由上可知,當標的失敗時,不僅可以在 Prometheus 的主頁上實時的檢視標的和 alerts 的狀態,還可以使用 Alertmanager 傳送警告,以便運維人員儘快解決問題。
當問題解決後,Prometheus 不僅會實時更新 metrics 的狀態,Alertmanager 也會在 slack 通知 resolved 的訊息。以下演示問題解決後的,Prometheus 的操作。
手動啟動 node exporter。首先 metric 在 Graph 中恢復至正常值 1。
圖 14. Metric up 的傳回值(啟)
targets 中現實 node 這個 job 是 up 的狀態。
圖 15. Targets 介面
Alerts 為綠色,顯示有 0 個啟用態的警告。
圖 16. Alers resolved 介面
而在 Alertmanager 剛剛的 alert 也被清空,顯示 No alerts found。
圖 17. Alertmanager resolved 介面
在 slack 端,在多次紅色 FRING 報警後,也收到了綠色了 RESOLVED 訊息。
圖 18. Slack resolved 介面

總結

本文對 Prometheus 的組成,架構和基本概念進行了介紹,並實體演示了 node exporter,Prometheus 和 Alermanager 的配置和執行。最後,以一個監控的 target 的啟停為例,演示 Prometheus 的一系列響應以及如何在 Prometheus 和 Alertmanager 中檢視服務,警報和告警的狀態。對於 Prometheus 中更高階的使用,如查詢函式的使用,更多圖形介面的整合,請參考官方檔案。
原文連結:https://www.ibm.com/developerworks/cn/cloud/library/cl-lo-prometheus-getting-started-and-practice

Kubernetes實戰培訓

Kubernetes應用實戰培訓將於2018年10月12日在深圳開課,3天時間帶你係統學習Kubernetes本次培訓包括:容器基礎、Docker基礎、Docker進階、Kubernetes架構及部署、Kubernetes常用物件、Kubernetes網路、儲存、服務發現、Kubernetes的排程和服務質量保證、監控和日誌、Helm、專案實踐等,點選下方圖片檢視詳情。

贊(0)

分享創造快樂