
1. Prometheus vs Grafana 역할
| Prometheus | Grafana | |
| 역할 | 메트릭 수집 + 저장 | 시각화 대시보드 |
| 기능 | 각 서비스에서 주기적으로 메트릭 scrape, 시계열 DB에 저장 | Prometheus 데이터를 쿼리해서 그래프/차트로 표시, 알림 설정\ |
데이터 흐름:
[모니터링 대상 서비스] → (메트릭 노출 /metrics) → [Prometheus 수집/저장] → [Grafana 시각화]
모니터링 대상 서비스는 /metrics 엔드포인트를 열어줘야 Prometheus가 긁어갈 수 있다.
- Spring Boot: spring-boot-starter-actuator + micrometer-registry-prometheus
- Node.js: prom-client
2. Docker Compose 기본 구성
services:
prometheus:
image: prom/prometheus:latest
ports:
- "127.0.0.1:9090:9090" # 외부 노출 차단, 로컬에서만 접근
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
- prometheus_data:/prometheus
command:
- "--storage.tsdb.retention.time=15d" # 데이터 보관 기간
- "--web.enable-lifecycle"
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
volumes:
- grafana_data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning
- ./grafana/dashboards:/var/lib/grafana/dashboards
3. Prometheus 설정 (prometheus.yml)
scrape_interval - 타겟에서 메트릭을 수집하는 주기
evaluation_interval - alerting rule을 평가하는 주기
나머지는 읽으면 일해할 수 있다.
scrape_configs
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: "pocat-backend"
metrics_path: /actuator/prometheus # Spring Boot 기본 경로
scrape_interval: 30s # job별 개별 설정 가능
scrape_timeout: 10s
basic_auth: # /metrics 인증이 필요한 경우
username: prometheus
password_file: /etc/prometheus/secrets/password
static_configs:
- targets: ["pocat-backend:8080"]
labels:
env: production # 메트릭에 태그 추가
team: backend
job 이름으로 서비스 구분
job_name이 메트릭의 job 라벨로 저장되어 Grafana에서 필터링/그룹핑에 활용된다.
# pocat-backend의 JVM 힙 메모리
jvm_memory_used_bytes{job="pocat-backend", area="heap"}
# 서비스별 상태 확인
up{job="pocat-backend"} # 1: 정상, 0: 다운
4. 이슈 : Docker 네트워크
이 문제는 로컬 환경에서 정상적으로 동작하는가? 를 확인할때 다른 compose로띄울경우 서로 다른 네트워크이기 때문에 통신이 안된다.
그럼 같은 compose에서 띄우면? 같은 프로젝트 내에서 동작하기때문에 우리는 저장소 자체를 분리해서 방법이 될 수 없다고 생각했다.
사실 운영단계에서는 상관없다 그냥 애초에 서로 다른 서버에 웹서버와 모니터링 서버가 동작하는거니까,
해결 : 공유 네트워크로 compose 간 통신
여러 docker-compose가 같은 서버에서 실행될 때 컨테이너 이름으로 통신하려면 공유 네트워크가 필요하다.
# 네트워크 생성 (최초 1회)
docker network create pocat-net
# 각 docker-compose.yml에 추가
services:
my-service:
networks:
- pocat-net
networks:
pocat-net:
external: true # 외부에서 만든 네트워크 참조
5. 운영 환경 아키텍처
권장 구조 (Private Subnet + ALB)
인터넷 → ALB → Private Subnet
├── pocat-backend:8080
├── pocat-batch:8081
├── DB
└── Prometheus + Grafana
- Prometheus는 Private Subnet 안에서 서비스들을 직접 scrape
/metrics엔드포인트는 외부에 절대 노출하지 않음- Grafana만 ALB에 연결해서 외부 접근 허용
보안 레이어
하나만 믿으면 뚫렸을 때 끝이므로 여러 레이어를 겹쳐야 한다.
VPC 내부망 제한 (Security Group)
+ VPN (WireGuard 등)
+ basic_auth
| 방법 | 특징 |
| Security Group으로 VPC 내부만 허용 | 외부 인터넷 차단 |
| 특정 IP만 허용 | IP 탈취 시 우회 가능, 단독으로 쓰기엔 부족 |
| basic_auth | 네트워크 뚫려도 인증 한 겹 추가 |
6. Grafana Provisioning
Provisioning이 필요한 이유
볼륨 마운트만 사용하면 docker compose down -v 또는 서버 교체 시 대시보드가 날아간다. Provisioning은 대시보드와 데이터소스를 코드(파일)로 관리해서 서버가 새로 띄워져도 자동 복원된다.
즉 대시보드를 GUI 형태가 아니라 코드베이스로 관리가 가능해진다.
디렉토리 구조
grafana/
├── provisioning/
│ ├── datasources/
│ │ └── prometheus.yml ← 데이터소스 자동 연결
│ └── dashboards/
│ └── dashboard.yml ← 대시보드 파일 위치 지정
└── dashboards/
└── pocat-overview.json ← 대시보드 정의
데이터소스 설정 (provisioning/datasources/prometheus.yml)
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090 # 같은 네트워크면 컨테이너 이름 사용
isDefault: true
editable: false
대시보드 프로바이더 설정 (provisioning/dashboards/dashboard.yml)
apiVersion: 1
providers:
- name: pocat
folder: POCAT
type: file
disableDeletion: true # UI에서 실수로 삭제 방지
updateIntervalSeconds: 30 # 파일 변경 시 자동 반영
options:
path: /var/lib/grafana/dashboards
Grafana UI에서 대시보드를 만든 후 JSON으로 export해서 dashboards/ 디렉토리에 저장하면 Git으로 버전 관리가 가능하다.
'TIL' 카테고리의 다른 글
| 트랜잭션 경계 설정중 외부 트랜잭션 객체 Lazy 로딩 안됨. (0) | 2026.05.20 |
|---|---|
| 분산lock AOP구현중 원자성 보장을 위한 lua 작성 그리고 그 단점 (0) | 2026.04.15 |
| 네트워크란 무엇인가 ( 네트워크는 마법이 아니다. ) (0) | 2026.03.09 |
| ArgumentResolver (0) | 2026.03.06 |
| 유닛테스트와 통합테스트 (0) | 2026.03.05 |