Prometheus와 Grafana: pull 기반 메트릭 수집·PromQL·대시보드
개요
Prometheus는 시계열 메트릭 수집·저장·질의의 사실상 표준이고, Grafana는 그 위에 얹는 시각화·대시보드 레이어다. 로그(무슨 일이 있었나)나 트레이스(요청이 어디를 지났나)와 달리, 메트릭은 숫자 시계열(초당 요청 수, p95 지연, CPU 사용률 등)로 시스템의 상태를 값싸게 요약한다. 둘을 합친 “Prometheus + Grafana” 스택은 Kubernetes 관측성의 기본 골격이며, 여기에 로그(OpenSearch/Loki)와 OpenTelemetry - 분산 추적을 더해 관측성 삼각형을 완성한다.
원리와 핵심 개념
Pull 모델과 scrape
Prometheus는 대상이 데이터를 밀어 보내는 push가 아니라, Prometheus가 대상의 /metrics 엔드포인트를 주기적으로 긁어오는(scrape) pull 모델이다. 각 애플리케이션·exporter는 HTTP로 현재 메트릭 스냅샷을 텍스트로 노출하고, Prometheus가 scrape_interval(예: 15s)마다 이를 수집해 로컬 TSDB에 적재한다.
Pull 모델의 장점은 (1) 대상의 헬스를 scrape 성공/실패 자체(up 메트릭)로 알 수 있고, (2) 서비스 디스커버리(Kubernetes SD 등)로 타깃을 동적으로 붙였다 뗄 수 있으며, (3) 대상이 Prometheus 주소를 몰라도 된다는 점이다. 단, 배치 잡처럼 수명이 짧아 scrape 시점에 살아있지 않은 워크로드는 Pushgateway로 예외 처리한다.
4가지 메트릭 타입
| 타입 | 의미 | 예시 |
|---|---|---|
| Counter | 단조 증가만 하는 누적값 | http_requests_total |
| Gauge | 오르내리는 순간값 | memory_usage_bytes, 큐 길이 |
| Histogram | 관측값을 버킷으로 분포화(+_sum,_count) | http_req_duration_seconds |
| Summary | 클라이언트에서 분위수 계산 | 요청 지연(사전 정의 quantile) |
Counter는 값 자체보다 변화율이 의미 있어 rate()와 함께 쓴다. Histogram은 버킷 경계 카운터를 서버에서 집계해 분위수를 계산하므로, 여러 인스턴스를 합산한 전역 p95를 구할 수 있다(Summary는 인스턴스별 분위수라 합산이 어렵다).
PromQL
PromQL은 시계열을 질의·집계하는 함수형 언어다. 핵심 패턴 두 가지:
# 5xx 에러 초당 발생률 (Counter → rate)
sum(rate(http_requests_total{status=~"5.."}[5m])) by (service)
# p95 요청 지연 (Histogram → histogram_quantile)
histogram_quantile(
0.95,
sum(rate(http_req_duration_seconds_bucket[5m])) by (le, service)
)
# 에러율(%) = 5xx / 전체
sum(rate(http_requests_total{status=~"5.."}[5m]))
/ sum(rate(http_requests_total[5m])) * 100rate(counter[5m])는 최근 5분 창의 초당 증가율을 구하고, histogram_quantile(0.95, ...)는 버킷 분포에서 95백분위를 보간한다. by (le, ...)로 버킷 라벨 le를 반드시 유지해야 분위수 계산이 성립한다.
Alertmanager
Prometheus의 recording/alerting rule이 PromQL 조건이 참이 되면 알림을 발생시키고, 이를 Alertmanager가 받아 라우팅·그룹핑·중복제거·억제(inhibition)·묵음(silence)을 처리한 뒤 Slack/PagerDuty/이메일로 보낸다.
groups:
- name: availability
rules:
- alert: HighErrorRate
expr: |
sum(rate(http_requests_total{status=~"5.."}[5m])) by (service)
/ sum(rate(http_requests_total[5m])) by (service) > 0.05
for: 10m # 10분 지속돼야 발화(플래핑 방지)
labels: { severity: page }
annotations:
summary: "{{ $labels.service }} 5xx 비율 5% 초과"4 Golden Signals
Google SRE의 4대 신호는 대시보드 설계의 기본 축이다.
| 신호 | 무엇을 보나 | 대표 메트릭 |
|---|---|---|
| Latency | 응답이 얼마나 느린가 | p50/p95/p99 지연 |
| Traffic | 얼마나 많은 요청이 오나 | 초당 요청 수(RPS) |
| Errors | 실패 비율 | 5xx 비율 |
| Saturation | 자원이 얼마나 찼나 | CPU/메모리/큐 포화도 |
실전: scrape 설정과 계측
# prometheus.yml — pull 대상 정의
global:
scrape_interval: 15s
scrape_configs:
- job_name: "app"
kubernetes_sd_configs:
- role: pod
relabel_configs: # annotation 있는 pod만 scrape
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: "true"애플리케이션은 client 라이브러리로 메트릭을 노출한다.
from prometheus_client import Counter, Histogram, start_http_server
REQS = Counter("http_requests_total", "요청 수", ["status"])
LAT = Histogram("http_req_duration_seconds", "요청 지연")
@LAT.time() # 처리 시간을 히스토그램에 기록
def handle(req):
REQS.labels(status="200").inc()
...
start_http_server(8000) # /metrics 엔드포인트 노출Kubernetes에서는 앱을 직접 계측하기 어려운 컴포넌트를 exporter(node-exporter, kube-state-metrics 등)로 노출하고, Prometheus Operator를 쓰면 ServiceMonitor CRD로 scrape 타깃을 선언형으로 관리한다. Grafana에서는 Prometheus를 데이터소스로 붙이고, 패널마다 위 PromQL을 넣어 4대 신호 대시보드를 구성한다. 대시보드 변수($service)로 서비스별 필터를 만든다.
함정과 베스트프랙티스
| 함정 | 문제 | 대응 |
|---|---|---|
| 고카디널리티 라벨 | user_id 같은 라벨이 시계열 폭발 → OOM | 라벨은 유한·저카디널리티만 |
rate() 창이 너무 짧음 | scrape 2회 미만이라 값이 튐 | 최소 4 × scrape_interval |
Gauge에 rate() | rate는 counter 전용 | Gauge는 delta/deriv |
for 없는 알림 | 순간 스파이크로 플래핑 | for: 5m~10m로 지속 조건 |
| 로컬 TSDB만 의존 | 장기 보존·HA 불가 | Thanos/Mimir로 원격 장기 저장 |
- RED/USE 방법론: 서비스는 Rate·Errors·Duration(RED), 자원은 Utilization·Saturation·Errors(USE)로 나눠 대시보드를 만든다.
- 알림은 증상 기반: “CPU 90%“보다 “사용자 에러율 5%“처럼 사용자 영향을 알림 조건으로 삼는다.
- 카나리 연계: 배포 시 이 메트릭들을 관측해 자동 롤백을 판단한다(배포 전략 - Rolling·Blue-Green·Canary).
정리
Prometheus는 pull 모델로 /metrics를 scrape해 Counter/Gauge/Histogram을 시계열로 저장하고, PromQL의 rate()·histogram_quantile()로 에러율과 p95를 계산하며, Alertmanager로 알림을 라우팅한다. Grafana는 이를 4 golden signals 중심 대시보드로 시각화한다. 고카디널리티 라벨 회피, 적절한 rate 창, for 지속 조건이 실전 안정성의 관건이다. 요청 흐름 단위의 원인 추적은 OpenTelemetry - 분산 추적으로, LLM 서빙 지표는 오픈소스 서빙 - KServe·Triton·vLLM과 연계한다.
키워드: #prometheus #grafana #observability PromQL histogram_quantile golden-signals