kkokkio - 프로젝트/트러블슈팅

Prometheus + Grafana 모니터링 도입기

파란배개 2025. 6. 16. 06:38

도입 목적

프로젝트가 심화됨에 따라 도입된 기술이 다양해지고, 그에 맞춰 얻어야할 정보의 양이 많아졌다.

따라서 현재 사용중인 기능의 전체적인 성능을 분석하고 시각화된 모니터링의 필요성이 절실해졌다.

  • Prometheus : 시스템에서 발생하는 다양한 메트릭 데이터를 수집하고 저장하는 도구
  • Grafana : 프로메테우스에서 저장된 메트릭 데이터를 다양한 그래프, 차트, 대시보드 등으로 시각화하여 시스템의 현 상태를 모니터링 할 수 있도록 하는 도구

가장 보편화된 이 두 가지 도구를 활용하여 모니터링을 구현하고자 하였다.

구현 과정

구현 과정은 굉장히 간단했다.

당장에 로컬에서 사용하기 위해 구현하였으므로, docker-compose를 활용하여 필요한 도커 컨테이너를 작성하여 사용하였다.

  prometheus:
    container_name: prometheus
    image: prom/prometheus:latest
    restart: always
    extra_hosts:
      - "host.docker.internal:host-gateway"
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
    depends_on:
      - mysql-exporter
    networks:
      - monitoring

  grafana:
    container_name: grafana
    image: grafana/grafana:latest
    restart: always
    ports:
      - "3000:3000"
    volumes:
      - grafana_data:/var/lib/grafana
    environment:
      - GF_SECURITY_ADMIN_USER=${DB_USERNAME}
      - GF_SECURITY_ADMIN_PASSWORD=${DB_PASSWORD}
    depends_on:
      - prometheus
    networks:
      - monitoring

  mysql-exporter:
    container_name: mysql-exporter
    image: prom/mysqld-exporter:latest
    restart: always
    ports:
      - "9104:9104"
    command:
      - "--mysqld.username=${DB_USERNAME}:${DB_PASSWORD}"
      - "--mysqld.address=db:3306"
    depends_on:
      - db
    networks:
      - monitoring

  node-exporter:
    container_name: node-exporter
    image: prom/node-exporter:latest
    restart: always
    ports:
      - "9100:9100"
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - '--path.procfs=/host/proc'
      - '--path.sysfs=/host/sys'
      - '--collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc)($$|/)'
    networks:
      - monitoring

또한, Prometheus의 경우, 추가적인 설정 파일이 필요하기에, prometheus.yml을 작성하여 Prometheus와 정보를 수집하는 exporter들을 연결해주었다.

global:
  scrape_interval: 15s
  # evaluation_interval: 15s # rule evaluation 주기

scrape_configs:
  - job_name: "app"
    metrics_path: "/api/actuator/prometheus"
    honor_labels: true # ← 우리가 붙인 tag 우선
    static_configs:
      - targets:
          - "host.docker.internal:8080"
        labels:
          instance: "app"
  - job_name: "mysql_exporter"
    metrics_path: "/metrics"
    static_configs:
      - targets: ["mysql-exporter:9104"]
  - job_name: "node_exporter"
    scrape_interval: 5s
    static_configs:
      - targets: ["node-exporter:9100"]

구현 중 발견한 문제

  • 네트워크 설정 문제 (간단했던 거..)컨테이너의 네트워크 설정 문제
    • MySQL - exporter - Prometheus - Grafana 로 이어지는 인프라는 모두 같은 컨테이너 네트워크를 가져야됨
    • 따라서 같은 네트워크를 가지지 못하는 컨테이너의 경우 같이 도커에서 돌고 있어도 해당 컨테이너에 접근이 불가
      • 정확히는 모두 네트워크를 명시하거나, 모두 명시하지 않거나
      • 도커는 기본적으로 default 네트워크에 포함되기 때문에 모두 명시하지 않는 경우에도 이론상으론 연결이 가능할 것으로 보임.
      • 하지만 보안성 및 네트워크의 용도에 맞는 격리성을 보았을 때 명시를 하는 쪽이 당연함
  • networks: monitoring: driver: bridge
  • 스프링부트 서버의 모니터링
    • Spring Actuator를 사용하여 프로메테우스와 연동 및 사용
    • 허나 서버를 도커에서 실행해야만 작동 가능

문제 해결

  • 네트워크 설정 문제
    • 간단하게 인프라 내의 모든 컨테이너에 아래의 설정을 명시하면 된다.
    • networks: - monitoring
  • 스프링부트 서버의 모니터링
    • 서버를 도커에서 실행할 경우?
    • Local과 Dev 환경의 차이로 인해 DockerFile의 문제가 발생
      • 로컬에서 도커 서버 실행의 필요성 → 굳이 필요한가

결과 및 성능 분석

Data source 추가

프로메테우스 입력 후 Save & Test

Dashboard 추가 > Import dashboard

원하는 대시보드 템플릿 (예시에선 7362 사용) 로드 > 이름과 가져온 Data Source 넣고 생성

짠 완성~

그냥 보기 쉽게 번역기..

DB의 가동 시간, QPS (초당 실행 쿼리 수), MySQL Questions (서버에서 실행된 명령문 수), InnoDB Buffer Pool Size(Innodb 엔진에서 테이블이나 인덱스 데이터를 캐시 하는 메모리 영역) 등을 모니터링 가능

  • 노드 익스포터를 통한 서버 모니터링

참고 : https://dongker.tistory.com/entry/DevOps-Prometheus와-MySQL-Exporter로-Grafana-MySQL-DB-모니터링-시스템-구축하기

추가 개선점

exporter의 경우 DB의 사용자 하나를 주어 연결하여 DB의 정보를 가져오기 때문에, 아예 exporter 전용 유저를 생성 후 사용하는 편이 좋다고 생각됨 → DB 유저 생성 및 사용 부분에 미숙하여 곧바로 적용하진 못했음..