Prometheus와 Grafana: pull 기반 메트릭 수집·PromQL·대시보드

상위: 00.Observability MOC

개요

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])) * 100

rate(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을 시계열로 저장하고, PromQLrate()·histogram_quantile()로 에러율과 p95를 계산하며, Alertmanager로 알림을 라우팅한다. Grafana는 이를 4 golden signals 중심 대시보드로 시각화한다. 고카디널리티 라벨 회피, 적절한 rate 창, for 지속 조건이 실전 안정성의 관건이다. 요청 흐름 단위의 원인 추적은 OpenTelemetry - 분산 추적으로, LLM 서빙 지표는 오픈소스 서빙 - KServe·Triton·vLLM과 연계한다.

키워드: #prometheus #grafana #observability PromQL histogram_quantile golden-signals