🔧DevOps

Prometheus

프로메테우스

시계열 메트릭 수집/저장 시스템. PromQL로 쿼리. Grafana와 함께.

상세 설명

Prometheus는 SoundCloud에서 2012년 개발을 시작하여 2016년 CNCF(Cloud Native Computing Foundation)의 두 번째 졸업 프로젝트가 된 오픈소스 모니터링 시스템입니다. 시계열 데이터베이스(TSDB)를 내장하여 메트릭을 수집, 저장, 조회하는 올인원 솔루션입니다.

핵심 특징은 Pull 모델입니다. Prometheus가 설정된 대상(targets)에 HTTP로 접근하여 /metrics 엔드포인트에서 메트릭을 가져옵니다. 이 방식은 모니터링 대상이 Prometheus를 알 필요 없어 느슨한 결합을 유지합니다. 기본 수집 주기(scrape_interval)는 15초입니다.

PromQL(Prometheus Query Language)은 강력한 메트릭 조회 언어입니다. rate(), increase(), histogram_quantile() 같은 함수로 복잡한 계산을 표현할 수 있습니다. 예: rate(http_requests_total[5m])은 5분간 초당 요청 수를 계산합니다.

실무에서는 Prometheus + Grafana(시각화) + Alertmanager(알림) 조합이 표준입니다. Kubernetes 환경에서는 ServiceMonitor CRD로 자동 타겟 디스커버리가 가능하며, 대규모 환경에서는 Thanos나 Mimir로 장기 보관과 고가용성을 확보합니다.

코드 예제

# prometheus.yml - Prometheus 설정 파일
global:
  scrape_interval: 15s      # 메트릭 수집 주기
  evaluation_interval: 15s  # 룰 평가 주기
  external_labels:
    cluster: 'production'
    region: 'ap-northeast-2'

# 알림 규칙 파일
rule_files:
  - '/etc/prometheus/rules/*.yml'

# Alertmanager 설정
alerting:
  alertmanagers:
    - static_configs:
        - targets: ['alertmanager:9093']

# 메트릭 수집 대상
scrape_configs:
  # Prometheus 자체 메트릭
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  # Kubernetes 서비스 디스커버리
  - job_name: 'kubernetes-pods'
    kubernetes_sd_configs:
      - role: pod
    relabel_configs:
      # prometheus.io/scrape: "true" 어노테이션이 있는 파드만 수집
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: true
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port]
        action: replace
        target_label: __address__
        regex: (.+)
        replacement: ${1}:$1

  # Node Exporter (서버 메트릭)
  - job_name: 'node-exporter'
    static_configs:
      - targets: ['node-exporter:9100']

---
# alert-rules.yml - 알림 규칙
groups:
  - name: application
    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: 5m
        labels:
          severity: critical
        annotations:
          summary: "{{ $labels.service }} 에러율 5% 초과"
          description: "최근 5분간 에러율: {{ $value | humanizePercentage }}"

      # 높은 레이턴시 알림
      - alert: HighLatency
        expr: |
          histogram_quantile(0.95,
            sum(rate(http_request_duration_seconds_bucket[5m])) by (le, service)
          ) > 1
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "{{ $labels.service }} P95 레이턴시 1초 초과"

---
# 유용한 PromQL 쿼리 예시

# 1. CPU 사용률 (%)
100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

# 2. 메모리 사용률 (%)
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100

# 3. 초당 요청 수 (RPS)
sum(rate(http_requests_total[5m])) by (service)

# 4. P99 응답 시간
histogram_quantile(0.99, sum(rate(http_request_duration_seconds_bucket[5m])) by (le))

# 5. 파드 재시작 횟수 (최근 1시간)
increase(kube_pod_container_status_restarts_total[1h])

실무에서 이렇게 말해요

시니어: "Prometheus 메트릭 보관 기간이 15일인데, 월간 리포트 뽑으려면 장기 보관이 필요해요. Thanos 도입 검토해봤어요?"

주니어: "네, Thanos Sidecar로 S3에 저장하면 무제한 보관 가능하고, 비용도 월 50달러 정도면 충분할 것 같습니다."

면접관: "Prometheus의 Pull 모델과 Push 모델의 차이점은 뭔가요?"

지원자: "Pull 모델은 Prometheus가 대상에서 메트릭을 가져와서 네트워크 문제 시 발견이 쉽고, Push 모델은 대상이 메트릭을 보내서 임시 작업에 적합합니다. Prometheus는 Pull 기본이지만 Pushgateway로 Push도 지원합니다."

리뷰어: "이 rate() 쿼리에서 range가 scrape_interval보다 작으면 정확한 값이 안 나와요. [1m]을 최소 [2m]으로 올려야 해요."

개발자: "아, 맞아요. scrape_interval이 15초니까 최소 4배인 1분 이상으로 설정하겠습니다."

주의사항

더 배우기