Skip to content
Published on

[Prometheus] アラートパイプライン:Rule評価からAlertmanager配信まで

Authors

1. 概要

Prometheusのアラートパイプラインはメトリクスデータに基づいて異常を検知し、適切な受信者に通知を配信するシステムです。パイプラインは主に2つのコンポーネントで構成されます:

  1. Prometheus Server:Rule評価とAlert生成
  2. Alertmanager:Alertルーティング、グルーピング、抑制、サイレンシング、通知配信

この記事ではRule Managerの評価ループ、Alert状態マシン、Alertmanagerの内部構造をソースコードレベルで分析します。

2. Rule Manager

2.1 全体構造

prometheus.ymlのrule_files
        |
        v
+-------------------+
|   Rule Manager    |
|                   |
|  +-- Rule Group 1 (evaluation_interval: 15s)
|  |     +-- recording rule A
|  |     +-- alerting rule B
|  |     +-- alerting rule C
|  |
|  +-- Rule Group 2 (evaluation_interval: 30s)
|  |     +-- recording rule D
|  |     +-- alerting rule E
|  |
+-------------------+
        |
   Alert送信
        |
        v
+-------------------+
|  Alertmanager     |
+-------------------+

2.2 Rule Group

Rule Groupは関連するルールの集まりで、同じ評価周期で順次実行されます:

groups:
  - name: node_alerts
    interval: 15s # デフォルトはglobal.evaluation_interval
    rules:
      - record: instance:node_cpu:rate5m
        expr: 1 - avg by(instance)(rate(node_cpu_seconds_total{mode="idle"}[5m]))

      - alert: HighCPU
        expr: instance:node_cpu:rate5m > 0.9
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: 'CPU使用率が90%を超過'

2.3 評価ループ

Rule Group評価ループ:

1. evaluation_intervalタイマー発火
        |
        v
2. グループ内のルールを順番に評価
   (recording ruleが先、alerting ruleの順)
        |
        v
3. 各ルールのPromQL式をTSDBに対して実行
        |
        v
4. recording rule:結果を新しい時系列としてTSDBに保存
   alerting rule:結果をAlert状態マシンに渡す
        |
        v
5. アクティブAlertをAlertmanagerに送信
        |
        v
6. 次の評価サイクルまで待機

ルールはグループ内で順番に評価されるため、recording ruleの結果を同じグループのalerting ruleで参照できます。

2.4 評価タイミング

評価タイミング管理:

- 各Rule Groupは独立したgoroutineで実行
- 評価開始時間はevaluation_intervalに整列
  (例:15秒間隔なら:00, :15, :30...)
- 評価がintervalより長くかかった場合、次の評価をスキップ
- スキップされた評価はメトリクスとして記録:
  prometheus_rule_group_iterations_missed_total

3. Alert状態マシン

3.1 状態遷移

Alert状態マシン:

  +----------+
  | inactive |
  +----+-----+
       |
       | 式の結果が存在(マッチ)
       v
  +---------+
  | pending |  (for duration待機中)
  +----+----+
       |
       | for duration経過
       v
  +---------+
  | firing  |  (Alertmanagerに送信)
  +----+----+
       |
       | 式の結果がない(マッチせず)
       v
  +----------+
  | resolved |  (解決済み、Alertmanagerに送信)
  +----+-----+
       |
       | 次の評価サイクル
       v
  +----------+
  | inactive |
  +----------+

注意:pending状態で式の結果がない場合、直接inactiveに遷移

3.2 for Duration

forフィールドはAlertがfiring状態に遷移する前に条件が持続すべき時間です:

for duration動作:

時間  式の結果  状態
0s    true     inactive -> pending (ActiveAt = 0s)
15s   true     pending (経過: 15s)
30s   true     pending (経過: 30s)
...
5m    true     pending -> firing (for: 5m充足)
5m15s true     firing (送信継続)
5m30s false    firing -> resolved
5m45s -        resolved -> inactive

forなし(for: 0s)の場合:
0s    true     inactive -> firing(即時)

3.3 Alertの識別

各Alertインスタンスはラベルセットで一意に識別されます:

Alert識別:

alertname + 式の結果ラベル + 追加labelsフィールド
= Alertの一意なfingerprint

例:
  alert: HighCPU
  expr: instance:node_cpu:rate5m > 0.9
  labels:
    severity: warning

結果ラベルがinstance="node-1"の場合:
  fingerprint = hash(alertname=HighCPU, instance=node-1, severity=warning)

同じルールでもinstance値が異なれば別のAlert

4. Alertmanagerへの送信

4.1 送信メカニズム

Alert送信フロー:

1. 評価ループからアクティブAlertを収集
   (firing + resolved)
        |
        v
2. AlertをAPI形式にシリアライズ
   POST /api/v2/alerts
        |
        v
3. 設定されたすべてのAlertmanagerインスタンスに送信
   (alerting.alertmanagers設定)
        |
        v
4. 送信失敗時は次の評価サイクルで再送信
   (Alertは毎評価サイクルごとに再送信)

4.2 Alertデータ形式

Alertデータ構造:

- labels:           Alert識別ラベルマップ
- annotations:      追加情報(summary、descriptionなど)
- startsAt:         Alert開始時間
- endsAt:           Alert終了時間(resolvedまたは予想終了)
- generatorURL:     Prometheus式リンク

firing状態:
  endsAt = 現在時刻 + 4 * evaluation_interval
  (次の送信前に期限切れにならないように)

resolved状態:
  endsAt = 解決時刻

4.3 Alertmanagerディスカバリ

Alertmanagerディスカバリ:

1. 静的設定:
   alerting:
     alertmanagers:
       - static_configs:
           - targets: ['alertmanager-1:9093', 'alertmanager-2:9093']

2. サービスディスカバリ:
   alerting:
     alertmanagers:
       - kubernetes_sd_configs:
           - role: pod
         relabel_configs:
           - source_labels: [__meta_kubernetes_pod_label_app]
             regex: alertmanager
             action: keep

Prometheusは発見されたすべてのAlertmanagerにAlertを送信します。

5. Alertmanager内部構造

5.1 処理パイプライン

Alertmanager処理パイプライン:

Alert受信(API)
    |
    v
Dispatcher
    |-- ルーティングツリーマッチング
    |-- Alertグルーピング
    |
    v
Notification Pipeline
    |-- Wait(グループ待機)
    |-- Dedup(重複排除)
    |-- Retry(リトライ)
    |-- Inhibit(抑制確認)
    |-- Silence(サイレンシング確認)
    |-- Notify(実際の送信)
    |
    v
Receiver
    |-- email
    |-- Slack
    |-- PagerDuty
    |-- Webhook
    |-- ...

5.2 ルーティングツリー

ルーティングツリーはAlertを適切な受信者にマッチさせる階層的構造です:

# alertmanager.yml
route:
  receiver: 'default-receiver'
  group_by: ['alertname', 'cluster']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  routes:
    - match:
        severity: critical
      receiver: 'pagerduty-critical'
      group_wait: 10s
      routes:
        - match:
            service: database
          receiver: 'dba-pagerduty'
    - match:
        severity: warning
      receiver: 'slack-warnings'
      group_by: ['alertname', 'service']
ルーティングツリーマッチング:

root (default-receiver)
  |
  +-- severity=critical -> pagerduty-critical
  |     |
  |     +-- service=database -> dba-pagerduty
  |
  +-- severity=warning -> slack-warnings

マッチング順序:
1. 子ルートを上から下へ順に走査
2. 最初にマッチしたルートを選択(continue: false がデフォルト)
3. continue: trueの場合は次のルートも確認を継続
4. マッチする子がない場合は現在のノードのreceiverを使用

6. Alertグルーピング

6.1 グルーピングメカニズム

グルーピング動作:

group_by: ['alertname', 'cluster']

Alert 1: alertname=HighCPU, cluster=prod, instance=node-1
Alert 2: alertname=HighCPU, cluster=prod, instance=node-2
Alert 3: alertname=HighCPU, cluster=staging, instance=node-3
Alert 4: alertname=DiskFull, cluster=prod, instance=node-1

グループ結果:
  グループ1: (alertname=HighCPU, cluster=prod)     -> Alert 1, 2
  グループ2: (alertname=HighCPU, cluster=staging)  -> Alert 3
  グループ3: (alertname=DiskFull, cluster=prod)     -> Alert 4

各グループは1つの通知として送信されます。

6.2 グルーピングタイミング

グルーピングタイミングパラメータ:

group_wait: 30s
  - 新しいグループ作成後、最初の通知送信までの待機時間
  - この間に同じグループに追加されるAlertを収集
  - 初期Alertストーム時の重複通知を防止

group_interval: 5m
  - グループに新しいAlertが追加された際の通知再送信間隔
  - 既存Alertのみの場合はこの間隔を適用しない

repeat_interval: 4h
  - 変更のないグループの通知繰り返し送信間隔
  - 受信者がAlertを見逃さないための定期リマインド

7. 抑制(Inhibition)

7.1 抑制ルール

抑制は特定のAlertがアクティブな場合に他のAlertの通知をブロックします:

inhibit_rules:
  - source_match:
      severity: critical
    target_match:
      severity: warning
    equal: ['alertname', 'cluster']
抑制動作:

source Alert(存在してfiring):
  alertname=HighCPU, cluster=prod, severity=critical

target Alert(抑制対象):
  alertname=HighCPU, cluster=prod, severity=warning

equalフィールドがマッチするため、target Alertの通知が抑制される。
同じ問題でcriticalがfiringならwarningは通知しない。

7.2 抑制処理

抑制処理フロー:

1. Notification PipelineのInhibitステージで実行
2. 現在のアクティブAlertリストからsource_matchを確認
3. マッチするsource Alertがある場合
4. equalフィールドの値が同一かを確認
5. 同一であればtarget Alertの通知を抑制
6. 抑制されたAlertはUIには表示される(状態は維持)

8. サイレンシング(Silencing)

8.1 サイレンス作成

サイレンスは特定の条件のAlert通知を一時的にブロックします:

サイレンス構成:

- matchers:     ラベルマッチャー(正規表現サポート)
- startsAt:     サイレンス開始時間
- endsAt:       サイレンス終了時間
- createdBy:    作成者
- comment:      理由

例:
  matchers:
    alertname = HighCPU
    cluster = prod
  startsAt: 2026-03-20T10:00:00Z
  endsAt:   2026-03-20T14:00:00Z
  comment: "計画メンテナンス"

8.2 サイレンス処理

サイレンスマッチング:

1. Notification PipelineのSilenceステージで実行
2. アクティブサイレンスリストを巡回
3. 各サイレンスのmatchersをAlertラベルに対して評価
4. すべてのmatcherがマッチすれば該当Alertをサイレンシング
5. サイレンシングされたAlertはAlertmanager UIに表示される
6. サイレンス期限切れ後、自動的に通知を再開

9. 重複排除(Deduplication)

9.1 重複排除メカニズム

重複排除シナリオ:

1. 同一Alertの繰り返し受信:
   - Prometheusが毎評価サイクルごとにfiring Alertを再送信
   - Alertmanagerが同一Alertの重複通知を防止
   - Notification Logに送信記録を保存

2. HAクラスタ重複:
   - 複数のPrometheusインスタンスが同一Alertを送信
   - AlertmanagerクラスタがgossipでDelivery状態を共有
   - 1つのAlertmanagerのみが実際の通知を送信

9.2 Notification Log

Notification Log:

- 各Alertグループの通知送信記録を保存
- キー:グループfingerprint + receiver
- 値:最終送信時間、送信済みAlert fingerprintリスト
- repeat_intervalと比較して再送信を判断
- HAクラスタでgossipプロトコルで同期

10. Alertmanager HAクラスタ

10.1 クラスタ構成

Alertmanager HAアーキテクチャ:

Prometheus 1 --+                          +--> Slack
Prometheus 2 --+--> [Alertmanager 1] <--> +--> PagerDuty
                    [Alertmanager 2] <-->
                    [Alertmanager 3] <-->
                         |
                    gossip protocol
                    (Memberlist)

10.2 Gossipプロトコル

AlertmanagerはMemberlist(HashiCorp)ベースのgossipプロトコルを使用します:

Gossipで同期されるデータ:

1. Notification Log:
   - どのAlertグループに通知が送信されたか
   - 他のインスタンスがすでに送信した場合は重複送信を防止

2. サイレンス状態:
   - 作成/変更/削除されたサイレンス情報
   - すべてのインスタンスで同一のサイレンスを適用

同期メカニズム:
  - 定期的にランダムなピアに状態を伝播
  - 新しいインスタンス参加時に全状態を同期
  - 結果整合性(eventual consistency)モデル

10.3 HA設定

# Alertmanagerクラスタの起動
alertmanager --config.file=alertmanager.yml \
  --cluster.listen-address=0.0.0.0:9094 \
  --cluster.peer=alertmanager-1:9094 \
  --cluster.peer=alertmanager-2:9094
HA動作:

1. すべてのインスタンスがAlertを受信
2. すべてのインスタンスがルーティング/グルーピングを独立して実行
3. Notification PipelineでDedupステージを実行
4. Notification Logをgossipで確認
5. まだ送信されていない場合のみ実際の通知を送信
6. 送信結果をNotification Logに記録しgossipで伝播

11. 通知配信(Notification)

11.1 レシーバータイプ

組み込みレシーバー:
  - email:      SMTPメール
  - slack:      Slack Webhook
  - pagerduty:  PagerDuty Events API
  - opsgenie:   OpsGenie API
  - victorops:  VictorOps API
  - webhook:    汎用HTTP Webhook
  - wechat:     WeChat
  - pushover:   Pushover
  - sns:        AWS SNS
  - telegram:   Telegram Bot API
  - webex:      Webex Teams
  - msteams:    Microsoft Teams

11.2 テンプレートシステム

通知テンプレート:

AlertmanagerはGoテンプレートを使用して通知内容を構成します。

利用可能なデータ:
  .Status:       firingまたはresolved
  .Alerts:       Alertリスト
  .GroupLabels:  グルーピングに使用されたラベル
  .CommonLabels: すべてのAlertに共通するラベル
  .ExternalURL:  Alertmanager外部URL

各Alertで利用可能なデータ:
  .Labels:       Alertラベル
  .Annotations:  Alertアノテーション
  .StartsAt:     開始時間
  .EndsAt:       終了時間
  .GeneratorURL: Prometheusリンク

11.3 リトライメカニズム

通知送信リトライ:

1. 通知送信失敗時
2. 指数バックオフ(exponential backoff)でリトライ
   初期間隔:1秒、最大間隔:5分
3. 最大リトライ後も失敗した場合はログに記録
4. 次のrepeat_intervalで再度試行

12. モニタリングとデバッグ

12.1 Prometheus Serverメトリクス

Rule評価関連メトリクス:
  prometheus_rule_evaluations_total:        ルール評価の総回数
  prometheus_rule_evaluation_failures_total: ルール評価失敗回数
  prometheus_rule_group_duration_seconds:    グループ評価所要時間
  prometheus_rule_group_iterations_missed_total: スキップされた評価回数

Alert関連メトリクス:
  prometheus_alerts:                         現在のアクティブAlert数(状態別)
  prometheus_notifications_total:             Alertmanager送信回数
  prometheus_notifications_errors_total:      送信失敗回数
  prometheus_notifications_dropped_total:     ドロップされた通知数
  prometheus_notifications_queue_length:      送信キューの長さ

12.2 Alertmanagerメトリクス

Alertmanagerメトリクス:
  alertmanager_alerts:                       現在のアクティブAlert数
  alertmanager_alerts_received_total:         受信したAlert数
  alertmanager_alerts_invalid_total:          無効なAlert数
  alertmanager_notifications_total:           送信された通知数(レシーバー別)
  alertmanager_notifications_failed_total:    送信失敗数
  alertmanager_silences:                     アクティブサイレンス数
  alertmanager_cluster_members:              クラスタメンバー数
  alertmanager_cluster_messages_received_total: gossipメッセージ数

12.3 一般的なトラブルシューティング

1. Alertがfiringにならない:
   - PromQL式を手動実行して結果を確認
   - for durationが十分に経過しているか確認
   - evaluation_interval設定を確認

2. 通知が受信されない:
   - Alertmanager接続状態を確認(Prometheus /targets)
   - ルーティングツリーマッチングを確認(amtool config routes test)
   - サイレンスを確認(Alertmanager UI)
   - 抑制ルールを確認

3. 重複通知:
   - group_by設定を確認
   - repeat_intervalを確認
   - HAクラスタgossip状態を確認

13. まとめ

Prometheusアラートパイプラインは、Rule Managerの周期的評価、Alert状態マシンの精密な状態管理、Alertmanagerの多段階処理パイプラインで構成されます。グルーピングで通知ストームを緩和し、抑制とサイレンシングで不要な通知をブロックし、gossipベースのHAクラスタで高可用性を保証します。