1. 程式人生 > 實用技巧 >Prometheus-alertmanager元件使用

Prometheus-alertmanager元件使用

警報管理

Alertmanager工作過程

​ Alertmanager處理從客戶端(通常是Prometheus伺服器或其它工具的警報)發來的警報,然後Alertmanager對警報進行去重、分組,然後路由到不同的接收器,如電子郵件、簡訊或SaaS服務(PagerDuty等)。還可以使用Alertmanager管理維護警報。

  • 先在Prometheus伺服器上編寫警報規則,這些規則將使用(exporter)收集的指標並在指定的閾值或標準上觸發警報。當指標達到閾值或標準時,生成一個警報並將其推送到alertmanger。告警在Alertmanger上的HTTP端點上接收。
  • 收到警報後,alertmanager會處理警報並根據其標籤進行路由。一旦路徑確定,他們將由Alertmanager傳送到外部目的地。如電子郵件、簡訊等工具。

alertmanager安裝配置

詳見文件

配置alertmanager

Alertmanager配置也是基於YAML的配置檔案,主要由global,route,receivers這三部分組成。

簡單樣例(alertmanager.yml)

通過電子郵件傳送任何收到的警報到另一個郵箱地址。

global:
  smtp_from: 'localhost:25'
  smtp_smarthost: '[email protected]'
  smtp_require_tls: false

route:
  receiver: 'email'

receivers:
-name: 'email'
  email_configs:
  - to: '[email protected]'

templates:
- '/ups/app/monitor/alertmanager/template/*.tmpl'
  • global: 全域性配置,為其它塊設定預設值
  • template: 包含儲存警報模板的目錄列表。由於alertmanager可以傳送到各種目的地,因此需要能夠自定義警報的外觀及其包含的資料
  • route: 它告知alertmanager如何處理特定的傳入警報。警報根據規則進行匹配然後採取相應的操作。
  • receivers(接收器):指定警報的目的地。每個接收器都有一個名稱和相關配置

在Prometheus中配置alertmanager

在Prometheus中配置,告訴Prometheus關於Alertmanager的資訊。在alerting塊中配置alertmanger相關資訊。

# Alertmanager configuration
alerting:
  alertmanagers:
  - static_configs:
    - targets:
      - progs:9093  # 對應啟動的altermanager節點的9093埠

​ alerting塊包含允許Prometheus識別一個或多個Alertmanager的配置。為此,Prometheus使用與查詢抓取目標時相同的發現機制,在預設配置中是static_configs。與監控作業一樣,它指定目標列表,此處是主機名progs加埠9093(Alertmanager預設埠)的形式。該列表假定你的Prometheus伺服器可以解析progs主機名為IP地址,並且Alertmanager在該主機的埠9093上執行。

監控alertmanager

Alertmanager可以暴露了自身的相關指標作為被監控物件。建立一個作業來監控alertmanager

  - job_name: 'alertmanager'
    static_configs:
    - targets: ['localhost:9093']

​ 這將從http://localhost:9093/metrics收集指標並抓取一系列以alertmanager_為字首的時間序列資料。這些資料包括按狀態分類的警報計數、按接收器分類的成功和失敗通知的計數、還可以包含Alertmanager叢集狀態指標。

新增警報規則

與記錄規則一樣,警報規則也是在Prometheus伺服器中配置載入的規則檔案(使用YAML語句定義)。現在rules目錄中建立一個新檔案node_alerts.yml,以儲存節點警報規則為例子進行說明。

在prometheus.yml配置檔案中的rule_files塊配置載入的規則檔案
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
  - "rules/*_rules.yml"
  - "rules/*_alerts.yml"

當前使用萬用字元載入該目錄中以_rules.yml_alerts.yml結尾的所有檔案。

新增警報規則

vi rules/node_alerts.yml

groups:
- name: node_alerts
  rules:
  - alert: InstanceDown
    expr: up{job="node_exporter"} == 0
    for: 10s
    labels:
      severity: critical
    annotations:
      summary: Host {{ $labels.instance }} is down!
  • 上面指定一個組名為node_alerts的警報規則,該組中的規則包含在rules的塊中。

  • 每個規則通過alert子句指定它的名稱,並且每個警報組中的警報名稱必須唯一。

  • 觸發警報表達式使用expr子句指定。

  • for子句控制在觸發警報之前必須為true的時間長度。在這個示例中,指標up{job="node_exporter"}需要在觸發警報之前的10秒中內等於0.這限制了警報誤報或暫時狀態的可能。

  • 使用標籤(labels)裝飾警報,指定要附加到警報的其它標籤,這裡添加了一個值為critical的severity的標籤。警報上的標籤與警報的名稱組合構成警報的標識

  • 註解(annotations)裝飾警報,用於展現更多的資訊的標籤,如描述、處理說明等。這裡新增一個名為summary的標籤來描述警報

重啟Prometheus服務啟用新的警報規則

開啟web介面檢視http://progs:9090/alerts

警報觸發

Prometheus以固定時間間隔(由引數evaluation_interval控制)評估所有的規則。預設值1分鐘。在每個評估週期內,Prometheus執行每個警報規則中定義的表示式並更新警報狀態。

警報狀態
  • Inactive:警報未啟用
  • Pending:警報已滿足測試表達式條件,但仍在等待for子句指定的持續時間
  • Firing:警報已滿足測試表達式條件,並且Pending的時間已超過for子句的持續時間

Pending到Firing的轉換可以確保警報更有效,且不會來回浮動。沒有for子句的警報會自動從Inactive轉換為Firing,只需要一個評估週期(evaluation_interval)即可觸發。帶有for子句的警報將首先轉換為Pending,然後轉換為Firing,因此至少需要兩個評估週期才能觸發。

警報的生命週期
  • 節點的可能不斷變化,每隔一段由scrape_interval定義的時間被Prometheus抓取一次,對我們來說是15秒。
  • 根據每個evaluation_interval的指標來評估警報規則,對我們來說還是15秒。
  • 當警報表達式為true時(對於上面示例來說節點發生down),會建立一個警報並轉換到Pending狀態,執行for子句。
  • 在下一個評估週期中,如果警報測試表達式仍然為true,則檢查for的持續時間。如果超過了持續時間,則警報將轉換為Firing,生成通知並將其推送到Alertmanager。
  • 如果警報測試表達式不再為true,則Prometheus會將警報規則的狀態從Pending更改為Inactive。
alertmanager的警報

通過http://progs:9090/alerts Web介面檢視警報及其狀態

處於Firing狀態的警報已經推送到alertmanager,可以在alertmanager API(http://progs:9093/api/v1/alerts)檢視

[root@progs config]# curl http://progs:9093/api/v1/alerts| python -m json.tool
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  1004  100  1004    0     0   172k      0 --:--:-- --:--:-- --:--:--  196k
{
    "data": [
        {
            "annotations": {
                "summary": "Host 192.168.10.181:9100 is down!"
            },
            "endsAt": "2020-08-08T02:37:48.046283806Z",
            "fingerprint": "2c28fee95b3f434c",
            "generatorURL": "http://progs:9090/graph?g0.expr=up%7Bjob%3D%22node_exporter%22%7D+%3D%3D+0&g0.tab=1",
            "labels": {
                "alertname": "InstanceDown",
                "hostname": "192.168.10.181",
                "instance": "192.168.10.181:9100",
                "job": "node_exporter",
                "severity": "critical"
            },
            "receivers": [
                "wechat"
            ],
            "startsAt": "2020-08-08T02:28:48.046283806Z",
            "status": {
                "inhibitedBy": [],
                "silencedBy": [],
                "state": "active"
            }
        },
        {
            "annotations": {
                "summary": "Host  is down!"
            },
            "endsAt": "2020-08-08T02:37:48.046283806Z",
            "fingerprint": "550e18fea3ef4d3d",
            "generatorURL": "http://progs:9090/graph?g0.expr=avg+by%28job%29+%28up%7Bjob%3D%22node_exporter%22%7D%29+%3C+0.75&g0.tab=1",
            "labels": {
                "alertname": "InstancesDown",
                "job": "node_exporter",
                "severity": "critical"
            },
            "receivers": [
                "wechat"
            ],
            "startsAt": "2020-08-08T02:28:48.046283806Z",
            "status": {
                "inhibitedBy": [],
                "silencedBy": [],
                "state": "active"
            }
        }
    ],
    "status": "success"
}
[root@progs config]# 

Prometheus為Pending和Firing狀態中的每個警報建立指標(ALERT),如下:

新增模板

模板(template)是一種在警報中使用時間序列資料的標籤和值的方法,可用於註解和標籤。模板使用標準的Go模板語法,並暴露一些包含時間序列的標籤和值的變數。標籤以變數$labels形式表示,指標的值則是變數$value。

引用時間序列的值
  • summary註解中引用instance標籤,使用{{$labels.instance}}
  • 引用時間序列的值,使用{{$value}}
  • 使用humanize函式,它使用指標字首將數字轉換為更易於閱讀的形式

路由

將不同屬性的警報路由到不同的目的地。預設使用後序遍歷路由

下面在alertmanager.yml檔案中新增一些路由配置

global:
  smtp_from: 'localhost:25'
  smtp_smarthost: '[email protected]'
  smtp_require_tls: false

route:
  group_by: ['instance']
  group_wait: 30s
  
  group_interval: 5m
  repeat_interval: 3h
  receiver: 'email'
  routes:
  - match:
      severity: critical
    receiver: pager
  - match_re:
      severity: ^(warning|critical)$
    receiver: support_team

receivers:
- name: 'email'
  email_configs:
  - to: '[email protected]'
- name: 'support_team'
  email_configs:
  - to: '[email protected]'
- name: 'pager'
  email_configs:
  - to: '[email protected]'

templates:
- '/ups/app/monitor/alertmanager/template/*.tmpl'
  • group_by: 控制Alertmanager分組警報的方式。預設所有警報分成一組
    • 示例指定標籤instance對警報分組,意味著來自特定例項的所有警報分在一起
    • 分組會改變alertmanager的處理行為,當觸發新警報時,等待group_wait中指定時間段,以便在觸發警報之前是否收到改組的其它警報
  • group_interval:在發出警報後,如果收到該分組的下一次評估新警報,alertmanager等待group_interval指定的時間段,再發送新警報。防止警報分組的警報氾濫
  • repeat_interval:僅作用於單個警報,等待重新發送相同警報的時間段。不適用警報組
路由表

routes子句列出分支路由。通過標籤匹配或正則表示式匹配將警報傳送到指定的目的地。路由都是分支,可以繼續設定分支路由。

標籤匹配
  - match:
      severity: critical
    receiver: pager

將所有severity標籤與critical值匹配,並將它們傳送到pager接收器。

路由分支

新routes塊巢狀已有的routes塊中。

  routes:
  - match:
      severity: critical
    receiver: pager
    routes:
      - match:
        service: application
      receiver: support_team

當新警報severity標籤為critical且service標籤application都成功匹配時,將警報傳送到接收器support_team。

正則表示式匹配
  - match_re:
      severity: ^(warning|critical)$
    receiver: support_team

它匹配severity標籤中的warning或critical值。

路由遍歷順序

預設使用後序遍歷路由,可以使用continue選項控制路由遍歷順序,該選項控制警報是否先序遍歷路由,然後再返回已遍歷路由樹。continue預設選項為false,即後序遍歷路由樹。

延申知識點
  • 前序遍歷(先序):前序遍歷可以記為根左右,若二叉樹為空,則結束返回。
  • 後序遍歷:後序遍歷可以記為左右根,也就是說在二叉樹的遍歷過程中,首先按照後序遍歷的規則遍歷左子樹,接著按照後序遍歷的規則遍歷右子樹,最後訪問根節點。若二叉樹為空,則結束返回。
  routes:
  - match:
      severity: critical
    receiver: pager
    continue: true

continue: true時,則警報將在此路由中觸發(如果匹配),並繼續執行下一個相鄰路由。

接收器

指定接收警報的目的地。

receivers:
- name: 'pager'
  email_configs:
  - to: '[email protected]'
  slack_configs:
  - api_url: https://hooks.slack.com/service/ABC123/ABC123/EXAMPLE
    channel: '#monitoring'

新增Slack接收器,它會訊息傳送到Slack例項。示例中任何向pager接收器傳送警報的路由都將被髮送到Slack的#monitoring頻道,並通過電子郵件傳送到[email protected]

通知模板

使用Go template函式來引用外部模板,從而避免在配置檔案中嵌入較長且複雜的字串。

建立模板檔案
cat > /ups/app/monitor/alertmanager/template/slack.tmpl <<-EOF
{{ define "slack.example.text" }}{{ .CommonAnnotations.summary }}{{ end}}
EOF

使用define函式定義了一個新模板,以end結尾,並取名為slack.example.text,然後在模板內的text中複製內容。

引用模板
  slack_configs:
  - api_url: https://hooks.slack.com/service/ABC123/ABC123/EXAMPLE
    channel: '#monitoring'
    text: '{{ template "slack.example.text" . }}'

使用了template選項來指定模板的名稱。使用模板通知來填充text欄位。

silence和維護

silence: 警報靜音。當明確知道停止服務以進行維護作業時,並不希望觸發警報。這種場景需要用到silence,設定特定時間段內遮蔽觸發警報規則。

設定silence的方法

  • alertmanager Web控制檯
  • amtool命令列工具

silence配置過程

alertmanager Web控制檯設定silence
新建silence

配置相關屬性

amtool工具設定silence
用法
usage: amtool [<flags>] <command> [<args> ...]

View and modify the current Alertmanager state.

Config File: The alertmanager tool will read a config file in YAML format from one of two default config locations:
$HOME/.config/amtool/config.yml or /etc/amtool/config.yml

All flags can be given in the config file, but the following are the suited for static configuration:

  alertmanager.url
  	Set a default alertmanager url for each request

  author
  	Set a default author value for new silences. If this argument is not
  	specified then the username will be used

  require-comment
  	Bool, whether to require a comment on silence creation. Defaults to true

  output
  	Set a default output type. Options are (simple, extended, json)

  date.format
  	Sets the output format for dates. Defaults to "2006-01-02 15:04:05 MST"

Flags:
  -h, --help           Show context-sensitive help (also try --help-long and --help-man).
      --date.format="2006-01-02 15:04:05 MST"  
                       Format of date output
  -v, --verbose        Verbose running information
      --alertmanager.url=ALERTMANAGER.URL  
                       Alertmanager to talk to
  -o, --output=simple  Output formatter (simple, extended, json)
      --timeout=30s    Timeout for the executed command
      --version        Show application version.

Commands:
  help [<command>...]
  alert
    query* [<flags>] [<matcher-groups>...]
    add [<flags>] [<labels>...]
  silence
    add [<flags>] [<matcher-groups>...]
    expire [<silence-ids>...]
    import [<flags>] [<input-file>]
    query* [<flags>] [<matcher-groups>...]
    update [<flags>] [<update-ids>...]
  check-config [<check-files>...]
  cluster
    show*
  config
    show*
    routes [<flags>]
      show*
      test [<flags>] [<labels>...]

amtool配置檔案

預設配置檔案路徑``$HOME/.config/amtool/config.ymlor/etc/amtool/config.yml`

# Define the path that `amtool` can find your `alertmanager` instance
alertmanager.url: "http://progs:9093"

# Override the default author. (unset defaults to your username)
author: [email protected]

# Force amtool to give you an error if you don't include a comment on a silence
comment_required: true
comment: default

# Set a default output format. (unset defaults to simple)
output: extended
新建silence

將在Alertmanager的http://progs:9093上新增一個新silence,它將警報與兩個標籤匹配:自動填充包含警報名稱的alertname標籤和service標籤。並返回一個silence ID

/ups/app/monitor/alertmanager/bin/amtool --comment=testing --alertmanager.url=http://progs:9093 silence add alertname=InstancesGone service=application
  • 使用預設config.yml檔案新增silence
/ups/app/monitor/alertmanager/bin/amtool silence add alertname=InstancesGone 
查詢當前的silence列表
/ups/app/monitor/alertmanager/bin/amtool --alertmanager.url=http://progs:9093 silence query