iT邦幫忙

2024 iThome 鐵人賽

DAY 23
1
DevOps

後 Grafana 時代的自我修養系列 第 23

後 Grafana 時代的第二十三天 - 探討 Prometheus AlertManager 的正確姿勢(二)

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20241007/20149562FpAjIkqKQT.png

前言

在先前介紹完了 Alertmanager 的基本架構後,我們理所當然的可以直接進入進階設定環節吧!本篇將會帶各位介紹關於如何調整 Alertmanager 核心設定,藉此我們能夠更了解到 Alertmanager 的運作機制。隨後,我們將會探討一些使用 Alertmanager 作為告警管理的實際注意事項,這也能加深我們對於告警事件概念的輪廓。

Alertmanager 設定總覽

以下為一個 Alertmanager 設定範例檔案,我們可以藉此來理解各個設定項目的意義:

global:
  smtp_smarthost: 'localhost:25'
  smtp_from: 'alertmanager@example.org'
  smtp_auth_username: 'alertmanager'
  smtp_auth_password: 'password'

templates:
  - '/etc/alertmanager/template/*.tmpl'

route:
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 3h

# A default receiverreceiver: team-X-mails
  routes:
    - matchers:
        - service=~"foo1|foo2|baz"
      receiver: team-X-mails
      routes:
        - matchers:
            - severity="critical"
          receiver: team-X-pager
    - matchers:
        - service="files"
      receiver: team-Y-mails
      routes:
        - matchers:
            - severity="critical"
          receiver: team-Y-pager
    - matchers:
        - service="database"
      receiver: team-DB-pager
# Also group alerts by affected database.group_by: [alertname, cluster, database]
      routes:
        - matchers:
            - owner="team-X"
          receiver: team-X-pager
          continue: true
        - matchers:
            - owner="team-Y"
          receiver: team-Y-pager

inhibit_rules:
  - source_matchers: [severity="critical"]
    target_matchers: [severity="warning"]
    equal: [alertname, cluster, service]

receivers:
  - name: 'team-X-mails'
    email_configs:
      - to: 'team-X+alerts@example.org'
  - name: 'team-Y-mails'
    email_configs:
      - to: 'team-Y+alerts@example.org'
  - name: 'team-Y-mails'
    email_configs:
      - to: 'team-Y+alerts@example.org'
  - name: 'team-Y-pager'
    pagerduty_configs:
      - service_key: <team-Y-key>
  - name: 'team-DB-pager'
    pagerduty_configs:
      - service_key: <team-DB-key>

Global 設定

global 是全局設置區域,它定義了告警管理的基礎配置,包括 SMTP 伺服器、發送者郵箱及 SMTP 認證資訊,這些設定會應用到所有的告警接收端。

smtp_smarthost:指定用來發送郵件的 SMTP 伺服器地址及端口號,這裡是 localhost:25。 smtp_from:郵件的發送者地址。 smtp_auth_username 和 smtp_auth_password:SMTP 認證使用的帳號與密碼。

Templates 設定

Alertmanager 支援自定義告警模板,透過 templates 設定,我們可以指定 Alertmanager 使用的模板路徑。這些模板可以用來自定義告警通知的格式,支持將 Prometheus 中的變數嵌入郵件或其他通知中。

templates:
  - '/etc/alertmanager/template/*.tmpl'

https://ithelp.ithome.com.tw/upload/images/20241007/20149562046JrNcKCJ.png

告警路由

Alertmanager 的路由機制是其核心功能之一。透過 route 區塊,我們可以定義告警分發的方式。路由可以根據告警的標籤(如 service 或 severity)來決定將告警發送給哪個接收者(receiver)。

route:
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 3h

關鍵設定:

  • group_wait:告警分組的等待時間。這個設定告訴 Alertmanager 在開始分組告警前等待多長時間,以便將短時間內的告警合併成一組發送。此處設為 30 秒。
  • group_interval:設置兩組告警之間的最短間隔時間。當第一組告警發送後,等待 group_interval 時間後再發送下一組告警。
  • repeat_interval:重複發送同一組告警的時間間隔,這裡設為 3 小時。這有助於避免同樣的告警被過於頻繁地重複通知。
route:
  receiver: team-X-mails
  routes:
    - matchers:
        - service=~"foo1|foo2|baz"
      receiver: team-X-mails
      routes:
        - matchers:
            - severity="critical"
          receiver: team-X-pager

路由設定: 這一段定義了多層次的路由結構:

  • 當 service 標籤符合 "foo1", "foo2" 或 "baz" 時,告警會發送給 team-X-mails 接收者。
  • 如果告警的 severity(嚴重性)是 critical,則會進一步路由到 team-X-pager,這意味著將會以更高優先級進行處理,例如觸發 PagerDuty。

告警抑制

告警抑制是用來避免因同一問題產生的多個不同嚴重度的告警。例如,當一個 critical 級別的告警出現時,我們可能不希望收到關聯的 warning 級別告警。

inhibit_rules:
  - source_matchers: [severity="critical"]
    target_matchers: [severity="warning"]
    equal: [alertname, cluster, service]

這段設定告訴 Alertmanager,當有 critical 嚴重性的告警出現時,會抑制同樣 alertname 且屬於同一 cluster 和 service 的 warning 告警,這樣能減少重複或冗餘的通知。

告警分組

Alertmanager 允許將多個相似的告警分組,以減少通知的數量,並提高可讀性。通過 group_by 參數,我們可以指定按照哪些標籤對告警進行分組。

group_by: [alertname, cluster, database]

這段配置將告警按照 alertname、cluster 和 database 來分組,這樣當多個數據庫相關的告警發生時,它們將會被合併成一個通知,而不是每個告警單獨發送,從而提高了告警通知的整體效率。

告警去重

告警去重的功能旨在避免對相同問題的重複通知。Alertmanager 會根據告警的標籤來進行去重,當多個相同的告警進來時,它只會發送一次通知,並在告警狀態發生變更(如恢復正常)時再發送更新。

去重的依據:Alertmanager 會根據 alertname、service、instance 等先有標籤進行去重。這些標籤組合決定了每個唯一的告警。

告警接收者

接收者(receivers)定義了告警應該發送到的具體目標。例如,可以是電子郵件、PagerDuty、Slack 等。每個接收者可以設置不同的通知渠道和格式。以下是 team-X-mails 接收者的設定:

receivers:
  - name: 'team-X-mails'
    email_configs:
      - to: 'team-X+alerts@example.org'

這裡指定了 team-X-mails 通過電子郵件將告警發送到 team-X+alerts@example.org

另外,team-DB-pager 是透過 PagerDuty 發送告警的範例:

  - name: 'team-DB-pager'
    pagerduty_configs:
      - service_key: <team-DB-key>

進階概念

接下來,我們就再更進一步的探討 Prometheus 與 Alertmanager 的運作機制,還有那些實際運作時會遇到的問題與解決方式。

Prometheus 告警規則生命週期

https://ithelp.ithome.com.tw/upload/images/20241007/201495622ZmAZRBHeU.png

注意:這裡只的 Prometheus 告警規則生命週期,皆還在向 Alertmanager 發送告警之前,並不包含 Alertmanager 的處理流程,我們需要明確清楚其中差異。

在 Prometheus 的運作流程中,指標抓取(scraping)與告警評估(evaluation)是兩個關鍵的環節:

  • 指標抓取:Prometheus 會以固定的時間間隔從監控目標中抓取(scrape)指標數據。這個時間間隔由 scrape_interval 設定,預設為 1 分鐘。你可以在全域配置中設置這個間隔,或者針對每個任務(job)進行覆寫。抓取到的數據會被儲存在 Prometheus 的本地存儲中,確保監控資訊的持久性。
  • 告警評估:Prometheus 擁有一個獨立於抓取週期的評估週期,負責定期檢查和更新告警狀態。這個評估週期由 evaluation_interval 設定,預設同樣為 1 分鐘。每次評估時,Prometheus 都會執行所有定義的告警規則,並根據結果更新告警的狀態。

一個告警在 Prometheus 中可以有以下三種狀態:

  • inactive(非活動):當前告警沒有生效,既不處於等待(pending)狀態,也不處於觸發(firing)狀態。
  • pending(等待):告警已經被觸發,但尚未達到設定的閾值持續時間,處於等待狀態。
  • firing(觸發):告警在持續了一段設定的時間後轉變為觸發狀態,表示問題已經存在一段時間,需要引起關注。

而告警的狀態只會在每次評估週期中發生變化,並且狀態轉換取決於是否設置了 FOR 設定:

  • 有 FOR 設定:如果告警規則中設置了 FOR 設定,Prometheus 會在第一次檢測到告警條件成立時,先將狀態設為 pending,並等待指定的時間。如果告警狀態在這段時間內一直維持,則狀態才會轉換為 firing。這個過程至少需要兩個評估週期,這種設置可以避免短暫的異常引起不必要的告警。
  • 沒有 FOR 設定(或設為 0):沒有設置 FOR 設定的告警一旦被觸發,會立即從 inactive 狀態轉換為 firing,不會經過 pending 狀態。

Alertmanager 告警事件生命週期

https://ithelp.ithome.com.tw/upload/images/20241007/201495624PkzeS8ot7.png

ref: https://jaanhio.me/blog/understanding-alertmanager/

Alertmanager 是告警通知管道的最後一環,在告警變為 "firing"(觸發)或 "inactive"(解除)時,它會接收並發送通知(注意,處於 "pending" 狀態的告警不會被轉發到 Alertmanager)。

其中一個重要功能是將相似的告警進行分組,這對於避免接收端被大量相同類型的告警轟炸非常有用。例如,當同一告警條件在多個節點上發生時,我們可以將所有節點的告警整合為一個通知,而不是為每個節點分別發送。這樣的分組雖然有效,但也可能引入額外的延遲。

Alertmanager 的通知分組主要由以下參數控制:group_by、group_wait 和 group_interval:

group_by: [ 'namespace', 'service' ]
group_wait: 30s
group_interval: 5m

當一個新告警觸發時,系統會等待 group_wait 的時間(例如 30 秒)才發送通知,以便在此期間收集其他符合 group_by 條件的告警,將它們一同分組發送。這表示,如果 group_wait 設為 30 秒,Alertmanager 將緩衝該告警 30 秒,等待其他可能的告警加入緩衝區,然後再發送。

如果之後在下一次評估中,同一分組內有新的告警被觸發,這些告警不會再等待 group_wait,而是等待 group_interval(例如 5 分鐘)後再發送。group_interval 決定了自上次通知發送後,需要等待多長時間才會再次發送相同分組內的通知。

告警路由策月

在 Prometheus 提到的最佳實踐中,首先,我們要保持路由設計簡單,第一級路由應該匹配 service 或 team,以確保告警能夠正確地分派。使用 amtool 或路由樹編輯器來進行測試和驗證,以確保配置的正確性,將相關告警進行分組,使通知對使用者更具意義。

此外,每個服務或團隊應該自行管理其設定檔和告警的間隔,以適應各自的客製需求。

下圖為 Routing Tree Editor 工具,可以讓我們更直觀的了解告警路由的設定:

https://ithelp.ithome.com.tw/upload/images/20241007/20149562UYMzSoK10E.png

告警歷史持久化 - Alertsnitch

在大部分的團隊中,告警事件通常是直接發送到目的地如 Slack 或 Email 等,這樣的設計雖然簡單,但卻會遇到一個問題,那就是告警事件的歷史紀錄難以追蹤,如果想要檢視某個服務在某個時間點的告警事件,可能需要翻閱大量的通知紀錄,這不僅效率低下,而且容易遺漏。

而 alertsnitch 是一個開源的告警歷史持久化專案,可以將告警事件儲存到 MySQL 或 PostgreSQL 中,並透過 Grafana 進行視覺化。藉此,我們開始擁有了統計追蹤並且優化告警事件的能力,每週甚至每天的告警事件,都可以被我們清楚的掌握。

https://ithelp.ithome.com.tw/upload/images/20241007/20149562ua2a0YHk1R.png

告警事件儀表板 - Karma

Karma 是一款為 Prometheus Alertmanager 提供的強大告警儀表板工具,專為彌補 Alertmanager 原生 UI 的不足而設計。它能從多個 Alertmanager 實例中聚合告警,為使用者提供一個集中的視覺化介面,方便管理和監控各種告警。

Karma 的核心功能包括:

  • 告警去重:將相似的告警進行去重處理,減少不必要的重複通知,提升告警的可讀性。
  • 多實例聚合:可以同時從多個 Alertmanager 實例中收集告警,提供統一的視圖,便於跨集群的監控和管理。
  • 視覺化:提供直觀的儀表板,展示告警的詳細狀態和相關資訊,幫助使用者快速了解告警情況。
  • 歷史記錄:保存告警的歷史狀態,讓使用者能夠追溯過往告警的處理情況,有助於後續的問題分析和改進。
  • 靜默管理:提供靜默管理功能,允許使用者對特定告警進行靜默處理,減少不必要的告警噪音。

https://ithelp.ithome.com.tw/upload/images/20241007/20149562PmU9VQDvgW.png

結論

在這章節中,我們已經算是對 Alertmanager 困難的部分有了蠻深入的了解。關於告警規則以及告警事件的的生命週期,我們需要特別注意其中的差異,這樣在實際的運作中,我們才能夠更清楚的知道問題的發生點在哪裡。了解其中的差異後,不論我們往後轉換到 Alertmanager 以外的告警事件工具,我們都能夠快速上手。有了紮實的基礎觀念後,我們就不需要被特定服務的告警事件工具給綁死,這樣在日後的技術選型上,我們就能夠有更多的選擇空間,。

References:


上一篇
後 Grafana 時代的第二十二天 - 探討 Prometheus AlertManager 的正確姿勢(一)
下一篇
後 Grafana 時代的第二十四天 - 探討 Grafana Alerting 有趣的部分
系列文
後 Grafana 時代的自我修養31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言