- Authors

- Name
- Youngju Kim
- @fjvbn20031
- 1. 개요
- 2. Rule Manager
- 3. Alert 상태 머신
- 4. Alertmanager로의 전송
- 5. Alertmanager 내부 구조
- 6. Alert 그루핑
- 7. 억제 (Inhibition)
- 8. 사일런싱 (Silencing)
- 9. 중복 제거 (Deduplication)
- 10. Alertmanager HA 클러스터
- 11. 알림 전달 (Notification)
- 12. 모니터링과 디버깅
- 13. 정리
1. 개요
Prometheus의 알림 파이프라인은 메트릭 데이터를 기반으로 이상 상태를 감지하고, 적절한 수신자에게 알림을 전달하는 시스템입니다. 이 파이프라인은 크게 두 컴포넌트로 구성됩니다:
- Prometheus Server: Rule 평가와 Alert 생성
- 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:00, 00:15, 00: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
각 그룹은 하나의 알림으로 전송됩니다.
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으로 전송 상태 공유
- 하나의 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. Silence 상태:
- 생성/수정/삭제된 사일런스 정보
- 모든 인스턴스에서 동일한 사일런스 적용
동기화 메커니즘:
- 주기적으로 무작위 피어에게 상태 전파
- 새 인스턴스 참여 시 전체 상태 동기화
- 최종 일관성(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 웹훅
- pagerduty: PagerDuty Events API
- opsgenie: OpsGenie API
- victorops: VictorOps API
- webhook: 범용 HTTP 웹훅
- 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 클러스터로 고가용성을 보장합니다.
다음 글에서는 Prometheus의 장기 저장소와 Remote Write/Read 프로토콜을 분석할 예정입니다.