Prometheus 監控系統入門與實踐

原文地址:https://www.ibm.com/developerworks/cn/cloud/library/cl-lo-prometheus-getting-started-and-practice/index.html 

吳 莉, 殷 一鳴, 和 蔡 林     2018 年 5 月 30 日發佈

隨着容器技術的迅速發展,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 具有以下特點:

  • 強大的多維度數據模型:
    1. 時間序列數據通過 metric 名和鍵值對來區分。
    2. 所有的 metrics 都可以設置任意的多維標籤。
    3. 數據模型更隨意,不需要刻意設置爲以點分隔的字符串。
    4. 可以對數據模型進行聚合,切割和切片操作。
    5. 支持雙精度浮點類型,標籤可以設爲全 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 的值和一個毫秒級的時間戳。
  • 格式:<metric name>{<label name>=<label value>, …},例如: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 的關係

1

2

3

4

5

6

job: api-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

1

2

3

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 爲服務

1

2

3

4

5

6

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 狀態

1

2

3

4

5

6

7

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

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

1

2

3

4

5

6

7

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 配置文件

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

global:                  # 全局設置,可以被覆蓋

  scrape_interval:     15s # 默認值爲 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=<job_name>` 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 配置文件

1

2

3

4

5

6

7

8

9

# 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 日誌

1

2

3

4

5

6

7

8

9

10

11

12

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 文件

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

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

1

2

3

4

5

6

7

8

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 服務

1

2

3

4

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 中更高級的使用,如查詢函數的使用,更多圖形界面的集成,請參考官方文檔。

參考資源

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章