DevOps/Monitoring

[DevOps/Monitoring] AWS EC2에 Prometheus + Grafana로 Docker 기반 모니터링 시스템 구축

공대생안씨 2025. 5. 16. 00:54

1. 모니터링 시스템

1-1. 사용 이유

  • 단순한 로그만으로는 운영 상태를 파악하는데 한계가 있음
  • 서비스의 성능, 상태, 오류 등 실시간 정보 파악 및 대응 가능
  • 특히 운영 환경 (Production)에서는 메트릭 기반 모니터링이 필수임

 

1-2. 구성 요소

  • 메트릭 수집기 (Collector) : 애플리케이션으로부터 CPU 사용량, 요청 수, 에러 수 등 다양한 지표 수집
    • ex) Prometheus, Telegraf, StatsD 등
  • 저장소 (Time-Series DB) : 수집된 데이터를 시계열로 저장
    • ex) Prometheus 내장 TSDB, InfluxDB 등
  • 시각화 도구 (Dashboard) : 데이터를 그래프, 차트 등으로 시각화 ⇒ 직관적인 분석 가능하게 함
    • ex) Grafana, Kibana 등
  • 알림 시스템 (Alerting) : 이상 징후 감지 → 이메일, 슬랙 등으로 알림 전송
    • ex) Prometheus Alertmanager, Grafana Alerting 등

 

1-3. 메트릭 (Metric)

  • 시스템이나 애플리케이션의 상태나 성능을 수치화한 지표 (“무엇을 모니터링할지”를 정의하는 대상)
  • 메트릭은 수치 기반으로 표현됨 ⇒ 시간에 따른 변화 기록해서 성능 추이 분석, 장애 감지, 이상 탐지, 용량 계획 등의 목적으로 사용

 

1-3-1. 대표적인 메트릭 예시

카테고리 의미 메트릭 예시
시스템 성능 서버 자원의 현재 상태 CPU 사용률, 메모리 사용량, 디스크 I/O
애플리케이션 성능 서비스 응답 속도와 안정성 HTTP 요청 수, 응답 시간, 에러율
애플리케이션 상태 애플리케이션 내부 동작 상태 GC 횟수, 스레드 수, DB 연결 수
사용자 트래픽 사용자 이용 패턴 및 부하 접속 사용자 수, API 호출 수, 사용자 세션 수

 

1-4. 적용할 도구 소개

1-4-1. Spring Boot Actuator

  • Spring Boot에서 제공하는 운영용 엔드포인트 제공 라이브러리
  • /actuator/health, /actuator/metrics, /actuator/prometheus 등으로 시스템 상태, 메트릭 정보 확인 가능

 

1-4-2. Prometheus

  • CNCF(Cloud Native Computing Foundation) 에서 관리하는 오픈소스 모니터링 도구
  • 대상 서버에 주기적으로 접속해 메트릭 수집 (pull 방식을 통해)
  • 수집한 데이터를 자체 저장소에 보관 → 쿼리 언어인 PromQL을 통해 원하는 정보 조회 가능

 

1-4-3. Grafana

  • Prometheus와 같은 시계열 데이터 저장소에 연결해 시각화 대시보드를 제공하는 도구
  • 다양한 차트와 템플릿, 경고 기능을 통해 모니터링 환경을 시각적으로 직관화 가능

 

2. 설정 방법

2-1. Spring Boot Actuator 의존성 추가

// build.gradle

// Spring Boot Actuator 의존성 추가
implementation 'org.springframework.boot:spring-boot-starter-actuator'

 

2-2. Prometheus 관련 설정

2-2-1. Prometheus 의존성 추가

// build.gradle

// Prometheus 의존성 추가
implementation 'io.micrometer:micrometer-registry-prometheus'

 

2-2-2. exposure 설정 변경

  • Prometheus가 메트릭을 polling 하려면 /actuator/prometheus 엔드포인트를 제공하도록 설정해야 함
# application.yml

management:
  endpoints:
    web:
      exposure:
        include: "prometheus"

⇒ 해당 엔드포인트를 제공하게 설정되었는지 확인하려면 /actuator/prometheus 로 접속

 

2-2-3. prometheus.yml 작성

  • 현재는 메트릭 수집 주기, 경로 등을 설정하지 않은 상태임 ⇒ 이를 설정하기 위한 YAML 파일 작성
#prometheus.yml

global:
  scrape_interval: 5s  # 매 5초마다 수집

scrape_configs:
  - job_name: 'SWITCH'
    metrics_path: '/actuator/prometheus'  # Spring에서 제공하는 메트릭 경로
    static_configs:
      - targets: ['[EC2 퍼블릭 IP]:[포트번호]']  # 또는 EC2 내 컨테이너 IP/이름
  • scrape_interval : 메트릭 수집 주기 (기본값: 1분)
  • job_name : Prometheus 내부에서 이 수집 대상의 이름
  • metrics_path : 메트릭이 노출되는 경로
  • targets : 모니터링 대상 서버 [host:port 형식]
    • EC2에서 Docker로 실행한 경우는 일반적으로 host.docker.inter:포트번호 또는 IP 사용

 

2-2-4. prometheus.yml 파일을 EC2 인스턴스에 업로드

  • prometheus.yml이 docker-compose.yml에서 마운트되려면 EC2 인스턴스에 로컬 파일로 존재해야 함

1. EC2 인스턴스에 접속

2. ~/prometheus 디렉토리 생성

mkdir ~/prometheus

3. scp 명령어로 prometheus.yml 파일 업로드 (복사)

scp -i [/PEM키 경로] prometheus.yml [ec2유저이름]@[ec2의 IP]:~/prometheus/prometheus.yml
  • ~/prometheus/prometheus.yml : EC2 내에 업로드할 경로

4. 해당 경로에 업로드됨을 확인

 

2-3. docker-compose 관련 설정

✏️ 현재 상황

- GitHub Actions를 통해 CI/CD 파이프라인 구축함
    ⇒ 간략하게 설명 : gradle.yml에서 (1) Gradle로 프로젝트 빌드 → (2) 프로젝트 내의 Dockerfile로 Docker 이미지 생성 및 DockerHub에 push → (3) EC2 인스턴스에 SSH로 접속 → (4) 이미지 pull → (5) 이미지 실행해서 애플리케이션을 컨테이너로 구동

⇒ Prometheus를 실행하고 싶음 ⇒ docker-compose 사용! (별도의 컨테이너로 실행하는 방식)

  • docker-compose 사용하는 이유
    1. 컨테이너는 하나의 역할만 수행해야 한다는 원칙
      • 스프링 애플리케이션 컨테이너에 Prometheus를 함께 구성 ⇒ 단일 책임 원칙에 어긋남!
    2. Prometheus는 prometheus 바이너리를 직접 실행하며 설정 파일 (prometheus.yml) 을 필요로 함 ⇒ 스프링 프로젝트와는 실행 구조가 다르기 때문에 같은 이미지에서 관리하기 어려움!
    3. docker-compose를 통해 Prometheus 뿐 아니라 Grafana도 함께 구성할 수 있는 확장성 확보

 

2-3-0. EC2에 docker-compose 설치

  • 설치되어 있지 않다면 docker-compose 명령어가 실행되지 않을 것
sudo curl -L "<https://github.com/docker/compose/releases/latest/download/docker-compose-$>(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker-compose --version

 

2-3-1. docker-compose.yml 파일 생성

# docker-compose.yml

version: '3'

services:
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    ports:
      - "9090:9090" # Prometheus는 기본적으로 9090 포트 사용
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
  • volumes : [호스트의 파일 경로]:[컨테이너 내부의 경로] ⇒ prom/prometheus 이미지는 /etc/prometheus/prometheus.yml 경로에서 설정 파일을 자동으로 찾기 때문에 해당 경로로 연결

 

2-3-2. EC2 인스턴스의 홈 디렉토리에 해당 파일 업로드

scp -i [/PEM키 경로] docker-compose.yml [ec2유저이름]@[ec2의 IP]:~
  • ~ : EC2 사용자의 홈 디렉토리

 

2-3-3. EC2 인스턴스의 보안 그룹 수정

  • 인바운드 규칙에 9090 포트 허용하도록 수정

 

2-3-4. EC2 인스턴스에 SSH로 접속 후 docker-compose.yml 실행

  • docker-compose -f ~/docker-compose.yml up -d 명령어로 실행

  • [EC2 퍼블릭 IP]:9090/targets 접속 시 아래와 같은 화면이 나온다면 성공

⇒ 이제 해당 페이지에서 원하는 메트릭 정보를 얻을 수 있음!

 

2-4. Grafana 관련 설정

  • Prometheus를 통해 애플리케이션의 메트릭을 수집할 수 있도록 설정 완료
  • 이제 수집된 메트릭을 시각화하여 보다 직관적으로 모니터링할 수 있도록 Grafana 도입할 것

 

2-4-1. docker-compose.yml 수정

# docker-compose.yml

version: '3'

services:
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
  
  # grafana 관련 설정
  grafana:
	  image: grafana/grafana:latest
    container_name: grafana
    user: "$UID:$GID"
    ports:
      - "3000:3000" # Grafana는 기본적으로 3000 포트 사용
    volumes:
      - ./grafana-data:/var/lib/grafana
    depends_on:
      - prometheus # prometheus 컨테이너가 먼저 시작된 후 실행
  • user: "$UID:$GID"
    • 각각 호스트(EC2)의 사용자 ID, 그룹 ID (환경 변수로 설정되어 있지 않으면 에러 발생 가능 ⇒ 이때는 이 줄 삭제하거나 직접 값 지정할 것)
      • UID 값 확인 방법 : id -u
      • GID 값 확인 방법 : id -g
  • volumes: - ./grafana-data:/var/lib/grafana
    • 로컬 디렉토리 (./grafana-data) 를 컨테이너 내부의 Grafana 데이터 디렉토리 (/var/lib/grafana)에 마운트
      ⇒ Grafana 설정, 대시보드, 사용자 설정 등이 컨테이너가 재시작되거나 삭제되어도 유지됨

 

2-4-2. EC2 인스턴스의 보안 그룹 수정

  • 인바운드 규칙에 3000 포트 허용하도록 수정

 

2-4-3. docker-compose 재실행

# 실행중인 컨테이너 확인
docker ps

# 기존 prometheus 컨테이너 중지, 삭제
docker kill [기존 컨테이너 ID]
docker rm [기존 컨테이너 ID]

# docker-compose 재실행
docker-compose -f ~/docker-compose-monitoring.yml up -d
  • [EC2 퍼블릭 IP]:3000 접속 시 아래와 같은 화면이 나온다면 성공

 

2-5. Grafana 대시보드

2-5-1. 최초 로그인

  • 최초 로그인 시 username, password 모두 admin으로 로그인 가능 → 이후 수정 해야함

 

2-5-2. Prometheus 설정

1. Connections > Data sources > Add data source 클릭

 

2. Prometheus 선택

 

3. Prometheus 접속했던 URL 입력

 

4. 하단의 Save & test 클릭

⇒ 해당 문구가 나온다면 성공한 것

 

⇒ Data sources에 추가된 것 확인 가능

 

2-5-3. 대시보드 검색

1. https://grafana.com/grafana/dashboards/ 접속

2. spring boot 검색

3. 원하는 대시보드 선택

4. ID 복사 (회원가입 필요)

 

2-5-4. 대시보드 적용

1. Dashboards > Create dashboard 클릭

 

2. Import dashboard 클릭

 

3. 복사한 ID 입력 > Load 클릭

 

4. Prometheus data source 선택 > Import 클릭

 

⇒ 대시보드가 적용된 것을 확인 가능!