Author: Lijbnode
Emali: lijb1121@163.comlinux
Prometheus 是一套開源的系統監控報警框架。它啓發於 Google 的 borgmon 監控系統,由工做在 SoundCloud 的 google 前員工在 2012 年建立,做爲社區開源項目進行開發,並於 2015 年正式發佈。2016 年,Prometheus 正式加入 Cloud Native Computing Foundation,成爲受歡迎度僅次於 Kubernetes 的項目。git
做爲新一代的監控框架,Prometheus 具備如下特色:github
須要指出的是,因爲數據採集可能會有丟失,因此 Prometheus 不適用對採集數據要 100% 準確的情形。但若是用於記錄時間序列數據,Prometheus 具備很大的查詢優點,此外,Prometheus 適用於微服務的體系架構。web
Prometheus 生態圈中包含了多個組件,其中許多組件是可選的:正則表達式
圖 1 爲 Prometheus 官方文檔中的架構圖:docker
圖 1. Prometheus 架構圖數據庫
從上圖能夠看出,Prometheus 的主要模塊包括:Prometheus server, exporters, Pushgateway, PromQL, Alertmanager 以及圖形界面。ubuntu
其大概的工做流程是:vim
下面將對 Prometheus 中的數據模型,metric 類型以及 instance 和 job 等概念進行介紹,以便讀者在 Prometheus 的配置和使用中能夠有一個更好的理解。
數據模型
Prometheus 中存儲的數據爲時間序列,是由 metric 的名字和一系列的標籤(鍵值對)惟一標識的,不一樣的標籤則表明不一樣的時間序列。
四種 Metric 類型
Prometheus 客戶端庫主要提供四種主要的 metric 類型:
Counter
例如,查詢 http_requests_total{method="get", job="Prometheus", handler="query"} 返回 8,10 秒後,再次查詢,則返回 14。
Gauge
例如: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
instance 和 jobs
instance: 一個單獨 scrape 的目標, 通常對應於一個進程。
jobs: 一組同種類型的 instances(主要用於保證可擴展性和可靠性),例如:
`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 這兩個標籤。
爲了更好的演示 Prometheus 從配置,到監控,到報警的功能,本實例將引入本機 ubuntu server 的監控。因爲 Prometheus 主要用於監控 web 服務,若是須要監控 ubuntu server,則須要在本機上安裝 node exporter。 Node exporter 主要用於暴露 metrics 給 Prometheus,其中 metrics 包括:cpu 的負載,內存的使用狀況,網絡等。
安裝 node export 首先須要從 github 中下載最新的 node exporter 包,放在指定的目錄並解壓安裝包,在本實例中,放在 /home/lilly/prom/exporters/ 中。
`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 轉換爲一個服務。
`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 命令進行啓停和查看。
`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 信息以下:
`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 能夠採用多種方式安裝,本文直接用官網的 docker image(prom/prometheus)啓動一個 Prometheus server, 並配置相應的靜態監控 targets,jobs 和 alert.rules 文件。
啓動 Prometheus 容器,並把服務綁定在本機的 9090 端口。命令以下:
`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 內容爲:
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 規則文件的內容以下:
# 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 容器的日誌中看到:
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 輸出示例
當接收到 Prometheus 端發送過來的 alerts 時,Alertmanager 會對 alerts 進行去重複,分組,路由到對應集成的接受端,包括:slack,電子郵件,pagerduty,hitchat,webhook。
在 Alertmanager 的配置文件中,須要進行以下配置:
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 的容器,以下:
當 Alertmanager 服務起來時,能夠經過瀏覽器訪 Alertmanager 的主頁 http://localhost:9093,其狀態信息以下:
圖 7. Alertmanager 狀態信息
在 alerts 的頁面中,咱們能夠看到從 Prometheus sever 端發過來的 alerts,此外,還能夠作 alerts 搜索,分組,靜音等操做。
圖 8. Alertmanager 報警頁面
下面將經過一個具體的實例來演示 Prometheus 的使用。在 alert.ruels 中定義了 alert 觸發的條件是 up 爲 0。下面,手動中止 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 中更高級的使用,如查詢函數的使用,更多圖形界面的集成,請參考官方文檔。
Prometheus 概念及詳細配置請參閱 Prometheus 官方文檔
Node exporter 安裝請參考 node_exporter github 倉庫