Prometheus + Grafana + Spring Boot 모니터링 환경 구성 (with Docker)

박은서·2025년 5월 2일

MONITERING

목록 보기
3/4

Spring Boot + Prometheus + Grafana 모니터링 환경 구성 (with Docker)

Spring 프로젝트를 Prometheus와 Grafana를 통해 모니터링하는 실습을 진행하며, Docker를 활용해 환경을 빠르게 구성하였다.


Docker를 사용한 이유

기존 방식대로 Prometheus, Grafana, Spring Boot를 각각 설치하고 설정하면 번거롭고, 환경이 조금만 바뀌어도 재설정이 필요하다. 이 때문에 환경 간 격리, 빠른 배포, 반복 가능한 실행 환경 구축을 위해 Docker를 사용했다.

왜 VM보다 Docker인가?

항목가상머신 (VM)Docker 컨테이너
OS 포함 여부전체 OS 포함호스트 OS 커널 공유
부팅 속도느림 (수십 초)빠름 (수 초 이내)
리소스 사용량무거움가벼움
설치/배포복잡간단 (이미지 기반)

Docker는 필요한 서비스만 빠르게 띄울 수 있는 경량화된 환경이다. 또한 docker-compose.yml 파일 하나로 여러 서비스를 한 번에 띄울 수 있어 매우 효율적이다.


docker-compose 파일 기반 컨테이너 실행 구조

Docker는 docker-compose.yml 파일을 바탕으로 컨테이너를 실행한다. 예를 들어, prometheus.yml 설정 파일을 바탕으로 prometheus라는 이름의 컨테이너가 실행된다.

어떤 환경에서든 docker-compose.yml만 있다면, 직접 로컬에 설치하지 않아도 동일한 환경을 실행할 수 있다.


localhost 접속이 가능한 이유

Prometheus나 Grafana를 로컬에 직접 설치하지 않았지만, 다음 주소로 브라우저에서 접근이 가능했다:

이는 Docker가 컨테이너 내부 포트를 로컬 포트에 바인딩시켰기 때문이다:

  mysql:
    ports:
      - "3305:3305"

prometheus:
    ports:
      - "9090:9090"

  grafana:
    ports:
      - "3000:3000"

이 설정은 컨테이너 내부의 9090 포트를 내 로컬 PC의 9090 포트에 연결한다는 뜻이다. 즉, 실제 실행은 컨테이너 안에서 이루어지지만, 로컬 포트로 브라우저에서 접근이 가능하다.


docker-compose.yml 분석

services:
  mysql:
    container_name: testdb
    image: mysql:8.0.33
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: testdb
      TZ: Asia/Seoul
    ports:
      - "3305:3305"
    networks:
      - test_network

  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    networks:
      - test_network

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    user: "$UID:$GID"
    ports:
      - "3000:3000"
    volumes:
      - ./grafana-data:/var/lib/grafana
    depends_on:
      - prometheus
    networks:
      - test_network

networks:
  test_network:
    driver: bridge

주요 설정 설명

  • services: 실행할 컨테이너 목록 (MySQL, Prometheus, Grafana)
  • volumes: 설정 파일 및 데이터를 로컬 디스크에 유지
    • 도커는 기본적으로 휘발성이기 때문에, volumes를 통해 로컬 디스크와 컨테이너 디렉토리를 연결!
  • depends_on: Grafana는 Prometheus가 먼저 실행된 후 실행됨
  • networks: 세 컨테이너는 같은 네트워크에서 통신 가능 (내부 IP 공유)
    • 도커는 컨테이너들끼리 격리되어 있기 때문에, 서로 네트워크를 지정하지 않으면 기본적으로 서로 도메인 이름(예시 http://prometheus:9090) 으로 접근이 되지 않는다.
  • user: "$UID:$GID": 현재 호스트 유저 GID 권한으로 컨테이너 실행하여 권한 오류 방지
    • 도커 컨테이너는 기본적으로 root 계정으로 실행되고, 컨테이너 안에서 실행된 파일은 root 소유가 된다. 호스트에서 해당 파일을 열거나 삭제하려고 하면 권한 오류가 생긴다. 따라서 해당 명령어로 권한 공유

의존성 추가 (build.gradle)

implementation 'org.springframework.boot:spring-boot-starter-actuator'
runtimeOnly 'io.micrometer:micrometer-registry-prometheus'
  • actuator: 스프링 애플리케이션 상태(헬스 체크, 메모리, 빈 정보 등)를 엔드포인트로 제공
  • micrometer-registry-prometheus: Prometheus가 이해할 수 있는 형식으로 메트릭 변환

application.yml 설정

server:
  port: 8080

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3305/testdb
    username: root
    password: password
  • 애플리케이션은 8080 포트에서 실행
  • 스프링을 도커 컨테이너의 MySQL에 연결
management:
  endpoints:
    web:
      exposure:
        include: "prometheus"
  • /actuator/prometheus 경로를 외부로 노출함

prometheus.yml 설정

scrape_configs:
  - job_name: 'Test Server'
    metrics_path: '/actuator/prometheus'
    scrape_interval: 5s
    static_configs:
      - targets: ['localhost:8080']
  • metrics_path: Spring 앱에서 메트릭을 노출하는 엔드포인트
  • scrape_interval: 5초마다 수집
  • targets: Prometheus가 메트릭을 긁어올 대상

실행 및 확인

docker-compose up -d

Actuator 확인

Prometheus 대시보드 확인

※ 하지만 도커는.. 격리된 네트워크에서 동작하기 때문에, 컨테이너에서 localhost 는 컨테이너 자기 자신을 가리킨다. 로컬 호스트의 브라우저에서 보려면 prometheus.yml 의 targets 을 ['host.docker.internal:8080'] 로 바꾸어야 한다!!!!

  • Status > Targets > 'Test Server'가 UP인지 확인

Grafana 시각화

  1. http://localhost:3000 접속
  2. 기본 로그인: admin / admin
  3. Prometheus 연결
    Data Sources > Add > Prometheus
    URL: http://prometheus:9090


  4. Dashboard > Import > ID: 12900 입력

JVM + Micrometer 통합 대시보드


이제 스프링 애플리케이션의 상태를 수치로 확인하고, 메모리 누수, 가비지 컬렉터 비정상 현상들을 조기에 탐지할 수 있다.
트래픽 변화에 따라 리소스 설정을 동적으로 최적화 할 수 있다.

운영을 위한 데이터 기반 의사결정의 출발....!!!!

0개의 댓글