prometheus-簡介及安裝


監控是整個產品周期中最重要的一環,及時預警減少故障影響免擴大,而且能根據歷史數據追溯問題。

對系統不間斷實時監控

實時反饋系統當前狀態

保證業務持續性運行

  • 監控系統

監控方案

告警

特點

適用

Zabbix

Y

大量定制工作

大部分的互聯網公司

open-falcon

Y

功能模塊分解比較細,顯得更復雜

系統和應用監控

Prometheus+Grafana

Y

擴展性好

容器,應用,主機全方面監控

市場上主流的開源監控系統基本都是這個流程

l  數據采集:對監控數據采集

l  數據存儲:將監控數據持久化存儲,用於歷時查詢

l  數據分析:數據按需處理,例如閾值對比、聚合

l  數據展示:Web頁面展示

l  監控告警:電話,郵件,微信,短信

要監控什么

硬件監控

1)通過遠程控制卡:Dell的IDRAC

2)IPMI(硬件管理接口)監控物理設備。

3)網絡設備:路由器、交換機

溫度,硬件故障等。

系統監控

CPU,內存,硬盤利用率,硬件I/O,網卡流量,TCP狀態,進程數

應用監控

Nginx、Tomcat、PHP、MySQL、Redis等,業務涉及的服務都要監控起來

日志監控

系統日志、服務日志、訪問日志、錯誤日志,這個現成的開源的ELK解決方案,會在下一章講解

安全監控

1)可以利用Nginx+Lua實現WAF功能,並存儲到ES,通過Kibana可視化展示不同的攻擊類型。

2)用戶登錄數,passwd文件變化,其他關鍵文件改動

API監控

收集API接口操作方法(GET、POST等)請求,分析負載、可用性、正確性、響應時間

業務監控

例如電商網站,每分鍾產生多少訂單、注冊多少用戶、多少活躍用戶、推廣活動效果(產生多少用戶、多少利潤)

流量分析

根據流量獲取用戶相關信息,例如用戶地理位置、某頁面訪問狀況、頁面停留時間等。監控各地區訪問業務網絡情況,優化用戶體驗和提升收益

Prometheus概述

Prometheus(普羅米修斯)是一個最初在SoundCloud上構建的監控系統。自2012年成為社區開源項目,擁有非常活躍的開發人員和用戶社區。為強調開源及獨立維護,Prometheus於2016年加入雲原生雲計算基金會(CNCF),成為繼Kubernetes之后的第二個托管項目。

https://prometheus.io

https://github.com/prometheus

作為新一代的監控框架,Prometheus 具有以下特點:

  • 多維數據模型:由度量名稱和鍵值對標識的時間序列數據
  • PromSQL:一種靈活的查詢語言,可以利用多維數據完成復雜的查詢
  • 不依賴分布式存儲,單個服務器節點可直接工作
  • 基於HTTP的pull方式采集時間序列數據
  • 推送時間序列數據通過PushGateway組件支持
  • 通過服務發現或靜態配置發現目標
  • 多種圖形模式及儀表盤支持

Prometheus適用於以機器為中心的監控以及高度動態面向服務架構的監控。

Prometheus組成及架構
  • Prometheus Server:收集指標和存儲時間序列數據,並提供查詢接口
  • ClientLibrary:客戶端庫
  • Push Gateway:短期存儲指標數據。主要用於臨時性的任務
  • Exporters:采集已有的第三方服務監控指標並暴露metrics
  • Alertmanager:告警
  • Web UI:簡單的Web控制台

數據模型

Prometheus將所有數據存儲為時間序列;具有相同度量名稱以及標簽屬於同一個指標。

每個時間序列都由度量標准名稱和一組鍵值對(也成為標簽)唯一標識。

時間序列格式:

<metric name>{<label name>=<label value>, ...}

示例:api_http_requests_total{method="POST", handler="/messages"}

指標類型

  • Counter:遞增的計數器
  • Gauge:可以任意變化的數值
  • Histogram:對一段時間范圍內數據進行采樣,並對所有數值求和與統計數量
  • Summary:與Histogram類似

指標和實例

實例:可以抓取的目標稱為實例(Instances)

作業:具有相同目標的實例集合稱為作業(Job)

scrape_configs:
    - job_name: 'prometheus'
      static_configs:
      - targets: ['localhost:9090']
   - job_name: 'node'
      static_configs:
      - targets: ['192.168.1.10:9090']

Prometheus部署

二進制 部署

下載最新版本的Prometheus,然后解壓縮並運行它:

https://prometheus.io/download/

https://prometheus.io/docs/prometheus/latest/getting_started/

tar xvfz prometheus-*.tar.gz
cd prometheus-*
mv prometheus-* /usr/local/prometheus

系統服務

[Unit]
Description=https://prometheus.io

[Service]
Restart=on-failure
ExecStart=/usr/local/prometheus/prometheus --config.file=/usr/local/prometheus/prometheus.yml

[Install]
WantedBy=multi-user.target

常用命令

啟動prometheus
./prometheus --config.file=prometheus.yml

檢測配置文件
./promtool check config prometheus.yml

重新加載配置文件
kill -hup PID
Docker容器部署

https://prometheus.io/docs/prometheus/latest/installation/

prometheus.yml通過運行以下命令將您從主機綁定:
docker run -p 9090:9090 -v /tmp/prometheus.yml:/etc/prometheus/prometheus.yml \
       prom/prometheus

或者為配置使用額外的卷:
docker run -p 9090:9090 -v /prometheus-data \
       prom/prometheus --config.file=/prometheus-data/prometheus.yml

訪問Web

http://localhost:9090訪問自己的狀態頁面

可以通過訪問localhost:9090驗證Prometheus自身的指標:localhost:9090/metrics

配置Prometheus監控本身

Prometheus從目標機上通過http方式拉取采樣點數據, 它也可以拉取自身服務數據並監控自身的健康狀況

當然Prometheus服務拉取自身服務采樣數據,並沒有多大的用處,但是它是一個好的DEMO。保存下面的Prometheus配置,並命名為:prometheus.yml:

global:
  scrape_interval:     15s # 默認情況下,每15s拉取一次目標采樣點數據。

  # 我們可以附加一些指定標簽到采樣點度量標簽列表中, 用於和第三方系統進行通信, 包括:federation, remote storage, Alertmanager
  external_labels:
    monitor: 'codelab-monitor'

# 下面就是拉取自身服務采樣點數據配置
scrape_configs:
  # job名稱會增加到拉取到的所有采樣點上,同時還有一個instance目標服務的host:port標簽也會增加到采樣點上
  - job_name: 'prometheus'

    # 覆蓋global的采樣點,拉取時間間隔5s
    scrape_interval: 5s

    static_configs:
      - targets: ['localhost:9090']

 全局配置文件

global:全局配置

alerting:告警配置

rule_files:告警規則

scrape_configs:配置數據源,稱為target,每個target用job_name命名。又分為靜態配置和服務發現

global:
  # 默認抓取周期,可用單位ms、smhdwy #設置每15s采集數據一次,默認1分鍾
  [ scrape_interval: <duration> | default = 1m ]
  # 默認抓取超時
  [ scrape_timeout: <duration> | default = 10s ]
  # 估算規則的默認周期# 每15秒計算一次規則。默認1分鍾
  [ evaluation_interval: <duration> | default = 1m ]
  # 和外部系統(例如AlertManager)通信時為時間序列或者警情(Alert)強制添加的標簽列表
  external_labels:
    [ <labelname>: <labelvalue> ... ]
 
# 規則文件列表
rule_files:
  [ - <filepath_glob> ... ]
 
# 抓取配置列表
scrape_configs:
  [ - <scrape_config> ... ]
 
# Alertmanager相關配置
alerting:
  alert_relabel_configs:
    [ - <relabel_config> ... ]
  alertmanagers:
    [ - <alertmanager_config> ... ]
 
# 遠程讀寫特性相關的配置
remote_write:
  [ - <remote_write> ... ]
remote_read:
  [ - <remote_read> ... ]
scrape_configs

根據配置的任務(job)以http/s周期性的收刮(scrape/pull)

指定目標(target)上的指標(metric)。目標(target)

可以以靜態方式或者自動發現方式指定。Prometheus將收刮(scrape)的指標(metric)保存在本地或者遠程存儲上。

使用scrape_configs定義采集目標

配置一系列的目標,以及如何抓取它們的參數。一般情況下,每個scrape_config對應單個Job。

目標可以在scrape_config中靜態的配置,也可以使用某種服務發現機制動態發現。

# 任務名稱,自動作為抓取到的指標的一個標簽
job_name: <job_name>
 
# 抓取周期
[ scrape_interval: <duration> | default = <global_config.scrape_interval> ]
# 每次抓取的超時
[ scrape_timeout: <duration> | default = <global_config.scrape_timeout> ]
# 從目標抓取指標的URL路徑
[ metrics_path: <path> | default = /metrics ]
# 當添加標簽發現指標已經有同名標簽時,是否保留原有標簽不覆蓋
[ honor_labels: <boolean> | default = false ]
# 抓取協議
[ scheme: <scheme> | default = http ]
# HTTP請求參數
params:
  [ <string>: [<string>, ...] ]
 
# 身份驗證信息
basic_auth:
  [ username: <string> ]
  [ password: <secret> ]
  [ password_file: <string> ]
# Authorization請求頭取值
[ bearer_token: <secret> ]
# 從文件讀取Authorization請求頭
[ bearer_token_file: /path/to/bearer/token/file ]
 
# TLS配置
tls_config:
  [ <tls_config> ]
 
# 代理配置
[ proxy_url: <string> ]
 
# DNS服務發現配置
dns_sd_configs:
  [ - <dns_sd_config> ... ]
# 文件服務發現配置
file_sd_configs:
  [ - <file_sd_config> ... ]
# K8S服務發現配置
kubernetes_sd_configs:
  [ - <kubernetes_sd_config> ... ]
 
# 此Job的靜態配置的目標列表
static_configs:
  [ - <static_config> ... ]
 
# 目標重打標簽配置
relabel_configs:
  [ - <relabel_config> ... ]
# 指標重打標簽配置
metric_relabel_configs:
  [ - <relabel_config> ... ]
 
# 每次抓取允許的最大樣本數量,如果在指標重打標簽后,樣本數量仍然超過限制,則整個抓取認為失敗
# 0表示不限制
[ sample_limit: <int> | default = 0 
relabel_configs

relabel_configs :允許在采集之前對任何目標及其標簽進行修改

重新標簽的意義?

  • 重命名標簽名
  • 刪除標簽
  • 過濾目標

action:重新標簽動作

  • replace:默認,通過regex匹配source_label的值,使用replacement來引用表達式匹配的分組
  • keep:刪除regex與連接不匹配的目標 source_labels
  • drop:刪除regex與連接匹配的目標 source_labels
  • labeldrop:刪除regex匹配的標簽
  • labelkeep:刪除regex不匹配的標簽
  • hashmod:設置target_label為modulus連接的哈希值source_labels
  • labelmap:匹配regex所有標簽名稱。然后復制匹配標簽的值進行分組,replacement分組引用(${1},${2},…)替代
基於文件的服務發現

支持服務發現的來源:

  • azure_sd_configs
  • consul_sd_configs
  • dns_sd_configs
  • ec2_sd_configs
  • openstack_sd_configs
  • file_sd_configs
  • gce_sd_configs
  • kubernetes_sd_configs
  • marathon_sd_configs
  • nerve_sd_configs
  • serverset_sd_configs
  • triton_sd_configs

Prometheus也提供了服務發現功能,可以從consul,dns,kubernetes,file等等多種來源發現新的目標。其中最簡單的是從文件發現服務。

https://github.com/prometheus/prometheus/tree/master/discovery

服務發現支持: endpoints,ingress,kubernetes,node,pod,service

監控linux服務器

node_exporter:用於*NIX系統監控,使用Go語言編寫的收集器。

使用文檔:https://prometheus.io/docs/guides/node-exporter/

GitHub:https://github.com/prometheus/node_exporter

exporter列表:https://prometheus.io/docs/instrumenting/exporters/

監控cpu、內存、硬盤

收集到 node_exporter 的數據后,我們可以使用 PromQL 進行一些業務查詢和監控,下面是一些比較常見的查詢。

注意:以下查詢均以單個節點作為例子,如果大家想查看所有節點,將 instance="xxx" 去掉即可。

CPU使用率:
100 - (avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) * 100)
內存使用率:
100 - (node_memory_MemFree_bytes+node_memory_Cached_bytes+node_memory_Buffers_bytes) / node_memory_MemTotal_bytes * 100
磁盤使用率:
100 - (node_filesystem_free_bytes{mountpoint="/",fstype=~"ext4|xfs"} / node_filesystem_size_bytes{mountpoint="/",fstype=~"ext4|xfs"} * 100)
監控服務狀態

使用systemd收集器:

--collector.systemd.unit-whitelist=".+"  從systemd中循環正則匹配單元
--collector.systemd.unit-whitelist="(docker|sshd|nginx).service"白名單,收集目標

/usr/bin/node_exporter --collector.systemd --collector.systemd.unit-whitelist=(docker|sshd|nginx).service

node_systemd_unit_state{name=“docker.service”}               只查詢docker服務

node_systemd_unit_state{name=“docker.service”,state=“active”}   返回活動狀態,值是1

node_systemd_unit_state{name=“docker.service”} == 1當前服務狀態

Granfana炫圖展示數據

Grafana是一個開源的度量分析和可視化系統。

https://grafana.com/grafana/download

Grafana支持查詢普羅米修斯。自Grafana 2.5.0(2015-10-28)以來,包含了Prometheus的Grafana數據源。

監控Docker服務器

cAdvisor(Container Advisor)用於收集正在運行的容器資源使用和性能信息。

https://github.com/google/cadvisor

https://grafana.com/dashboards/193

運行單個cAdvisor來監控整個Docker主機

docker run \
  --volume=/:/rootfs:ro \
  --volume=/var/run:/var/run:ro \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  --volume=/dev/disk/:/dev/disk:ro \
  --publish=8080:8080 \
  --detach=true \
  --name=cadvisor \
  google/cadvisor:latest

使用Prometheus監控cAdvisor

cAdvisor將容器統計信息公開為Prometheus指標。默認情況下,這些指標在/metrics HTTP端點下提供。可以通過設置-prometheus_endpoint命令行標志來自定義此端點。

要使用Prometheus監控cAdvisor,只需在Prometheus中配置一個或多個作業,這些作業會在該指標端點處刮取相關的cAdvisor流程。

監控MySQL

mysql_exporter:用於收集MySQL性能信息。

https://github.com/prometheus/mysqld_exporter

https://grafana.com/dashboards/7362

登錄mysql為exporter創建賬號:
mysql>CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'XXXXXXXX' WITH MAX_USER_CONNECTIONS 3;
mysql>GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';

# cat .my.cnf 
[client]
user=exporter
password=exporter123

# ./mysqld_exporter --config.my-cnf=.my.cnf
  - job_name: mysql
    static_configs:
    - targets:
      - 192.168.31.66:9104

告警

使用prometheus進行告警分為兩部分:Prometheus Server中的告警規則會向Alertmanager發送。然后,Alertmanager管理這些告警,包括進行重復數據刪除,分組和路由,以及告警的靜默和抑制。

部署Alertmanager

在Prometheus平台中,警報由獨立的組件Alertmanager處理。通常情況下,我們首先告訴Prometheus Alertmanager所在的位置,然后在Prometheus配置中創建警報規則,最后配置Alertmanager來處理警報並發送給接收者(郵件,webhook、slack等)。

地址1:https://prometheus.io/download/

地址2:https://github.com/prometheus/alertmanager/releases

設置告警和通知的主要步驟如下:

  1. 部署Alertmanager
  2. 配置Prometheus與Alertmanager通信
  3. 在Prometheus中創建告警規則

 

配置Prometheus與Alertmanager通信

# vi prometheus.yml
alerting:
  alertmanagers:
  - static_configs:
    - targets:
       - 127.0.0.1:9093
在Prometheus中創建告警規則

https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/

# vi prometheus.yml
rule_files:
   - "rules/*.yml"

# vi rules/node.yml
groups:
- name: example# 報警規則組名稱
  rules:
# 任何實例5分鍾內無法訪問發出告警
  - alert: InstanceDown
    expr: up == 0
    for: 5m#持續時間 , 表示持續一分鍾獲取不到信息,則觸發報警
    labels:
      severity: page# 自定義標簽
    annotations:
      summary: "Instance {{ $labels.instance }} down"# 自定義摘要
      description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes."# 自定義具體描述
告警狀態

一旦這些警報存儲在Alertmanager,它們可能處於以下任何狀態:

  • Inactive:這里什么都沒有發生。
  • Pending:已觸發閾值,但未滿足告警持續時間(即rule中的for字段)
  • Firing:已觸發閾值且滿足告警持續時間。警報發送到Notification Pipeline,經過處理,發送給接受者。

這樣目的是多次判斷失敗才發告警,減少郵件。

告警分配

route屬性用來設置報警的分發策略,它是一個樹狀結構,按照深度優先從左向右的順序進行匹配。

route:
  receiver: 'default-receiver'  
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  group_by: [cluster, alertname]
# 所有不匹配以下子路由的告警都將保留在根節點,並發送到“default-receiver”
  routes:
# 所有service=mysql或者service=cassandra的告警分配到數據庫接收端
  - receiver: 'database-pager'
    group_wait: 10s
    match_re:
      service: mysql|cassandra
# 所有帶有team=frontend標簽的告警都與此子路由匹配
# 它們是按產品和環境分組的,而不是集群
  - receiver: 'frontend-pager'
    group_by: [product, environment]
    match:
      team: frontend 

group_by:報警分組依據

group_wait:為一個組發送通知的初始等待時間,默認30s

group_interval:在發送新告警前的等待時間。通常5m或以上

repeat_interval:發送重復告警的周期。如果已經發送了通知,再次發送之前需要等待多長時間。通常3小時或以上

主要處理流程:

  1. 接收到Alert,根據labels判斷屬於哪些Route(可存在多個Route,一個Route有多個Group,一個Group有多個Alert)。
  2. 將Alert分配到Group中,沒有則新建Group。
  3. 新的Group等待group_wait指定的時間(等待時可能收到同一Group的Alert),根據resolve_timeout判斷Alert是否解決,然后發送通知。
  4. 已有的Group等待group_interval指定的時間,判斷Alert是否解決,當上次發送通知到現在的間隔大於repeat_interval或者Group有更新時會發送通知。
告警收斂(分組、抑制、靜默)

告警面臨最大問題,是警報太多,相當於狼來了的形式。收件人很容易麻木,不再繼續理會。關鍵的告警常常被淹沒。在一問題中,alertmanger在一定程度上得到很好解決。

Prometheus成功的把一條告警發給了Altermanager,而Altermanager並不是簡簡單單的直接發送出去,這樣就會導致告警信息過多,重要告警被淹沒。所以需要對告警做合理的收斂。

告警收斂手段:

分組(group):將類似性質的警報分類為單個通知

抑制(Inhibition):當警報發出后,停止重復發送由此警報引發的其他警報

靜默(Silences):是一種簡單的特定時間靜音提醒的機制

Prometheus一條告警怎么觸發的

報警處理流程如下:

  1. Prometheus Server監控目標主機上暴露的http接口(這里假設接口A),通過上述Promethes配置的'scrape_interval'定義的時間間隔,定期采集目標主機上監控數據。
  2. 當接口A不可用的時候,Server端會持續的嘗試從接口中取數據,直到"scrape_timeout"時間后停止嘗試。這時候把接口的狀態變為“DOWN”。
  3. Prometheus同時根據配置的"evaluation_interval"的時間間隔,定期(默認1min)的對Alert Rule進行評估;當到達評估周期的時候,發現接口A為DOWN,即UP=0為真,激活Alert,進入“PENDING”狀態,並記錄當前active的時間;
  4. 當下一個alert rule的評估周期到來的時候,發現UP=0繼續為真,然后判斷警報Active的時間是否已經超出rule里的‘for’ 持續時間,如果未超出,則進入下一個評估周期;如果時間超出,則alert的狀態變為“FIRING”;同時調用Alertmanager接口,發送相關報警數據。
  5. AlertManager收到報警數據后,會將警報信息進行分組,然后根據alertmanager配置的“group_wait”時間先進行等待。等wait時間過后再發送報警信息。
  6. 屬於同一個Alert Group的警報,在等待的過程中可能進入新的alert,如果之前的報警已經成功發出,那么間隔“group_interval”的時間間隔后再重新發送報警信息。比如配置的是郵件報警,那么同屬一個group的報警信息會匯總在一個郵件里進行發送。
  7. 如果Alert Group里的警報一直沒發生變化並且已經成功發送,等待‘repeat_interval’時間間隔之后再重復發送相同的報警郵件;如果之前的警報沒有成功發送,則相當於觸發第6條條件,則需要等待group_interval時間間隔后重復發送。
  8. 同時最后至於警報信息具體發給誰,滿足什么樣的條件下指定警報接收人,設置不同報警發送頻率,這里有alertmanager的route路由規則進行配置
編寫告警規則案例
# cat rules/general.yml 
groups:
- name: general.rules
  rules:
  - alert: InstanceDown
    expr: up == 0
    for: 2m
    labels:
      severity: error
    annotations:
      summary: "Instance {{ $labels.instance }} 停止工作"
      description: "{{ $labels.instance }}: job {{ $labels.job }} 已經停止5分鍾以上."


# cat rules/node.yml
groups:
- name: node.rules
  rules:
  - alert: NodeFilesystemUsage
    expr: 100 - (node_filesystem_free_bytes{fstype=~"ext4|xfs"} / node_filesystem_size_bytes{fstype=~"ext4|xfs"} * 100) > 80
    for: 2m
    labels:
      severity: warning
    annotations:
      summary: "{{$labels.instance}}: {{$labels.mountpoint }} 分區使用過高"
      description: "{{$labels.instance}}: {{$labels.mountpoint }} 分區使用大於 80% (當前值: {{ $value }})"
  - alert: NodeMemoryUsage
    expr: 100 - (node_memory_MemFree_bytes+node_memory_Cached_bytes+node_memory_Buffers_bytes) / node_memory_MemTotal_bytes * 100 > 80
    for: 2m
    labels:
      severity: warning
    annotations:
      summary: "{{$labels.instance}}: 內存使用過高"
      description: "{{$labels.instance}}: 內存使用大於 80% (當前值: {{ $value }})"
  - alert: NodeCPUUsage
    expr: 100 - (avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) * 100) > 80
    for: 2m
    labels:
      severity: warning
    annotations:
      summary: "{{$labels.instance}}: CPU使用過高"
      description: "{{$labels.instance}}: CPU使用大於 80% (當前值: {{ $value }})"

# cat rules/reload.yml 
groups:
- name: prometheus.rules
  rules:
  - alert: AlertmanagerReloadFailed
    expr: alertmanager_config_last_reload_successful == 0
    for: 10m
    labels:
      severity: warning
    annotations:
      summary: "{{$labels.instance}}: Alertmanager配置重新加載失敗"
      description: "{{$labels.instance}}: Alertmanager配置重新加載失敗"
  - alert: PrometheusReloadFailed
    expr: prometheus_config_last_reload_successful == 0
    for: 10m
    labels:
      severity: warning
    annotations:
      summary: "{{$labels.instance}}: Prometheus配置重新加載失敗"
      description: "{{$labels.instance}}: Prometheus配置重新加載失敗"


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM