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 |
| Summary | Histogram과 비슷하나 분위(quantile)를 서버 쪽에서 미리 계산 | rpc_duration_seconds |
Counter는 계속 증가만 하는 누적값이라 “지금 초당 몇 번 일어나는지”를 알려주지 않습니다. 반드시 rate()나 increase() 함수로 감싸서 봐야 의미가 있습니다 — Part 3에서 자세히 다룹니다.
prometheus.yml 심화 설정 — 기본값 그대로 쓰지 마세요
① scrape_interval — Job마다 다르게 줄 수 있습니다
전역(global) 설정을 모든 job이 따르지만, 특정 job만 더 자주/덜 자주 수집하도록 개별 오버라이드가 가능합니다. GPU처럼 빠르게 바뀌는 값은 짧게, 디스크 용량처럼 느리게 바뀌는 값은 길게 주면 저장 공간을 아낍니다.
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을 실행하면 느려집니다. 자주 쓰는 복잡한 쿼리를 미리 계산해서 새로운 메트릭으로 저장해두면, 대시보드는 그 결과만 가볍게 조회합니다.
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-lifecycle | API로 설정 리로드 가능 (재시작 없이 설정 반영) | 항상 켜기 |
--web.enable-lifecycle를 켜두면, prometheus.yml을 수정한 뒤 컨테이너를 재시작하지 않고도 아래 명령어 하나로 설정을 즉시 반영할 수 있습니다.
curl -X POST http://localhost:9090/-/reload
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·디스크
# 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"} |
Prometheus 알림(Alert) 제대로 쓰기
⚠️ Alert Rule만으로는 “알림”이 안 갑니다
alert_rules.yml은 Prometheus 안에서 “조건이 맞는지 평가”만 합니다. 실제로 텔레그램·이메일·슬랙으로 알림을 “보내는” 역할은 별도 프로그램인 Alertmanager가 합니다. Alertmanager 없이는 Prometheus 웹 화면의 Alerts 탭에서 빨간불만 켜질 뿐, 아무에게도 알림이 가지 않습니다.
Alert Rule 문법 완전 분해
- alert: GPUTemperatureHigh # ① 알림 이름 expr: nvidia_smi_temperature_gpu > 85 # ② 조건 (PromQL) for: 2m # ③ 이 시간 동안 계속 참이어야 발동 (스파이크 무시) labels: severity: warning # ④ 심각도 (나중에 라우팅에 사용) annotations: summary: "GPU 온도 위험" # ⑤ 알림 제목 description: "{{ $value }}도" # ⑥ 알림 본문, $value로 실제 측정값 삽입
for 없이 조건이 맞는 즉시 알림이 발동하면, GPU 온도가 잠깐 튀었다가 바로 내려가는 “노이즈”에도 알림이 옵니다. 1~5분 정도 for를 주면 진짜 지속되는 문제만 걸러집니다.
Alertmanager 최소 구성 — 텔레그램으로 알림 받기
이 시리즈에서 이미 n8n에 텔레그램 봇을 연결해두셨다면, Alertmanager의 Webhook 기능으로 그 봇을 재활용할 수 있습니다.
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-netroute:
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']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초 안에 찾습니다.
Grafana 데이터소스 — 추가 옵션까지 제대로 설정하기
기본 연결(URL 입력 후 Save & Test)만 하고 끝내는 분들이 많은데, 아래 추가 옵션들을 켜두면 훨씬 안정적이고 빠른 대시보드가 됩니다.
Connections → Data sources → Prometheus → 설정 화면에서
| 옵션 | 위치 | 추천 설정 | 이유 |
|---|---|---|---|
| Scrape interval | HTTP 섹션 하단 | 15s (prometheus.yml과 동일하게) | 다르면 그래프가 들쑥날쑥하게 보임 |
| Query timeout | HTTP 섹션 | 60s | 무거운 쿼리(긴 기간 조회) 타임아웃 방지 |
| HTTP Method | HTTP 섹션 | POST | 긴 PromQL 쿼리는 URL 길이 제한(GET)에 걸릴 수 있음 |
| Default | 맨 아래 | 켜기 (1개뿐이면 자동) | 패널 만들 때 매번 데이터소스 선택 안 해도 됨 |
| Prometheus type | Type and version | Prometheus 자동감지 확인 | 버전별 PromQL 기능 차이 자동 대응 |
여러 데이터소스 운영 시 — 폴더로 정리
나중에 Loki(로그)나 다른 Prometheus 인스턴스를 추가하게 되면, Connections → Data sources 목록이 길어집니다. 데이터소스 자체엔 폴더 기능이 없지만, 대시보드 쪽(Dashboards)에는 폴더 기능이 있으니 “AI서버”, “네트워크” 처럼 폴더로 미리 나눠두는 걸 권장합니다.
Grafana 패널 — 타입별로 언제 뭘 써야 하는지
대시보드를 만들 때 “Add panel” 누르고 패널 타입을 고르는 순간 많이들 막힙니다. 용도별로 정리했습니다.
| 패널 타입 | 가장 잘 맞는 용도 | 실전 예시 |
|---|---|---|
| Time series | 시간에 따른 변화 추세를 보고 싶을 때 (가장 기본) | CPU 사용률 그래프, GPU 온도 추이 |
| Gauge | “지금 한 값”을 직관적으로, 임계값 색상과 함께 | 현재 GPU 온도 (초록→노랑→빨강) |
| Bar gauge | 여러 항목을 막대로 한눈에 비교 | 컨테이너별 메모리 사용량 순위 |
| Stat | 숫자 하나를 크게, 트렌드 화살표와 함께 | 현재 떠있는 컨테이너 개수 |
| Table | 여러 라벨/값을 표 형태로 정리 | 컨테이너별 CPU·메모리·상태 종합표 |
| Heatmap | 분포(히스토그램) 시각화 | 응답시간 분포 (대부분 몇 ms대인지) |
| State timeline | 시간대별 상태(켜짐/꺼짐) 변화 | 컨테이너 Up/Down 이력 |
Gauge/Stat에서 임계값(Threshold) 색상 설정하는 법
자주 쓰는 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 by | Table 패널에서 특정 컬럼 기준 정렬 |
| Filter by value | 특정 값 이상/이하인 데이터만 표시 (노이즈 제거) |
| Add field from calculation | 기존 필드들로 새 계산 컬럼 추가 (예: 사용량/전체 = 비율) |
Variables(변수) — 대시보드 하나로 모든 걸 보기
컨테이너마다, GPU마다 똑같은 대시보드를 복제하지 마세요. 변수(Variable) 하나로 드롭다운 선택만 바꿔서 같은 패널을 재사용할 수 있습니다.
실전 예시 — “컨테이너 선택” 드롭다운 만들기
container_namelabel_values(container_memory_usage_bytes, name) → 모든 컨테이너 이름이 드롭다운 목록이 됨{name="n8n"} 대신 {name="$container_name"}로 작성이렇게 하면 대시보드 상단에 드롭다운이 생기고, 거기서 n8n·dify·comfyui 중 고르면 같은 패널들이 그 컨테이너 데이터로 바로 바뀝니다. 컨테이너마다 따로 대시보드 만들 필요가 없어집니다.
Multi-value — 여러 개 동시 선택도 가능
Variable 설정에서 “Multi-value” 옵션을 켜면 체크박스 형태로 여러 컨테이너를 동시에 선택해서 비교할 수 있습니다. “Include All option”을 같이 켜면 “전체 선택”도 가능합니다.
Grafana 자체 알림(Unified Alerting) — Alertmanager 없이도 가능
Part 4에서 다룬 Prometheus+Alertmanager 조합 대신, Grafana 자체 알림 기능(Unified Alerting)을 쓰면 별도 컨테이너 없이도 텔레그램·Discord·Slack 알림이 가능합니다. 홈랩 규모에서는 이 방법이 훨씬 간단합니다.
① Contact point 만들기 — 텔레그램
Telegram 선택② Alert rule 만들기 — Prometheus 쪽 yml 안 만지고 UI에서
nvidia_smi_temperature_gpu)for:와 동일한 역할. 2분 정도 권장둘 다 비슷한 일을 합니다. 이미 prometheus.yml에 alert_rules.yml을 설정해두셨다면 그대로 두고, Grafana에서는 Notification Policy만 추가로 연결하는 게 중복 작업을 줄입니다. 처음부터 새로 만드는 경우라면 UI가 훨씬 편한 Grafana Alert rule을 추천합니다.
Annotations — “이 시점에 뭐가 있었는지” 그래프에 표시하기
GPU 사용률이 갑자기 튄 시점에 “이때 ComfyUI로 영상 생성을 돌렸다” 같은 메모를 그래프 위에 직접 남길 수 있습니다. 배포 시점, 재시작 시점을 표시해두면 나중에 원인 추적이 훨씬 쉬워집니다.
자동 Annotation — Alert 발동 시점 자동 표시
대시보드 설정 → Annotations에서 “Alert state changes” 옵션을 켜두면, 알림이 발동/해제된 시점이 그래프에 자동으로 표시됩니다. 수동으로 기록할 필요가 없어집니다.
대시보드 운영 팁 — Row, 폴더, 공유, 백업
Row로 패널 그룹 접기/펼치기
패널이 10개 넘어가면 한 화면에 다 보기 힘듭니다. “Row”를 추가하면 “GPU”, “CPU/RAM”, “컨테이너” 같은 섹션으로 나눠서 접고 펼칠 수 있습니다. Add panel → Row 선택 → 패널들을 그 Row 안으로 드래그.
대시보드를 폴더로 정리
Dashboards → New folder로 “AI서버 모니터링” 폴더를 만들고, GPU 대시보드·시스템 대시보드·컨테이너 대시보드를 그 안에 모아두면 나중에 대시보드가 늘어나도 안 헤맵니다.
대시보드 JSON으로 백업/공유
대시보드 설정(⚙️) → JSON Model에서 전체 구성을 JSON으로 복사할 수 있습니다. 직접 만든 대시보드는 이 JSON을 따로 백업해두세요 — Grafana 컨테이너 데이터가 날아가도 이 JSON으로 즉시 복원 가능합니다.
직접 만든 대시보드는 이 시리즈의 백업 스크립트(backup.sh)가 자동으로 백업하는 범위에 포함되도록, Grafana 데이터 폴더도 tar로 묶는 단계를 추가하는 걸 권장합니다. 또는 위 JSON Export를 주기적으로 별도 저장하세요.
Playlist — 여러 대시보드를 자동 순환 표시
거실 모니터나 별도 화면에 여러 대시보드를 자동으로 돌려가며 보여주고 싶을 때, Dashboards → Playlists에서 “어떤 대시보드들을, 몇 초마다 순환”할지 정하면 자동 슬라이드쇼처럼 작동합니다.
AI 서버 특화 — 바로 적용 가능한 추천 설정 모음
지금까지 배운 걸 실제로 이 홈랩 환경에 적용한다면, 아래 구성을 추천합니다.
📋 추천 대시보드 구조 (Row 4개)
| Row | 패널 | 타입 | 쿼리 |
|---|---|---|---|
| GPU | GPU 온도 | Gauge | nvidia_smi_temperature_gpu |
| VRAM 사용률 | Bar gauge | (nvidia_smi_memory_used_bytes/nvidia_smi_memory_total_bytes)*100 | |
| GPU 사용률 추이 | Time series | nvidia_smi_utilization_gpu_ratio*100 | |
| 시스템 | CPU/RAM 추이 | Time series | Part 3 쿼리 2개 같은 패널에 |
| 디스크 여유공간 | Stat | node_filesystem_avail_bytes{mountpoint="/"}/1024^3 | |
| 컨테이너 | 메모리 Top 5 | Bar gauge | topk(5, container_memory_usage_bytes{name!=""}) |
| 전체 컨테이너 상태표 | Table | container_last_seen{name!=""} | |
| 알림 | 현재 발동중 알림 | Alert list 패널 | – |
🎯 임계값 추천표 (Gauge 색상 기준)
| 지표 | 초록(정상) | 노랑(주의) | 빨강(위험) |
|---|---|---|---|
| GPU 온도 | < 70°C | 70~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% 이상 — 백업 실패나 로그 폭증 조기 발견
내 환경 맞춤 모니터링 — ComfyUI·RTX 3060 OC·Dify·Firecrawl·WordPress·Open WebUI
ComfyUI·Dify·Firecrawl·Open WebUI·WordPress는 /metrics 엔드포인트를 직접 제공하지 않습니다. 대신 이미 떠있는 cAdvisor(컨테이너별)와 nvidia-exporter(GPU)를 라벨로 필터링하는 것만으로 실용적인 수준의 모니터링이 가능합니다. 아래는 그 방법입니다.
🎨 ① ComfyUI — GPU 점유 시점과 컨테이너 리소스를 같이 본다
ComfyUI 자체엔 메트릭 엔드포인트가 없지만, “ComfyUI가 돌 때 GPU가 얼마나 쓰이는지”는 cAdvisor + nvidia-exporter 조합으로 충분히 보입니다. 생성 작업 중 VRAM이 얼마나 차오르는지, 컨테이너 자체의 CPU/RAM은 정상인지를 같은 화면에 겹쳐 보면 충분합니다.
# 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) | < 170W | 170~195W | > 195W | OC 헤드룸(225W) 대비 87% 지점을 위험선으로 |
| VRAM 사용률 | < 83% | 83~95% | > 95% | 12GB 기준 — 10GB 넘으면 주의(83%) |
| GPU 온도 | < 70°C | 70~83°C | > 83°C | Ampere 권장 한계 약 85~88°C보다 여유있게 |
| 팬 속도 | < 70% | 70~85% | > 85% | 지속적으로 높으면 케이스 환기 점검 필요 |
# 전력 소비를 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
위 클럭·팬 메트릭은 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 연동 문제가 실제로 가장 많이 나는 지점).
# 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가 메모리를 가장 많이 먹는 지점이라 별도 패널로 감시할 가치가 있습니다.
# 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) — 이건 컨테이너가 아니라 외부 사이트입니다
WordPress(agibop.com)는 R730의 Docker 컨테이너가 아니라 외부에 호스팅된 별도 사이트입니다. 그래서 cAdvisor·nvidia-exporter로는 절대 안 보이고, “이 사이트가 지금 살아있는지·응답이 느린지”를 외부에서 HTTP로 직접 확인하는 방식이 필요합니다.
두 가지 방법이 있습니다. 이미 이 시리즈에 있는 Uptime Kuma가 압도적으로 더 간단합니다.
| 방법 | 난이도 | 장점 |
|---|---|---|
| Uptime Kuma (추천) | ★☆☆ 쉬움 | URL만 등록하면 끝, 자체 알림 기능 내장, 별도 Prometheus 설정 불필요 |
| Prometheus blackbox_exporter | ★★★ 복잡 | Grafana 한 화면에 GPU·서버랑 같이 보고 싶을 때만 가치 있음 |
https://agibop.comGrafana 한 화면에 굳이 같이 보고 싶다면, Uptime Kuma가 자체적으로 /metrics Prometheus 엔드포인트를 제공하니(설정에서 활성화) Prometheus job으로 추가해서 끌어올 수도 있습니다. 처음엔 Uptime Kuma 자체 대시보드만으로 충분합니다.
💬 ⑥ Open WebUI — 메모리 증가 추세를 지켜보세요
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 헤드룸 대비%) | Gauge | power_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" |
마무리 체크리스트
- ✓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·컨테이너 상태를 실시간으로 추적하고 문제 발생 시 텔레그램으로 먼저 알게 되는 운영 가능한 모니터링 체계를 갖추신 겁니다.

