프로메테우스 그라파나 실전 가이드: 기본 대시보드가 안 알려주는 꿀팁

0
21
An advanced monitoring dashboard interface displaying real-time metrics of Prometheus and Grafana, optimizing an AI homelab server with NVIDIA RTX 3060 GPU tracking, cAdvisor container metrics, and customized PromQL alerts.
홈랩 인프라 및 로컬 AI 컴포넌트 감시를 위한 프로메테우스·그라파나 최종 연동 대시보드 구조
홈랩 모니터링 Prometheus Grafana 실전 가이드
Prometheus와 Grafana를 “설치만 하고 기본 대시보드만 보는 수준”에서 벗어나, 실제로 전문가들이 쓰는 설정·쿼리·대시보드 구성법까지 전부 다룹니다. 설치 자체는 다루지 않습니다 — 설치는 이미 검증된 방법이 따로 있으니 그걸 먼저 끝내고 오세요. 프로메테우스 그라파나 실전 가이드 시작합니다.
📌
설치는 여기서 — 이 글은 활용에만 집중합니다

Docker Compose 작성, 포트 설정, 컨테이너 실행까지의 설치 과정은

AI 서버 활용 및 튜닝 가이드 5편 §07

을 먼저 따라해주세요. 이 글은 설치가 끝난 다음, “그래서 이걸 어떻게 제대로 쓰는가”에만 집중합니다.

PART01

Prometheus 핵심 개념 — 이것부터 이해해야 설정이 보인다

모니터링 시스템을 설계할 때 가장 먼저 마주하는 거대한 갈림길이 바로 데이터를 보내는 주체가 누구인가입니다.

“Prometheus가 가서 가져온다”는 말은, 데이터를 가진 애플리케이션(Ex. 가상화 서버, GPU 익스포터, 웹 서비스 등)이 프로메테우스에게 데이터를 던져주는 게 아니라, 프로메테우스가 정해진 시간마다 각 서비스의 문을 두드려 “지금 상태가 어때?” 하고 받아오는 구조(Scraping)를 뜻합니다.

🛒 배달(Push)과 장보기(Pull)의 차이

기존의 전통적인 모니터링 시스템(구형 시스템이나 일부 APM)이 ‘배달’이라면, 프로메테우스는 ‘장보기’에 가깝습니다.

Push 방식 (배달): 애플리케이션들이 각자 타이머를 재고 있다가, “저 지금 CPU 80%예요!”, “저 지금 메모리 꽉 찼어요!”라며 중앙 모니터링 서버로 데이터를 계속 배달(Push)합니다.
Pull 방식 (장보기): 애플리케이션들은 그저 자기 집 앞마당(/metrics라는 웹 페이지)에 현재 상태를 적은 메모만 슥 올려둡니다. 그러면 Prometheus가 카트를 끌고 돌아다니며 그 메모를 수집(Pull)해 갑니다.

🧠 프로메테우스가 “가서 가져올 때” 생기는 3가지 강력한 이점

홈랩이나 AI 인프라 환경에서 이 Pull 방식은 단순한 ‘취향 차이’를 넘어 시스템의 생존을 결정하는 중요한 무기가 됩니다.

1. 중앙 서버의 과부하 방지 (주도권은 나에게)
Push 방식의 치명적인 약점은 트래픽이 몰릴 때 발생합니다. 만약 디도스(DDoS) 공격을 받거나 AI 추론 요청이 폭주하면, 수많은 컨테이너가 동시에 모니터링 서버로 데이터를 push하려 들 것입니다. 모니터링 서버가 먼저 뻗어버리는 불상사가 생기죠. 반면 Pull 방식은 프로메테우스가 자신의 체력(자원 상태)에 맞춰 5초든, 30초든 원하는 주기로 요청을 조절하기 때문에 모니터링 인프라 자체가 마비되는 일이 거의 없습니다.

2. “살아는 있니?” — 자연스러운 생사 확인 (Health Check)
Push 방식에서는 어떤 컨테이너가 조용할 때, ‘일이 없어서 조용한 건지’, ‘서버가 죽어서 말을 못 하는 건지’ 알기 어렵습니다. 하지만 Pull 방식은 프로메테우스가 직접 찌르는 구조이기 때문에, 요청을 보냈는데 찔리지 않거나(Connection Refused) 404 에러가 뜨면 그 즉시 “이 녀석 죽었구나!” 하고 감지할 수 있습니다. 프로메테우스 기본 메트릭인 up 메트릭이 바로 이 원리로 작동합니다.

3. 애플리케이션의 극단적인 단순화
모니터링 대상이 되는 서비스(ComfyUI, Dify, Node Exporter 등)는 프로메테우스 서버가 어디에 있는지, IP가 뭔지 알 필요가 없습니다. 그저 자기 포트(Ex. 9100)에 프로메테우스가 읽을 수 있는 형식의 텍스트만 띄워두면 끝입니다. 모니터링 서버의 IP가 바뀌더라도 개별 애플리케이션의 설정을 바꿀 필요 없이, 프로메테우스의 설정 파일(prometheus.yml)만 수정하면 됩니다.

💡
요약하자면

프로메테우스의 Pull 방식은 개별 서비스들에게 모니터링 전송 로직이라는 짐을 지우지 않고, 중앙 서버가 철저하게 통제된 주기 속에서 인프라 전체를 훑어 나가는 가장 안정적인 엔지니어링 선택지입니다.

혹시 현재 구축 중이거나 구상하고 계신 홈랩 환경에서, 프로메테우스가 데이터를 ‘가져가기’ 까다로운 환경(예: IP가 계속 바뀌는 가변 컨테이너나 외부 방화벽 뒤에 숨은 서비스)이 존재하나요?

Prometheus  ──(15초마다 직접 요청)──▶  node-exporter:9100/metrics
Prometheus  ──(15초마다 직접 요청)──▶  cadvisor:8092/metrics
Prometheus  ──(15초마다 직접 요청)──▶  nvidia-exporter:9835/metrics

🏷️ 메트릭의 구조 — 이름 + 라벨(Label)

모든 메트릭은 메트릭이름{라벨="값"} 숫자값 형태입니다. 라벨이 핵심입니다 — 같은 메트릭이라도 라벨로 잘게 쪼개서 구분할 수 있습니다.

실제 메트릭 예시
node_cpu_seconds_total{cpu="0",mode="idle"}  48291.2
node_cpu_seconds_total{cpu="1",mode="idle"}  47733.8
node_cpu_seconds_total{cpu="0",mode="user"}  1820.4
container_memory_usage_bytes{name="n8n"}     184320000
container_memory_usage_bytes{name="comfyui"} 2147483648

위처럼 CPU 코어별로, 컨테이너 이름별로 라벨이 자동으로 붙어서 나뉩니다. 이 라벨을 PromQL에서 필터링·집계하는 게 실력의 거의 전부입니다.

📐 4가지 메트릭 타입

타입설명예시
Counter계속 증가만 하는 값 (리셋 시 0으로). 누적 요청수, 누적 에러수 등http_requests_total
Gauge오르락내리락하는 값. 현재 상태nvidia_smi_temperature_gpu
Histogram값을 구간(bucket)별로 집계. 응답시간 분포 등http_request_duration_seconds_bucket
SummaryHistogram과 비슷하나 분위(quantile)를 서버 쪽에서 미리 계산rpc_duration_seconds
⚠️
Counter는 절대 값 그대로 보지 마세요

Counter는 계속 증가만 하는 누적값이라 “지금 초당 몇 번 일어나는지”를 알려주지 않습니다. 반드시 rate()increase() 함수로 감싸서 봐야 의미가 있습니다 — Part 3에서 자세히 다룹니다.

PART02

prometheus.yml 심화 설정 — 기본값 그대로 쓰지 마세요

① scrape_interval — Job마다 다르게 줄 수 있습니다

전역(global) 설정을 모든 job이 따르지만, 특정 job만 더 자주/덜 자주 수집하도록 개별 오버라이드가 가능합니다. GPU처럼 빠르게 바뀌는 값은 짧게, 디스크 용량처럼 느리게 바뀌는 값은 길게 주면 저장 공간을 아낍니다.

yaml — job별 scrape_interval 오버라이드
scrape_configs:
  - job_name: 'nvidia-gpu'
    scrape_interval: 5s        # GPU는 빠르게 변하니 5초마다
    static_configs:
      - targets: ['nvidia-exporter:9835']

  - job_name: 'node'
    scrape_interval: 30s       # CPU/RAM은 30초면 충분
    static_configs:
      - targets: ['host.docker.internal:9100']

② 라벨 직접 붙이기 — labels: 옵션

여러 서버를 모니터링할 때 “어느 서버 데이터인지” 구분하려면 라벨을 직접 추가합니다. 지금은 R730 한 대뿐이지만, 나중에 NAS나 다른 서버도 모니터링하게 되면 이게 필수입니다.

  - job_name: 'node'
    static_configs:
      - targets: ['host.docker.internal:9100']
        labels:
          server: 'r730'
          role: 'ai-main'

③ external_labels — Prometheus 인스턴스 자체에 라벨 달기

나중에 Prometheus를 여러 대 운영하거나, Grafana에서 여러 환경(운영/테스트)을 구분하고 싶을 때 유용합니다.

global:
  scrape_interval: 15s
  external_labels:
    environment: 'homelab'
    server_name: 'R730'

④ Recording Rules — 무거운 쿼리를 미리 계산해두기

대시보드에서 매번 무거운 PromQL을 실행하면 느려집니다. 자주 쓰는 복잡한 쿼리를 미리 계산해서 새로운 메트릭으로 저장해두면, 대시보드는 그 결과만 가볍게 조회합니다.

yaml — /mnt/data/00_infra/prometheus/recording_rules.yml
groups:
  - name: precomputed_metrics
    interval: 30s
    rules:
      # CPU 사용률(%) — 매번 계산하지 않고 미리 저장
      - record: instance:cpu_usage:rate5m
        expr: 100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

      # 컨테이너별 메모리 사용량(MB)
      - record: container:memory_usage:mb
        expr: container_memory_usage_bytes{name!=""} / 1024 / 1024

만든 다음 rule_files:alert_rules.yml과 같이 한 줄 추가하면 됩니다. 대시보드에서는 instance:cpu_usage:rate5m처럼 미리 계산된 이름으로 바로 조회합니다.

⑤ 데이터 보존 기간/용량 제한 (docker-compose.yml command 항목에 추가)

옵션설명추천값
--storage.tsdb.retention.time시간 기준 보존 (이 기간 지나면 자동 삭제)30d (홈랩 기준 충분)
--storage.tsdb.retention.size용량 기준 보존 (디스크 용량 한계 설정)10GB (디스크 적은 경우 병행 권장)
--web.enable-lifecycleAPI로 설정 리로드 가능 (재시작 없이 설정 반영)항상 켜기

--web.enable-lifecycle를 켜두면, prometheus.yml을 수정한 뒤 컨테이너를 재시작하지 않고도 아래 명령어 하나로 설정을 즉시 반영할 수 있습니다.

curl -X POST http://localhost:9090/-/reload
PART03

PromQL 실전 마스터 — 진짜 쓸모있는 쿼리 패턴 20선

PromQL은 처음엔 어려워 보이지만, 패턴 몇 개만 외우면 거의 모든 상황에 응용할 수 있습니다.

📈 비율(rate) 계열 — Counter를 다룰 때 필수

함수용도예시
rate()초당 평균 증가율 (긴 구간, 부드러운 그래프)rate(container_network_receive_bytes_total[5m])
irate()초당 증가율 (짧은 구간, 순간 변화에 민감)irate(node_disk_read_bytes_total[1m])
increase()구간 내 총 증가량 (비율 아니라 절댓값)increase(http_requests_total[1h])
💡

rate()irate() 둘 다 헷갈리면 그냥 rate()만 쓰세요. 대시보드용으로는 거의 항상 rate()가 더 안정적인 그래프를 보여줍니다. irate()는 알림(alert)처럼 즉각 반응이 중요할 때만 씁니다.

🖥️ 실전 쿼리 — CPU·RAM·디스크

PromQL
# CPU 사용률(%) — 코어 평균
100 - (avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

# CPU 사용률(%) — 코어별로 따로 보기
100 - (rate(node_cpu_seconds_total{mode="idle"}[5m]) * 100)

# RAM 사용률(%)
(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100

# 디스크 여유공간(GB)
node_filesystem_avail_bytes{mountpoint="/"} / 1024^3

# 디스크 I/O (초당 읽기 MB)
rate(node_disk_read_bytes_total[5m]) / 1024^2

🎮 실전 쿼리 — GPU (nvidia_gpu_exporter 기준)

# GPU 사용률(%)
nvidia_smi_utilization_gpu_ratio * 100

# VRAM 사용량(GB)
nvidia_smi_memory_used_bytes / 1024^3

# VRAM 사용률(%)
(nvidia_smi_memory_used_bytes / nvidia_smi_memory_total_bytes) * 100

# GPU 온도
nvidia_smi_temperature_gpu

# GPU 전력 소비(W)
nvidia_smi_power_draw_watts

# 지난 1시간 GPU 온도 최고값 (스파이크 확인용)
max_over_time(nvidia_smi_temperature_gpu[1h])

🐳 실전 쿼리 — 컨테이너 (cAdvisor 기준)

# 컨테이너별 메모리 사용량 순위 (높은 순)
topk(5, container_memory_usage_bytes{name!=""})

# 컨테이너별 CPU 사용률(%)
rate(container_cpu_usage_seconds_total{name!=""}[5m]) * 100

# 특정 컨테이너만 (n8n)
container_memory_usage_bytes{name="n8n"} / 1024^2

# 컨테이너 재시작 횟수 (지난 1시간)
increase(container_last_seen{name!=""}[1h])

🔧 집계 연산자 — sum, avg, max, topk, bottomk

연산자용도
sum() by (label)라벨별로 그룹화해서 합산
avg() by (label)라벨별 평균
topk(N, ...)상위 N개만 (리소스 많이 쓰는 컨테이너 찾기에 최적)
bottomk(N, ...)하위 N개만
count()몇 개가 매칭되는지 개수
# 컨테이너 이름별로 CPU 합산 (코어 여러 개일 때 합치기)
sum(rate(container_cpu_usage_seconds_total[5m])) by (name)

# 현재 떠있는 컨테이너 개수
count(container_last_seen{name!=""})

🔍 필터링 연산자 정리

연산자의미예시
=정확히 일치{name="n8n"}
!=일치하지 않음{name!=""} (빈 값 제외, 거의 항상 필요)
=~정규식 일치{name=~"n8n|dify.*"}
!~정규식 불일치{mode!~"idle|iowait"}
PART04

Prometheus 알림(Alert) 제대로 쓰기

⚠️ Alert Rule만으로는 “알림”이 안 갑니다

🚨
가장 많이 오해하는 부분

alert_rules.yml은 Prometheus 안에서 “조건이 맞는지 평가”만 합니다. 실제로 텔레그램·이메일·슬랙으로 알림을 “보내는” 역할은 별도 프로그램인 Alertmanager가 합니다. Alertmanager 없이는 Prometheus 웹 화면의 Alerts 탭에서 빨간불만 켜질 뿐, 아무에게도 알림이 가지 않습니다.

Alert Rule 문법 완전 분해

yaml
- alert: GPUTemperatureHigh        # ① 알림 이름
  expr: nvidia_smi_temperature_gpu > 85   # ② 조건 (PromQL)
  for: 2m                          # ③ 이 시간 동안 계속 참이어야 발동 (스파이크 무시)
  labels:
    severity: warning              # ④ 심각도 (나중에 라우팅에 사용)
  annotations:
    summary: "GPU 온도 위험"        # ⑤ 알림 제목
    description: "{{ $value }}도"  # ⑥ 알림 본문, $value로 실제 측정값 삽입
⚠️
for: 절을 꼭 쓰세요

for 없이 조건이 맞는 즉시 알림이 발동하면, GPU 온도가 잠깐 튀었다가 바로 내려가는 “노이즈”에도 알림이 옵니다. 1~5분 정도 for를 주면 진짜 지속되는 문제만 걸러집니다.

Alertmanager 최소 구성 — 텔레그램으로 알림 받기

이 시리즈에서 이미 n8n에 텔레그램 봇을 연결해두셨다면, Alertmanager의 Webhook 기능으로 그 봇을 재활용할 수 있습니다.

yaml — docker-compose.yml에 추가 (검증 전)
  alertmanager:
    image: prom/alertmanager:latest
    container_name: alertmanager
    restart: unless-stopped
    ports:
      - "9093:9093"
    volumes:
      - /mnt/data/00_infra/alertmanager/alertmanager.yml:/etc/alertmanager/alertmanager.yml:ro
    networks:
      - ai-common-net
yaml — alertmanager.yml (텔레그램 직접 연동)
route:
  receiver: 'telegram'
  group_wait: 30s
  repeat_interval: 1h

receivers:
  - name: 'telegram'
    telegram_configs:
      - bot_token: 'YOUR_BOT_TOKEN'
        chat_id: YOUR_CHAT_ID
        message: '{{ .CommonAnnotations.summary }}: {{ .CommonAnnotations.description }}'

등록 후 prometheus.yml에 아래처럼 alertmanager 위치를 알려줘야 합니다.

alerting:
  alertmanagers:
    - static_configs:
        - targets: ['alertmanager:9093']
PART05

Prometheus 웹 UI — Grafana 없이도 이만큼 보입니다

Grafana로 넘어가기 전에, Prometheus 자체 웹 화면(:9090)을 제대로 쓰는 법부터 익히면 문제 진단이 훨씬 빨라집니다.

메뉴용도언제 쓰나
Graph (검색창)PromQL 쿼리 직접 입력해서 그래프/테이블로 즉시 확인Grafana 패널 만들기 전 쿼리 미리 테스트
Status → Targets모든 수집 대상의 UP/DOWN 상태, 마지막 스크레이프 시각, 에러 메시지데이터가 안 보일 때 1번째로 확인
Status → Rules등록된 알림 규칙과 현재 상태(정상/pending/firing)알림이 왜 안 오는지 확인
Status → Configuration현재 실제로 로드된 설정 전체 (오타 확인용)설정이 반영 안 된 것 같을 때
Status → TSDB Status저장된 시리즈 개수, 가장 많은 라벨/메트릭 순위디스크 용량이 갑자기 커질 때 원인 찾기
Alerts현재 발동 중인 알림 목록지금 뭐가 문제인지 한눈에
실전 디버깅 순서

대시보드에 데이터가 안 보이면 → ① Status→Targets에서 해당 서비스가 UP인지 → ② UP인데도 안 보이면 Graph에서 PromQL을 직접 쳐서 데이터가 있는지 → ③ 데이터는 있는데 Grafana에만 안 보이면 Grafana 데이터소스 설정 문제. 이 순서로 가면 원인을 거의 항상 30초 안에 찾습니다.

PART06

Grafana 데이터소스 — 추가 옵션까지 제대로 설정하기

기본 연결(URL 입력 후 Save & Test)만 하고 끝내는 분들이 많은데, 아래 추가 옵션들을 켜두면 훨씬 안정적이고 빠른 대시보드가 됩니다.

Connections → Data sources → Prometheus → 설정 화면에서

옵션위치추천 설정이유
Scrape intervalHTTP 섹션 하단15s (prometheus.yml과 동일하게)다르면 그래프가 들쑥날쑥하게 보임
Query timeoutHTTP 섹션60s무거운 쿼리(긴 기간 조회) 타임아웃 방지
HTTP MethodHTTP 섹션POST긴 PromQL 쿼리는 URL 길이 제한(GET)에 걸릴 수 있음
Default맨 아래켜기 (1개뿐이면 자동)패널 만들 때 매번 데이터소스 선택 안 해도 됨
Prometheus typeType and versionPrometheus 자동감지 확인버전별 PromQL 기능 차이 자동 대응

여러 데이터소스 운영 시 — 폴더로 정리

나중에 Loki(로그)나 다른 Prometheus 인스턴스를 추가하게 되면, Connections → Data sources 목록이 길어집니다. 데이터소스 자체엔 폴더 기능이 없지만, 대시보드 쪽(Dashboards)에는 폴더 기능이 있으니 “AI서버”, “네트워크” 처럼 폴더로 미리 나눠두는 걸 권장합니다.

PART07

Grafana 패널 — 타입별로 언제 뭘 써야 하는지

대시보드를 만들 때 “Add panel” 누르고 패널 타입을 고르는 순간 많이들 막힙니다. 용도별로 정리했습니다.

패널 타입가장 잘 맞는 용도실전 예시
Time series시간에 따른 변화 추세를 보고 싶을 때 (가장 기본)CPU 사용률 그래프, GPU 온도 추이
Gauge“지금 한 값”을 직관적으로, 임계값 색상과 함께현재 GPU 온도 (초록→노랑→빨강)
Bar gauge여러 항목을 막대로 한눈에 비교컨테이너별 메모리 사용량 순위
Stat숫자 하나를 크게, 트렌드 화살표와 함께현재 떠있는 컨테이너 개수
Table여러 라벨/값을 표 형태로 정리컨테이너별 CPU·메모리·상태 종합표
Heatmap분포(히스토그램) 시각화응답시간 분포 (대부분 몇 ms대인지)
State timeline시간대별 상태(켜짐/꺼짐) 변화컨테이너 Up/Down 이력

Gauge/Stat에서 임계값(Threshold) 색상 설정하는 법

1
패널 우측 패널 옵션 → Standard options → Thresholds
기본값 “Base”(초록) 외에 “+ Add threshold”로 단계 추가
2
GPU 온도 기준 예시
Base(초록) → 70 이상 노랑(warning) → 85 이상 빨강(critical)
3
Unit(단위) 설정도 같이
Standard options → Unit → “Temperature → Celsius” 선택하면 숫자 옆에 °C가 자동으로 붙음

자주 쓰는 Unit 설정 모음

데이터 종류Unit 검색어
온도celsius
퍼센트(0~100 값)percent (0-100)
바이트→자동단위(KB/MB/GB)bytes(IEC)
초당 바이트(네트워크)bytes/sec(IEC)
와트(전력)watt
초 단위 시간seconds

Transform 기능 — 쿼리 결과를 가공하기

패널 편집 화면 상단 “Transform” 탭에서, PromQL을 다시 안 짜고도 결과를 가공할 수 있습니다.

Transform용도
Rename by regex범례 이름을 깔끔하게 정리 (예: 긴 컨테이너ID → 서비스명만)
Sort byTable 패널에서 특정 컬럼 기준 정렬
Filter by value특정 값 이상/이하인 데이터만 표시 (노이즈 제거)
Add field from calculation기존 필드들로 새 계산 컬럼 추가 (예: 사용량/전체 = 비율)
PART08

Variables(변수) — 대시보드 하나로 모든 걸 보기

컨테이너마다, GPU마다 똑같은 대시보드를 복제하지 마세요. 변수(Variable) 하나로 드롭다운 선택만 바꿔서 같은 패널을 재사용할 수 있습니다.

실전 예시 — “컨테이너 선택” 드롭다운 만들기

1
대시보드 설정(⚙️) → Variables → “+ Add variable”
Name: container_name
2
Type: Query
Data source: Prometheus 선택
3
Query 칸에 라벨 목록을 가져오는 쿼리 입력
label_values(container_memory_usage_bytes, name) → 모든 컨테이너 이름이 드롭다운 목록이 됨
4
패널의 PromQL에서 변수 사용
고정값 {name="n8n"} 대신 {name="$container_name"}로 작성

이렇게 하면 대시보드 상단에 드롭다운이 생기고, 거기서 n8n·dify·comfyui 중 고르면 같은 패널들이 그 컨테이너 데이터로 바로 바뀝니다. 컨테이너마다 따로 대시보드 만들 필요가 없어집니다.

Multi-value — 여러 개 동시 선택도 가능

Variable 설정에서 “Multi-value” 옵션을 켜면 체크박스 형태로 여러 컨테이너를 동시에 선택해서 비교할 수 있습니다. “Include All option”을 같이 켜면 “전체 선택”도 가능합니다.

PART09

Grafana 자체 알림(Unified Alerting) — Alertmanager 없이도 가능

Part 4에서 다룬 Prometheus+Alertmanager 조합 대신, Grafana 자체 알림 기능(Unified Alerting)을 쓰면 별도 컨테이너 없이도 텔레그램·Discord·Slack 알림이 가능합니다. 홈랩 규모에서는 이 방법이 훨씬 간단합니다.

① Contact point 만들기 — 텔레그램

1
좌측 메뉴 → Alerting → Contact points → “+ Add contact point”
Integration: Telegram 선택
2
BOT API Token / Chat ID 입력
n8n 만들 때 이미 발급받은 봇 토큰을 그대로 재사용 가능
3
“Test” 버튼으로 즉시 발송 테스트
텔레그램에 테스트 메시지가 오면 연결 확인 완료

② Alert rule 만들기 — Prometheus 쪽 yml 안 만지고 UI에서

1
Alerting → Alert rules → “+ New alert rule”
조건이 될 PromQL 쿼리 입력 (예: nvidia_smi_temperature_gpu)
2
조건 설정 — “Threshold” 선택
“IS ABOVE 85” 같이 직관적인 UI로 조건 입력 (PromQL 비교문 직접 안 써도 됨)
3
Evaluation behavior — “Pending period” 설정
Prometheus의 for:와 동일한 역할. 2분 정도 권장
4
Notifications — ①에서 만든 Contact point 선택
“Save rule”로 완료
💡
Prometheus alert_rules.yml vs Grafana Alert rule, 뭘 써야 하나?

둘 다 비슷한 일을 합니다. 이미 prometheus.yml에 alert_rules.yml을 설정해두셨다면 그대로 두고, Grafana에서는 Notification Policy만 추가로 연결하는 게 중복 작업을 줄입니다. 처음부터 새로 만드는 경우라면 UI가 훨씬 편한 Grafana Alert rule을 추천합니다.

PART10

Annotations — “이 시점에 뭐가 있었는지” 그래프에 표시하기

GPU 사용률이 갑자기 튄 시점에 “이때 ComfyUI로 영상 생성을 돌렸다” 같은 메모를 그래프 위에 직접 남길 수 있습니다. 배포 시점, 재시작 시점을 표시해두면 나중에 원인 추적이 훨씬 쉬워집니다.

1
그래프에서 표시하고 싶은 시점을 Ctrl+클릭(또는 드래그)
“Add annotation” 팝업이 뜸
2
메모 입력 후 저장
이후 같은 대시보드를 보는 모든 사람에게 그 시점에 세로선+메모가 보임

자동 Annotation — Alert 발동 시점 자동 표시

대시보드 설정 → Annotations에서 “Alert state changes” 옵션을 켜두면, 알림이 발동/해제된 시점이 그래프에 자동으로 표시됩니다. 수동으로 기록할 필요가 없어집니다.

PART11

대시보드 운영 팁 — Row, 폴더, 공유, 백업

Row로 패널 그룹 접기/펼치기

패널이 10개 넘어가면 한 화면에 다 보기 힘듭니다. “Row”를 추가하면 “GPU”, “CPU/RAM”, “컨테이너” 같은 섹션으로 나눠서 접고 펼칠 수 있습니다. Add panel → Row 선택 → 패널들을 그 Row 안으로 드래그.

대시보드를 폴더로 정리

Dashboards → New folder로 “AI서버 모니터링” 폴더를 만들고, GPU 대시보드·시스템 대시보드·컨테이너 대시보드를 그 안에 모아두면 나중에 대시보드가 늘어나도 안 헤맵니다.

대시보드 JSON으로 백업/공유

대시보드 설정(⚙️) → JSON Model에서 전체 구성을 JSON으로 복사할 수 있습니다. 직접 만든 대시보드는 이 JSON을 따로 백업해두세요 — Grafana 컨테이너 데이터가 날아가도 이 JSON으로 즉시 복원 가능합니다.

⚠️
grafana_data 볼륨만 믿지 마세요

직접 만든 대시보드는 이 시리즈의 백업 스크립트(backup.sh)가 자동으로 백업하는 범위에 포함되도록, Grafana 데이터 폴더도 tar로 묶는 단계를 추가하는 걸 권장합니다. 또는 위 JSON Export를 주기적으로 별도 저장하세요.

Playlist — 여러 대시보드를 자동 순환 표시

거실 모니터나 별도 화면에 여러 대시보드를 자동으로 돌려가며 보여주고 싶을 때, Dashboards → Playlists에서 “어떤 대시보드들을, 몇 초마다 순환”할지 정하면 자동 슬라이드쇼처럼 작동합니다.

PART12

AI 서버 특화 — 바로 적용 가능한 추천 설정 모음

지금까지 배운 걸 실제로 이 홈랩 환경에 적용한다면, 아래 구성을 추천합니다.

📋 추천 대시보드 구조 (Row 4개)

Row패널타입쿼리
GPUGPU 온도Gaugenvidia_smi_temperature_gpu
VRAM 사용률Bar gauge(nvidia_smi_memory_used_bytes/nvidia_smi_memory_total_bytes)*100
GPU 사용률 추이Time seriesnvidia_smi_utilization_gpu_ratio*100
시스템CPU/RAM 추이Time seriesPart 3 쿼리 2개 같은 패널에
디스크 여유공간Statnode_filesystem_avail_bytes{mountpoint="/"}/1024^3
컨테이너메모리 Top 5Bar gaugetopk(5, container_memory_usage_bytes{name!=""})
전체 컨테이너 상태표Tablecontainer_last_seen{name!=""}
알림현재 발동중 알림Alert list 패널

🎯 임계값 추천표 (Gauge 색상 기준)

지표초록(정상)노랑(주의)빨강(위험)
GPU 온도< 70°C70~85°C> 85°C
VRAM 사용률< 80%80~95%> 95%
RAM 사용률< 75%75~90%> 90%
디스크 사용률< 70%70~85%> 85%

🔔 알림 추천 — 텔레그램으로 받을 것만 추려보기

모든 변화에 알림을 받으면 금방 무시하게 됩니다. 아래 3개 정도만 우선 연결하는 걸 추천합니다.

  • !GPU 온도 85도 이상 2분 지속 — 하드웨어 보호 최우선
  • !VRAM 95% 이상 5분 지속 — OOM 직전 경고
  • !디스크 85% 이상 — 백업 실패나 로그 폭증 조기 발견
PART13

내 환경 맞춤 모니터링 — ComfyUI·RTX 3060 OC·Dify·Firecrawl·WordPress·Open WebUI

⚠️
이 6개 서비스 대부분은 자체 Prometheus 메트릭이 없습니다

ComfyUI·Dify·Firecrawl·Open WebUI·WordPress는 /metrics 엔드포인트를 직접 제공하지 않습니다. 대신 이미 떠있는 cAdvisor(컨테이너별)와 nvidia-exporter(GPU)를 라벨로 필터링하는 것만으로 실용적인 수준의 모니터링이 가능합니다. 아래는 그 방법입니다.

🎨 ① ComfyUI — GPU 점유 시점과 컨테이너 리소스를 같이 본다

ComfyUI 자체엔 메트릭 엔드포인트가 없지만, “ComfyUI가 돌 때 GPU가 얼마나 쓰이는지”는 cAdvisor + nvidia-exporter 조합으로 충분히 보입니다. 생성 작업 중 VRAM이 얼마나 차오르는지, 컨테이너 자체의 CPU/RAM은 정상인지를 같은 화면에 겹쳐 보면 충분합니다.

PromQL — ComfyUI 전용 패널
# ComfyUI 컨테이너 메모리(시스템 RAM, VRAM 아님)
container_memory_usage_bytes{name="comfyui"} / 1024^3

# ComfyUI 컨테이너 CPU 사용률(%)
rate(container_cpu_usage_seconds_total{name="comfyui"}[2m]) * 100

# ComfyUI 네트워크 I/O (모델 다운로드·이미지 입출력 확인용)
rate(container_network_transmit_bytes_total{name="comfyui"}[5m]) / 1024^2
💡

GPU 사용률 패널(nvidia_smi_utilization_gpu_ratio)과 위 ComfyUI CPU 패널을 같은 Row에 나란히 두면, “GPU는 90% 찍는데 ComfyUI CPU는 5%다” 같은 식으로 실제로 GPU 작업 중인지 한눈에 교차 확인됩니다.

🎮 ② RTX 3060 OC 12GB — 이 카드 스펙에 맞춘 정밀 임계값

RTX 3060의 정격 TGP는 170W이고, 8핀 커넥터+PCIe 슬롯 조합상 최대 225W까지 헤드룸이 있습니다(OC 모델들이 보통 이 여유를 씁니다). 범용 임계값 대신 이 카드에 맞춘 값을 쓰세요.

지표정상주의위험비고
전력 소비(W)< 170W170~195W> 195WOC 헤드룸(225W) 대비 87% 지점을 위험선으로
VRAM 사용률< 83%83~95%> 95%12GB 기준 — 10GB 넘으면 주의(83%)
GPU 온도< 70°C70~83°C> 83°CAmpere 권장 한계 약 85~88°C보다 여유있게
팬 속도< 70%70~85%> 85%지속적으로 높으면 케이스 환기 점검 필요
PromQL — RTX 3060 OC 전용 쿼리
# 전력 소비를 OC 헤드룸(225W) 대비 비율로 — 임계값 색상 설정에 직접 활용
(nvidia_smi_power_draw_watts / 225) * 100

# 팬 속도(%) — 지속적으로 높으면 발열/먼지 점검 신호
nvidia_smi_fan_speed_ratio * 100

# GPU 코어 클럭 (OC가 실제로 유지되는지 확인)
nvidia_smi_clocks_current_graphics_clock

# 메모리 클럭 (12GB GDDR6 OC 유지 확인)
nvidia_smi_clocks_current_memory_clock
⚠️
exporter 버전에 따라 일부 메트릭명이 다를 수 있습니다

위 클럭·팬 메트릭은 utkuozdemir/nvidia_gpu_exporter 버전에 따라 이름이 조금씩 다를 수 있습니다. Prometheus Graph 화면에서 nvidia_까지만 입력하면 자동완성으로 실제 사용 가능한 전체 메트릭 목록이 나옵니다 — 거기서 정확한 이름을 확인하세요.

🤖 ③ Dify — 컨테이너 6개 중 어디가 문제인지 구분해서 본다

Dify는 컨테이너 하나가 아니라 dify-api·dify-worker·dify-web·dify-plugin-daemon·dify-sandbox·dify-nginx 6개로 구성됩니다. 정규식으로 한 번에 모아보면서, 특히 plugin_daemon은 따로 떼서 보는 걸 추천합니다 (Ollama 연동 문제가 실제로 가장 많이 나는 지점).

PromQL — Dify 전용 패널
# Dify 컨테이너 전체 메모리 합산
sum(container_memory_usage_bytes{name=~"dify-.*"}) / 1024^3

# Dify 컨테이너별로 나눠서 (Table 패널 추천)
container_memory_usage_bytes{name=~"dify-.*"} / 1024^2

# plugin_daemon만 따로 — Ollama 연동 이슈 시 여기부터 확인
rate(container_cpu_usage_seconds_total{name="dify-plugin-daemon"}[2m]) * 100

# dify-api 재시작 감지 (API 장애 조기 발견)
changes(container_last_seen{name="dify-api"}[10m])

🔥 ④ Firecrawl — Playwright 컨테이너가 제일 무겁습니다

Firecrawl도 firecrawl-api·firecrawl-playwright·firecrawl-redis-db·firecrawl-pg-db·firecrawl-rabbitmq 등 여러 컨테이너입니다. 실제 브라우저를 띄워서 크롤링하는 firecrawl-playwright가 메모리를 가장 많이 먹는 지점이라 별도 패널로 감시할 가치가 있습니다.

PromQL — Firecrawl 전용 패널
# Firecrawl 전체 컨테이너 메모리
sum(container_memory_usage_bytes{name=~"firecrawl-.*"}) / 1024^3

# Playwright만 따로 — 크롤링 중 메모리 누수 감시
container_memory_usage_bytes{name="firecrawl-playwright"} / 1024^2

# Firecrawl API CPU — 크롤 요청이 몰릴 때 확인
rate(container_cpu_usage_seconds_total{name="firecrawl-api"}[2m]) * 100
💡

대량 크롤링 작업을 돌릴 계획이라면, firecrawl-playwright 메모리 패널에 Stat 패널 + “지난 1시간 최고값”(max_over_time(...[1h]))을 추가해두면, 작업 끝나고 메모리가 제대로 회수됐는지(누수 여부) 바로 확인됩니다.

📰 ⑤ WordPress(agibop.com) — 이건 컨테이너가 아니라 외부 사이트입니다

🚨
cAdvisor로는 안 보입니다

WordPress(agibop.com)는 R730의 Docker 컨테이너가 아니라 외부에 호스팅된 별도 사이트입니다. 그래서 cAdvisor·nvidia-exporter로는 절대 안 보이고, “이 사이트가 지금 살아있는지·응답이 느린지”를 외부에서 HTTP로 직접 확인하는 방식이 필요합니다.

두 가지 방법이 있습니다. 이미 이 시리즈에 있는 Uptime Kuma가 압도적으로 더 간단합니다.

방법난이도장점
Uptime Kuma (추천)★☆☆ 쉬움URL만 등록하면 끝, 자체 알림 기능 내장, 별도 Prometheus 설정 불필요
Prometheus blackbox_exporter★★★ 복잡Grafana 한 화면에 GPU·서버랑 같이 보고 싶을 때만 가치 있음
1
Uptime Kuma 접속(:3005) → “+ Add New Monitor”
Monitor Type: HTTP(s) · URL: https://agibop.com
2
Heartbeat Interval: 60초 정도로 설정
너무 짧으면 호스팅사에서 봇으로 인식할 수 있음
3
Notifications에 텔레그램 봇 연결
다운 감지 시 즉시 알림 — n8n 텔레그램 봇 토큰 재사용 가능

Grafana 한 화면에 굳이 같이 보고 싶다면, Uptime Kuma가 자체적으로 /metrics Prometheus 엔드포인트를 제공하니(설정에서 활성화) Prometheus job으로 추가해서 끌어올 수도 있습니다. 처음엔 Uptime Kuma 자체 대시보드만으로 충분합니다.

💬 ⑥ Open WebUI — 메모리 증가 추세를 지켜보세요

Open WebUI도 자체 메트릭은 없지만, 대화 기록이 쌓이면서 메모리가 천천히 늘어나는 패턴이 있을 수 있어 장기 추세를 보는 게 의미 있습니다.

PromQL — Open WebUI 전용 패널
# Open WebUI 메모리 — Time series로 길게(7일) 보면서 추세 확인
container_memory_usage_bytes{name="open-webui"} / 1024^2

# 컨테이너 재시작 여부 (멈춤·크래시 조기 발견)
changes(container_last_seen{name="open-webui"}[1h])
💡

위 메모리 패널의 시간 범위를 7일로 늘려서 봤을 때 계단식으로 꾸준히 우상향한다면 메모리 누수 의심 신호입니다. 톱니파(올랐다 내렸다 반복)면 정상적인 사용 패턴입니다.

🗂️ 이 6개 통합 Row 하나로 만들기

지금까지 만든 대시보드에 “내 서비스” Row를 새로 추가하고, 위 쿼리들을 한 곳에 모아두면 매일 확인할 화면이 완성됩니다.

패널타입쿼리 핵심
ComfyUI ↔ GPU 사용률 비교Time series (2개 라인)ComfyUI CPU + GPU 사용률 겹쳐보기
RTX 3060 전력(OC 헤드룸 대비%)Gaugepower_draw_watts/225*100
Dify 6개 컨테이너 메모리Table{name=~"dify-.*"}
Firecrawl Playwright 메모리Stat (1h 최고값 병기)name="firecrawl-playwright"
agibop.com 상태Uptime Kuma 자체 화면 (또는 임베드)
Open WebUI 메모리 7일 추세Time series (긴 기간)name="open-webui"
PART14

마무리 체크리스트

  • prometheus.yml에 job별 scrape_interval 적절히 분리했는가
  • retention.time/size 디스크 용량 고려해서 설정했는가
  • Grafana 데이터소스에 timeout·HTTP Method(POST) 설정했는가
  • 최소 1개 이상 대시보드에 Variable(변수)로 컨테이너 선택 가능하게 만들었는가
  • GPU 온도·VRAM·디스크 최소 3개는 텔레그램 알림 연결했는가
  • 직접 만든 대시보드 JSON을 백업해뒀는가
  • RTX 3060 OC 전력을 헤드룸(225W) 대비 비율로 설정했는가
  • WordPress(agibop.com)는 Uptime Kuma로 별도 등록했는가
🎉
여기까지 했다면

설치만 끝낸 수준이 아니라, 실제로 GPU 온도·VRAM·컨테이너 상태를 실시간으로 추적하고 문제 발생 시 텔레그램으로 먼저 알게 되는 운영 가능한 모니터링 체계를 갖추신 겁니다.

Leave A Reply

Please enter your comment!
Please enter your name here