iT邦幫忙

2024 iThome 鐵人賽

2
DevOps

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

後 Grafana 時代的第三十二天 - AlertSnitch 無縫整合 Grafana 全家桶的最佳實踐

  • 分享至 

  • xImage
  •  

前言

在前一篇文章中,我們概述了 AlertSnitch 的功能和應用場景,特別是在告警歷史可視化中的重要性。後來有好幾個小夥伴紛紛表示對 AlertSnitch 與 Loki、Grafana 的整合很有興趣,這也讓我想在特地為 AlertSnitch 搭配 Loki 的絕配組合寫一篇安裝指引。這篇文章將探討其架構設計、組件功能,以及如何在實際環境中進行安裝與配置,幫助各位快速上手。

設計思路

https://ithelp.ithome.com.tw/upload/images/20241225/20149562eBdqF7GWCw.png

相信大家在看到上面的架構圖時,應該已經注意到 AlertSnitch 是實現告警事件資訊持久化的關鍵角色。它負責將告警資訊儲存於 Grafana Loki,並透過 Grafana 進行告警歷史的查看與分析,這與原本 Prometheus → AlertManager → Slack 或其他通知目的地的流程有很大不同。

AlertManager 的核心職能是處理告警路由的相關任務,包括告警的去重、分組與抑制等功能,但它並不具備持久化存儲或分析告警資訊的能力。這樣的設計使得 AlertManager 能保持簡單、高效與穩定的特性。因此,為了補足這一缺陷,我們需要引入 AlertSnitch,幫助我們實現對告警歷史的存儲與分析功能。

有興趣的小夥伴可以參考我的這篇 AlertManager 介紹

AlertSnitch 專案

首先,我們第一步需要安裝 AlertSnitch 專案,並且使用 AlertSnitch for Loki 現成設定檔:

git clone git@github.com:MikeHsu0618/alertsnitch.git

接下來,我們來看看如何配置 Grafana Loki,然後繼續安裝並配置 AlertSnitch。

Note:本篇教學的運作環境將以 Kubernetes 為主,因此需要具備基本的 Kubernetes 和 Helm 使用經驗,以及對 Grafana Stacks 概念的理解。如果對這些關鍵字還不熟悉的朋友,可以參考我之前撰寫的 Kubernetes 和 Grafana Stacks 入門系列文

AlertManager(optional)

AlertManager 作為接收 Prometheus Rule 告警的端點並進行分派的角色,允許我們配置告警接收者(receivers)以及使用 Labels 制定各種路由策略。因此,我們需要在 AlertManager 中為 AlertSnitch 分別配置相關的 routes 和 receivers 欄位,以確保告警能正確傳遞並處理。

# config.yaml
route:
  group_by: ['alertname', 'cluster', 'service']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 3h
  receiver: team-X-mails
  routes:
    - matchers:
        - alertname =~ "InfoInhibitor|Watchdog"
      receiver: "null"
	- receiver: alertsnitch
	  continue: true
    - matchers:
        - service=~"foo1|foo2|baz"
      receiver: team-X-mails
...
receivers:
  - name: 'team-X-mails'
    email_configs:
      - to: 'team-X+alerts@example.org'
  - name: alertsnitch
    webhook_configs:
      - url: http://localhost:9567/webhook?source=alertsnitch

在這段配置中,我們可以注意到一些設計巧思:

  1. Routes 的匹配順序與 continue 設定

    Routes 是按照順序從上至下進行匹配的,並在匹配到條件後執行相應的接收者(receiver)。為了讓 AlertSnitch 能夠實現持久化存儲而不影響原有的告警通知,我們將 AlertSnitch receiver 放在靠前的位置,並設置 continue: true,使告警可以繼續向下匹配其他規則。

    在這裡,我們注意到 AlertSnitch receiver 被放在第二條匹配規則中,而不是第一條。這是因為第一條規則針對的是 InfoInhibitor 和 Watchdog,這些是 Prometheus 的內建告警,用於監控 AlertManager 本身的健康狀態,通常不需要持久化或特別處理,因此可以直接忽略。

  2. Receivers 的 Webhook 配置

    receivers 的配置中,alertsnitch receiver 使用了一個帶有 query string 的 Webhook URL,例如:

    http://localhost:9567/webhook?source=alertsnitch 
    

    這種設計支持將靜態 Label 作為參數傳遞,便於在寫入 Loki 時標記來源,如:{source="alertsnitch"}。如此一來,當需要將來自多個 AlertManager 的告警集中存儲於一個中心化的 Loki 集群時,這樣的設計可以幫助我們有效區分不同的告警來源,避免數據混淆。

Grafana Loki

從現在開始,我們將快速在 Kuberentes 環境中建立起一個完整的 AlertSnitch 所需的最低要件。首先我們需要建立一個讓 AlertSnitch 持久化告警訊息的儲存後端。

helm upgrade --install loki grafana/loki --version 6.21.0 -n loki --create-namespace -f values.yaml
----
Release "loki" does not exist. Installing it now.
NAME: loki
LAST DEPLOYED: Sun Dec 22 22:39:49 2024
NAMESPACE: loki
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
***********************************************************************
 Welcome to Grafana Loki
 Chart version: 6.21.0
 Chart Name: loki
 Loki version: 3.3.0
***********************************************************************

** Please be patient while the chart is being deployed **

Tip:

  Watch the deployment status using the command: kubectl get pods -w --namespace loki

If pods are taking too long to schedule make sure pod affinity can be fulfilled in the current cluster.

***********************************************************************
Installed components:
***********************************************************************
* gateway
* minio
* compactor
* index gateway
* query scheduler
* ruler
* distributor
* ingester
* querier
* query frontend

在這裡我們可以注意到我們特地將 Loki 的 max query series 設定調整到比原本 500 更大的值,主要是為了滿足 loki query 統計告警訊息後的大量時序資料。

loki:
  limits_config:
    max_query_series: 100000

對於大範圍、多告警紀錄進行分析時,原本的 500 條 series 的保守限制很容易觸發上限,影響分析結果,所以調高 max_query_series 可以確保我們處理更大的告警資料。

AlertSnitch for Loki Configuration

在AlertSnitch 的環境參數中,我們可以看到儲存後端的相關設定,特別是這裡還支持了 Loki 多租戶功能。而啟動 AlertSnitch 的唯一必要條件是成功與一個儲存後端綁定,例如 Grafana Loki、MySQL 或 PostgreSQL。

# helm/alertsnitch/values.yaml
fullname: alertsnitch

image:
  repository: mikehsu0618/alertsnitch
  pullPolicy: IfNotPresent
  tag: "latest"

service:
  type: ClusterIP
  port: 9567

env:
  ALERTSNITCH_ADDR: ":9567"
  ALERTSNITCH_DEBUG: "true"
  ALERTSNITCH_BACKEND: "loki"
  ALERTSNITCH_BACKEND_ENPOINT: "http://loki-gateway.loki"
  ALERTSNITCH_LOKI_TENANT_ID: ""

沒問題的話,我們就能夠開始進行安裝:

helm upgrade --install alertsnitch ./ -n alertsnitch --create-namespace   
---
Release "alertsnitch" does not exist. Installing it now.
NAME: alertsnitch
LAST DEPLOYED: Sun Dec 22 22:42:00 2024
NAMESPACE: alertsnitch
STATUS: deployed
REVISION: 1
TEST SUITE: None

完成後,我們將可以看到順利連接 database 的相關 log。

Connected to database
2024/12/22 14:57:31 Starting listener on :9567

如果你的 Loki 是剛建立出來還沒有寫入任何資料時,將會導致 AlertSnitch 將無法判定其為健康狀態。而這時我們可以簡單的手動寫入一筆資料到 Loki 來解決:

curl -H "Content-Type: application/json" -XPOST -s "http://127.0.0.1:3100/loki/api/v1/push"  \
--data-raw "{\"streams\": [{\"stream\": {\"job\": \"test\"}, \"values\": [[\"$(date +%s)000000000\", \"fizzbuzz\"]]}]}"

到此,我們已經大略完成了運作起 AlertSnitch 的最低要件了,接下來我們將透過實戰演練來體驗 AlertSnitch 的強大之處。

在 Grafana 中實際體驗 AlertSnitch for Loki

在實戰演練的部分,我們將利用 K6 產生如下所示的 AlertManager 告警訊息內容,並且對 AlertSnitch 發出請求,模擬現實情況各種不同狀態的告警 firing、resolved 等狀態紀錄,並且在 Grafana 介面中實現告警歷史分析可視化。

{
  "receiver": "webhook",
  "status": "firing",
  "alerts": [
    {
      "status": "firing",
      "labels": {
        "alertname": "Test",
        "dc": "eu-west-1",
        "instance": "localhost:9090",
        "job": "prometheus24"
      },
      "annotations": {
        "description": "some description"
      },
      "startsAt": "2018-08-03T09:52:26.739266876+02:00",
      "endsAt": "0001-01-01T00:00:00Z",
      "generatorURL": "http://example.com:9090/graph?g0.expr=go_memstats_alloc_bytes+%3E+0\u0026g0.tab=1"                                                                                  
    }
  ],
  "groupLabels": {
    "alertname": "Test",
    "job": "prometheus24"
  },
  "commonLabels": {
    "alertname": "Test",
    "dc": "eu-west-1",
    "instance": "localhost:9090",
    "job": "prometheus24"
  },
  "commonAnnotations": {
    "description": "some description"
  },
  "externalURL": "http://example.com:9093",
  "version": "4",
  "groupKey": "{}:{alertname=\"Test\", job=\"prometheus24\"}"
}

K6(feed generator)

如果還沒有安裝 K6 的話可以透過 brew 指令快速安裝:

brew install k6

在專案中 K6 的現成腳本中,我們只需要指定到我們的 AlertSnitch 端點就能輕鬆產生告警資料:

# generator.js
const ALERTSNITCH_URL = 'http://localhost:9567/webhook';

const res = http.post( ALERTSNITCH_URL, JSON.stringify(payload), {
    headers: { 'Content-Type': 'application/json' },
});

接著執行指令就能產生 AlertManager 告警資訊請求:

k6 run k6/generator.js     
---
          /\      |‾‾| /‾‾/   /‾‾/   
     /\  /  \     |  |/  /   /  /    
    /  \/    \    |     (   /   ‾‾\  
   /          \   |  |\  \ |  (‾)  | 
  / __________ \  |__| \__\ \_____/ .io

     execution: local
        script: k6/generator.js
        output: -

     scenarios: (100.00%) 1 scenario, 1 max VUs, 10m30s max duration (incl. graceful stop):
              * default: 30 iterations shared among 1 VUs (maxDuration: 10m0s, gracefulStop: 30s)

running (00m03.3s), 0/1 VUs, 30 complete and 0 interrupted iterations
default ✓ [======================================] 1 VUs  00m03.3s/10m0s  30/30 shared iters

Grafana

接著就讓我們來安裝 Grafana 並且載入特製的 Dashboard 來體驗 AlertSnitch 為我們帶來的可視化資訊。

helm upgrade --install grafana grafana/grafana --version 8.6.4 -n grafana --create-namespace -f values.yaml               (orbstack/default)
Release "grafana" does not exist. Installing it now.
NAME: grafana
LAST DEPLOYED: Sun Dec 22 23:20:54 2024
NAMESPACE: grafana
STATUS: deployed
REVISION: 1

AlertSnitch Dashboard(Loki)

安裝 Grafana 後就讓我們登入其中(預設帳號密碼皆為 admin),載入 AlertSnitch Dashboard 的 ID 22488

https://ithelp.ithome.com.tw/upload/images/20241225/20149562U3aAcwBOom.png

載入後,我們的 AlertSnitch 替我們儲存在 Loki 的各種告警歷史都會被呈現出來。

https://ithelp.ithome.com.tw/upload/images/20241225/20149562ylwheJeSNo.png

得益於 Grafana 和 Loki 的靈活特性,我在設計這張 Dashboard 時,充分結合了兩者的優勢,創造出了一些有趣且實用的使用者體驗:

  1. 在 AlertSnitch 將告警資訊寫入 Loki 時,已經預先從訊息中的 commonLabels 等關鍵欄位(如 severity、priority、container 等)提取信息,並作為 Loki Index Label 寫入。此舉不僅大幅提升了查詢 Loki 時透過 Label Filter 篩選的效率,還能幫助我們聚焦於更重要的告警資訊。

https://ithelp.ithome.com.tw/upload/images/20241225/20149562UERKgovnVW.png

  1. 由於 AlertSnitch 記錄了所有告警的 Firing 和 Resolved 時間點,因此我們可以據此推算出查詢區間內所有告警的平均 MTTR(Mean Time to Resolved)。這項數據足以支持我們在每個固定週期進行審查,進而改進服務的穩定性。此外,其餘圖表中還能直觀地呈現最常被使用的告警維度標籤,如 Severity 和 Priority,這大大有助於我們聚焦在最需要優化的目標上。

https://ithelp.ithome.com.tw/upload/images/20241225/20149562GEI1lbhDX2.png

  1. 對於各種訊息格式不統一的告警訊息,Loki 則能夠輕鬆透過全文檢索來進行無差別過濾,這也正是使用 Loki 的靈活之處。

https://ithelp.ithome.com.tw/upload/images/20241225/20149562s3OJRyz0mQ.png

  1. 在 History Alert Details 區塊中,我們可以清楚地查看每條告警的詳細資訊,而無需在 Slack 訊息中毫無頭緒地翻找。此外,該區塊還設置了多種實用功能,例如快速跳轉到 Prometheus Rule Query 語句或 Runbook 頁面,大幅提升查看與處理告警時的效率與使用體驗。

https://ithelp.ithome.com.tw/upload/images/20241225/20149562KRYhnsp9Jc.png

至此,我們已經從零開始成功打造了 AlertSnitch for Loki 的完整服務,並實現了其在分析告警歷史中的實際應用。

結語

在 AlertSnitch 的實踐中,我們不僅實現了對 Grafana 和 Loki 的深度整合,更重要的是成功將那些原本「閱後即忘」的告警資訊轉化為有價值的洞見。這些被忽視的數據,透過 AlertSnitch 的整理與分析,讓我們得以重新審視告警的模式與趨勢,進一步優化系統穩定性與運維效率。

目前,我們主要利用 Grafana 原生的 Panel 來呈現這些告警資訊,通過靈活的查詢與可視化功能,快速了解系統的運行情況。然而,這僅僅是個開始,未來我們可以進一步打造專屬於 AlertSnitch 的 Grafana App,將告警數據的管理與分析功能提升到全新的層次。這不僅能提供更直觀的告警歷史視圖和報表,還能結合自動化的分析與建議,幫助我們更高效地處理告警並持續改進服務的可靠性。AlertSnitch 的潛力,遠不止於此,而是為告警數據帶來更多可能性和價值。


上一篇
後 Grafana 時代的第三十一天 - AlertSnitch 告警歷史可視化的利器
系列文
後 Grafana 時代的自我修養32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

1
雷N
iT邦研究生 1 級 ‧ 2024-12-26 10:37:16

讚讚讚 最近來玩看看 這玩意兒

Yeah~/images/emoticon/emoticon41.gif

我要留言

立即登入留言