隨着容器技術的迅速發展,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 等。
- 一些其他的工具。
從上圖可以看出,Prometheus 的主要模塊包括:Prometheus server, exporters, Pushgateway, PromQL, Alertmanager 以及圖形界面。
其大概的工作流程是:
- Prometheus server 定期從配置好的 jobs 或者 exporters 中拉 metrics,或者接收來自 Pushgateway 發過來的 metrics,或者從其他的 Prometheus server 中拉 metrics。
- Prometheus server 在本地存儲收集到的 metrics,並運行已定義好的 alert.rules,記錄新的時間序列或者向 Alertmanager 推送警報。
- Alertmanager 根據配置文件,對接收到的警報進行處理,發出告警。
- 在圖形界面中,可視化採集數據。
Prometheus 相關概念
下面將對 Prometheus 中的數據模型,metric 類型以及 instance 和 job 等概念進行介紹,以便讀者在 Prometheus 的配置和使用中可以有一個更好的理解。
數據模型
Prometheus 中存儲的數據爲時間序列,是由 metric 的名字和一系列的標籤(鍵值對)唯一標識的,不同的標籤則代表不同的時間序列。
- metric 名字:該名字應該具有語義,一般用於表示 metric 的功能,例如:http_requeststotal, 表示 http 請求的總數。其中,metric 名字由 ASCII 字符,數字,下劃線,以及冒號組成,且必須滿足正則表達式 [a-zA-Z:][a-zA-Z0-9_:]*。
- 標籤:使同一個時間序列有了不同維度的識別。例如 http_requeststotal{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"} 時,返回結果如下:
Summary
- 類似於 Histogram, 典型的應用如:請求持續時間,響應大小。
- 提供觀測值的 count 和 sum 功能。
- 提供百分位的功能,即可以按百分比劃分跟蹤結果。
instance 和 jobs
instance: 一個單獨 scrape 的目標, 一般對應於一個進程。
jobs: 一組同種類型的 instances(主要用於保證可擴展性和可靠性),例如:
清單 1. job 和 instance 的關係
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 爲例,對上述概念進行說明。
如上圖所示,這三個 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: 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 配置文件
# 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 的信息如下:
爲了保證 Prometheus 確實從 node exporter 中收集數據,可以在 Graph 頁面中搜索 metric 名字,如 node_cpu 並點擊 Execute,可以在 console 中看到 metric 如下。
其中第一條爲來自 node exporter 的 metric,此時 ubuntu server 上 goroutines 的個數爲 13。點擊 Graph 可以觀察 metrics 的歷史數據。如下圖所示:
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,其狀態信息如下:
在 alerts 的頁面中,我們可以看到從 Prometheus sever 端發過來的 alerts,此外,還可以做 alerts 搜索,分組,靜音等操作。
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,如下所示:
此時,Alerts 頁面中顯示 InstanceDown,狀態爲 PENDING。因爲 alert 規則中定義需要保持 5 分鐘,所以在這之前,alerts 還沒有發送至 Alertmanager。
5 分鐘後,狀態由 PENDING 變爲 FIRING,於此同時,在 Alertmanager 中可以看到有一個 alert。
在 Alertmanager 的配置文件中定義,黨 severity 爲 critical 的時候,往 Alertmanager-critical channel 中發送警告,且每隔兩分鐘重複發送。如下圖所示。
由上可知,當目標失敗時,不僅可以在 Prometheus 的主頁上實時的查看目標和 alerts 的狀態,還可以使用 Alertmanager 發送警告,以便運維人員儘快解決問題。
當問題解決後,Prometheus 不僅會實時更新 metrics 的狀態,Alertmanager 也會在 slack 通知 resolved 的消息。以下演示問題解決後的,Prometheus 的操作。
手動啓動 node exporter。首先 metric 在 Graph 中恢復至正常值 1。
targets 中現實 node 這個 job 是 up 的狀態。
Alerts 爲綠色,顯示有 0 個激活態的警告。
而在 Alertmanager 剛剛的 alert 也被清空,顯示 No alerts found。
在 slack 端,在多次紅色 FRING 報警後,也收到了綠色了 RESOLVED 消息。
總結
本文對 Prometheus 的組成,架構和基本概念進行了介紹,並實例演示了 node exporter, Prometheus 和 Alermanager 的配置和運行。最後,以一個監控的 target 的啓停爲例,演示 Prometheus 的一系列響應以及如何在 Prometheus 和 Alertmanager 中查看服務,警報和告警的狀態。對於 Prometheus 中更高級的使用,如查詢函數的使用,更多圖形界面的集成,請參考官方文檔。
參考資源
Prometheus 概念及詳細配置請參閱 Prometheus 官方文檔
Node exporter 安裝請參考 node_exporter github 倉庫
Slack 信息發送請參考 Incoming Webhooks
51Reboot 2019 最新課程招生信息
Python 零基礎入門課程
此課程爲面授班和網絡班,一共 15 個課時,每週上一個全天,歷時4個月。附加:錄播視頻+筆記+答疑2019-6月份開課
Python 自動化運維進階課程
此課程爲面授班和網絡班,一共 15 個課時,每週上一個全天,歷時4個月。附加:錄播視頻+筆記+答疑2019-4月份開課
Docker+K8s 課程
此課程爲網絡班,一共 150個課時,每週上一個全天,歷時4個月。附加:錄播視頻+筆記+答疑現已開課
現在報名即可享受早鳥價
golang 課程
早報名可享受早鳥價
想要詳細瞭解和報名的同學可以私聊WeChat:17812796384