모니터링: Prometheus + Grafana

Kubernetes 메트릭 수집, 시각화, 알림 시스템 구축


Kubernetes 메트릭 수집, 시각화, 알림 시스템 구축

목표: 프로덕션급 모니터링 스택을 구축하고 운영할 수 있는 수준


📊 Prometheus

개요

graph TB
    subgraph "Prometheus 아키텍처"
        PROM["🎯 Prometheus"] -->|"수집"| TARGETS["📊 Targets"]
        PROM -->|"저장"| TSDB["🗄️ TSDB"]
        PROM -->|"알림"| ALERT["🚨 Alertmanager"]
        
        TARGETS -->|"/metrics"| APP["📦 Application"]
        TARGETS -->|"API"| K8S["🔷 Kubernetes API"]
        TARGETS -->|"cAdvisor"| NODE["💻 Node Exporter"]
    end

특징:

  • Pull 기반 메트릭 수집
  • PromQL 쿼리 언어
  • 시계열 데이터베이스 (TSDB)
  • 서비스 디스커버리

🛠️ 설치

Prometheus Operator

# Prometheus Operator 설치
kubectl apply -f https://github.com/prometheus-operator/prometheus-operator/releases/latest/download/bundle.yaml

# 또는 Helm
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm install prometheus prometheus-community/kube-prometheus-stack

ServiceMonitor

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: my-app-metrics
  labels:
    release: prometheus
spec:
  selector:
    matchLabels:
      app: my-app
  endpoints:
  - port: metrics
    interval: 30s
    path: /metrics

📈 메트릭 수집

애플리케이션 메트릭

# Python 예시 (prometheus_client)
from prometheus_client import Counter, Histogram, start_http_server

# 카운터
requests_total = Counter('http_requests_total', 'Total requests', ['method', 'status'])

# 히스토그램
request_duration = Histogram('http_request_duration_seconds', 'Request duration')

# 사용
requests_total.labels(method='GET', status='200').inc()
request_duration.observe(0.5)

# 메트릭 서버 시작
start_http_server(8000)

Kubernetes 메트릭

# 노드 메트릭
kubectl top nodes

# Pod 메트릭
kubectl top pods

# 컨테이너 메트릭
kubectl top pods --containers

🔍 PromQL

기본 쿼리

# CPU 사용률
rate(container_cpu_usage_seconds_total{container!=""}[5m])

# 메모리 사용량
container_memory_usage_bytes{container!=""}

# HTTP 요청률
rate(http_requests_total[5m])

# 95번째 백분위 응답 시간
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))

# Pod 재시작 횟수
increase(kube_pod_container_status_restarts_total[1h])

고급 쿼리

# CPU 사용률이 80%를 초과하는 Pod
rate(container_cpu_usage_seconds_total[5m]) / 
kube_pod_container_resource_limits{resource="cpu"} > 0.8

# 메모리 사용률이 90%를 초과하는 노드
(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / 
node_memory_MemTotal_bytes > 0.9

# 디스크 사용률
(node_filesystem_size_bytes{mountpoint="/"} - node_filesystem_avail_bytes{mountpoint="/"}) / 
node_filesystem_size_bytes{mountpoint="/"}

🚨 알림

PrometheusRule

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: my-app-alerts
  labels:
    release: prometheus
spec:
  groups:
  - name: my-app
    rules:
    - alert: HighErrorRate
      expr: rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) > 0.1
      for: 5m
      labels:
        severity: critical
      annotations:
        summary: "High error rate detected"
        description: "Error rate is {{ $value | humanizePercentage }}"
    
    - alert: HighLatency
      expr: histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m])) > 1
      for: 10m
      labels:
        severity: warning
      annotations:
        summary: "High latency detected"
        description: "95th percentile latency is {{ $value }}s"
    
    - alert: PodCrashLooping
      expr: rate(kube_pod_container_status_restarts_total[15m]) > 0
      for: 5m
      labels:
        severity: critical
      annotations:
        summary: "Pod is crash looping"
        description: "Pod {{ $labels.pod }} is restarting frequently"

Alertmanager 설정

apiVersion: monitoring.coreos.com/v1alpha1
kind: AlertmanagerConfig
metadata:
  name: my-app-alerts
spec:
  route:
    groupBy: ['alertname', 'severity']
    groupWait: 30s
    groupInterval: 5m
    repeatInterval: 12h
    receiver: 'slack'
  receivers:
  - name: 'slack'
    slackConfigs:
    - apiURL:
        name: slack-webhook
        key: url
      channel: '#alerts'
      title: '{{ .GroupLabels.alertname }}'
      text: '{{ .CommonAnnotations.description }}'

📊 Grafana

대시보드

apiVersion: integreatly.org/v1alpha1
kind: GrafanaDashboard
metadata:
  name: my-app-dashboard
  labels:
    app: grafana
spec:
  json: |
    {
      "title": "My App Dashboard",
      "panels": [
        {
          "title": "Request Rate",
          "type": "graph",
          "targets": [
            {
              "expr": "rate(http_requests_total[5m])",
              "legendFormat": "{{method}} {{status}}"
            }
          ]
        },
        {
          "title": "Latency",
          "type": "graph",
          "targets": [
            {
              "expr": "histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))",
              "legendFormat": "95th percentile"
            }
          ]
        }
      ]
    }

주요 대시보드

대시보드내용
Node Exporter노드 리소스 사용량
Kubernetes Cluster클러스터 전체 상태
Kubernetes PodsPod 리소스 사용량
Kubernetes Networking네트워크 트래픽
Application애플리케이션 메트릭

📋 체크리스트

  • Prometheus Operator 설치
  • ServiceMonitor 설정
  • 애플리케이션 메트릭 노출
  • PromQL 기본 쿼리
  • 알림 규칙 작성
  • Alertmanager 설정
  • Grafana 대시보드 생성
  • 주요 메트릭 모니터링

🔗 관련 노트

  • 03-06-로깅-EFK-스택 — 로그 수집
  • 03-07-분산추적 — 분산 추적
  • 02-11-Pod-실패-원인-분석 — 문제 해결

마지막 업데이트: 2026-06-01