현대의 분산 시스템 환경에서 모니터링은 선택이 아닌 필수입니다. 시스템의 상태를 실시간으로 파악하고, 문제가 발생하기 전에 미리 대응할 수 있는 모니터링 체계를 구축하는 것은 안정적인 서비스 운영의 핵심입니다. 오늘은 현재 가장 널리 사용되는 모니터링 스택인 프로메테우스(Prometheus)와 그라파나(Grafana)를 활용한 모니터링 시스템 구축 방법을 알아보겠습니다.
프로메테우스는 SoundCloud에서 시작되어 현재는 CNCF(Cloud Native Computing Foundation)의 졸업 프로젝트로 관리되는 오픈소스 모니터링 시스템입니다. 다음과 같은 특징들이 프로메테우스를 특별하게 만듭니다.
Pull 기반 메트릭 수집 : 기존의 Push 방식과 달리, 프로메테우스는 타겟 시스템에서 메트릭을 가져오는 Pull 방식을 사용합니다. 이는 네트워크 토폴로지를 단순화하고, 모니터링 대상의 상태를 더 정확하게 파악할 수 있게 해줍니다.
시계열 데이터베이스 : 모든 데이터를 시간 기반으로 저장하여 트렌드 분석과 과거 데이터 조회가 용이합니다.
강력한 쿼리 언어(PromQL) : 복잡한 메트릭 계산과 집계를 가능하게 하는 전용 쿼리 언어를 제공합니다.
서비스 디스커버리 : Kubernetes, Docker, Consul 등 다양한 환경에서 동적으로 모니터링 대상을 발견할 수 있습니다.
그라파나는 데이터 시각화에 특화된 오픈소스 플랫폼으로, 프로메테우스와 완벽한 조합을 이룹니다.
직관적인 대시보드 : 드래그 앤 드롭으로 쉽게 대시보드를 구성할 수 있습니다.
다양한 데이터 소스 지원 : 프로메테우스뿐만 아니라 InfluxDB, Elasticsearch, MySQL 등 다양한 데이터 소스를 연결할 수 있습니다.
알림 기능 : 임계값 기반 알림을 설정하여 문제 상황을 즉시 감지할 수 있습니다.
풍부한 시각화 옵션 : 그래프, 게이지, 테이블, 히트맵 등 다양한 형태로 데이터를 표현할 수 있습니다.
프로메테우스와 그라파나 기반 모니터링 시스템의 기본 구조는 다음과 같습니다.
Docker를 사용한 간단한 설치 방법
# docker-compose.yml
version: '3.8'
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
ports:
- "9090:9090"
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
# prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node-exporter'
static_configs:
- targets: ['node-exporter:9100']
# docker-compose.yml에 추가
node-exporter:
image: prom/node-exporter:latest
container_name: node-exporter
ports:
- "9100:9100"
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc)($$|/)'
# docker-compose.yml에 추가
grafana:
image: grafana/grafana:latest
container_name: grafana
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=admin123
volumes:
- grafana-storage:/var/lib/grafana
volumes:
grafana-storage:
CPU 사용률
100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
메모리 사용률
(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100
디스크 사용률
(1 - (node_filesystem_avail_bytes / node_filesystem_size_bytes)) * 100
HTTP 요청 속도
rate(http_requests_total[5m])
응답 시간
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))
에러율
rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) * 100
효과적인 알림은 모니터링의 핵심입니다. AlertManager를 통해 다음과 같은 알림 규칙을 설정할 수 있습니다.
# alert.rules.yml
groups:
- name: system-alerts
rules:
- alert: HighCPUUsage
expr: 100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 5m
labels:
severity: warning
annotations:
summary: "High CPU usage on {{ $labels.instance }}"
description: "CPU usage is above 80% for more than 5 minutes"
- alert: HighMemoryUsage
expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 90
for: 5m
labels:
severity: critical
annotations:
summary: "High memory usage on {{ $labels.instance }}"
description: "Memory usage is above 90% for more than 5 minutes"
일관된 레이블링은 나중에 메트릭을 쿼리하고 집계하는 데 매우 중요합니다.
http_requests_total{method="GET", endpoint="/api/users", status="200", service="user-service"}
높은 카디널리티를 가진 레이블(사용자 ID, 세션 ID 등)은 피하고, 필요시 그룹핑하여 사용합니다.
개요 대시보드 : 전체 시스템 상태를 한눈에 파악
서비스별 대시보드 : 특정 서비스의 상세 메트릭
인프라 대시보드 : 서버, 네트워크, 스토리지 상태
프로메테우스와 그라파나를 활용한 모니터링 시스템은 현대적인 인프라 운영에 없어서는 안 될 도구입니다. 초기 설정은 복잡해 보일 수 있지만, 한 번 구축하면 시스템의 가시성과 안정성을 크게 향상시킬 수 있습니다.
무엇보다 중요한 것은 모니터링이 목적이 아니라 수단이라는 점입니다. 수집한 데이터를 바탕으로 실제 문제를 해결하고, 시스템을 개선하는 것이 진정한 모니터링의 가치입니다.