5. Exporter와 Service Discovery: 다양한 시스템 메트릭 수집하기

지난 장에서는 Spring Boot 애플리케이션이 Actuator를 통해 스스로 메트릭을 노출하는 방법을 배웠습니다. 하지만 우리가 모니터링해야 할 대상은 애플리케이션뿐만이 아닙니다. 애플리케이션이 실행되는 서버의 CPU, 메모리, 디스크 상태는 물론, 연동된 데이터베이스(MySQL, Redis 등)의 상태도 매우 중요합니다.

이처럼 프로메테우스 메트릭을 자체적으로 노출하지 않는 시스템을 모니터링하기 위해 사용하는 것이 바로 Exporter입니다. 그리고 클라우드 환경처럼 대상 시스템의 IP가 계속 변하는 상황에 대응하기 위한 기술이 Service Discovery입니다.

1. Exporter란? - 시스템을 위한 번역가

Exporter는 특정 시스템(예: MySQL 데이터베이스)의 내부 상태나 성능 지표를 수집하여, 프로메테우스가 이해할 수 있는 텍스트 포맷으로 변환 후 HTTP 엔드포인트(주로 /metrics)로 노출해주는 독립적인 프로그램입니다.

비유: 통역사

Exporter는 마치 외국인과 대화할 때 필요한 '통역사'와 같습니다.

각 시스템(MySQL, Redis)에 맞는 전용 통역사(Exporter)가 필요한 것처럼, 모니터링할 대상 시스템마다 그에 맞는 Exporter를 설치하고 실행해야 합니다.

MySQL mysqld_exporter Prometheus

mysqld_exporter가 MySQL의 상태를 조회하여 Prometheus 포맷으로 변환하면, Prometheus가 이를 수집(scrape)합니다.

주요 Exporter 종류

2. Service Discovery란? - 동적 환경에서의 목표물 자동 탐지

지금까지 우리는 prometheus.yml 파일의 static_configs에 모니터링할 대상의 IP 주소를 직접 하드코딩했습니다. 서버가 몇 대 안 될 때는 괜찮지만, 다음과 같은 현대적인 클라우드 환경에서는 이 방식은 불가능에 가깝습니다.

문제 상황: 수동 관리의 한계

새로운 서버가 100대 추가될 때마다 담당자가 밤새 prometheus.yml 파일을 수정하고 프로메테우스를 재시작해야 한다면 어떨까요? 이는 잦은 실수와 장애로 이어질 수밖에 없습니다.

Service Discovery(SD)는 이러한 문제를 해결하기 위해 Prometheus가 외부 시스템(예: AWS, Kubernetes, Consul)의 API를 통해 모니터링 대상을 동적으로 발견하고 목록을 자동으로 갱신하는 기능입니다.

실습: `file_sd_config`를 이용한 동적 타겟 관리

가장 간단한 형태의 Service Discovery인 file_sd_config를 실습해보겠습니다. 이는 특정 파일(JSON 또는 YAML)에 정의된 타겟 목록을 프로메테우스가 주기적으로 읽어와 반영하는 방식입니다.

1단계: 타겟 파일 생성
프로메테우스 설정 파일이 있는 곳에 targets.json 파일을 생성하고 아래와 같이 작성합니다. Node Exporter(포트 9100)와 지난 시간에 만든 Spring Boot 앱(포트 8080)을 타겟으로 추가합니다.

[
  {
    "targets": ["localhost:9100"],
    "labels": {
      "job": "node_exporter_sd",
      "env": "development"
    }
  },
  {
    "targets": ["localhost:8080"],
    "labels": {
      "job": "spring_app_sd",
      "env": "development"
    }
  }
]

2단계: `prometheus.yml` 수정
기존의 static_configs 부분을 주석 처리하거나 삭제하고, file_sd_configs를 사용하도록 수정합니다.

# prometheus.yml
scrape_configs:
  - job_name: 'file-discovery'
    # 파일 기반 서비스 디스커버리 설정
    file_sd_configs:
      - files:
        - 'targets.json' # 읽어올 파일 경로
        # (선택) 파일을 다시 읽어오는 주기. 기본값은 5분.
        refresh_interval: 1m

이제 프로메테우스를 재시작하면 targets.json 파일의 내용을 읽어 두 개의 타겟을 모니터링하기 시작합니다. 앞으로 타겟을 추가/삭제할 때 프로메테우스를 재시작할 필요 없이 targets.json 파일만 수정하면 됩니다.

3. Relabeling - 동적으로 수집된 메타데이터 활용하기

Service Discovery를 사용하면 타겟의 IP 주소뿐만 아니라 다양한 메타데이터를 함께 가져올 수 있습니다. 예를 들어, Kubernetes SD는 Pod의 이름, 네임스페이스, 레이블 등의 정보를 가져오고, EC2 SD는 인스턴스 ID, 타입, 리전, 태그 등의 정보를 가져옵니다.

Relabeling(재레이블링)은 이렇게 수집된 메타데이터를 이용해 스크랩하기 전 타겟의 레이블을 동적으로 수정하는 강력한 기능입니다.

예를 들어, Kubernetes 환경에서 Pod의 네임스페이스를 namespace 레이블로 추가하고 싶을 때 아래와 같이 relabel_configs를 사용할 수 있습니다.

# kubernetes_sd_config 사용 시 예시
relabel_configs:
  # 쿠버네티스 SD가 제공하는 __meta_kubernetes_pod_namespace 레이블의 값을
  # 실제 메트릭에 adj-attach될 namespace 레이블의 값으로 사용한다.
  - source_labels: [__meta_kubernetes_pod_namespace]
    target_label: namespace
    action: replace

Relabeling은 복잡하지만, 대규모의 동적 환경에서 모니터링 시스템을 체계적으로 관리하기 위한 필수 기술입니다.

면접관의 시선 💡

Q: "프로메테우스에서 static_configs만으로 타겟을 관리할 때의 문제점은 무엇이고, 어떻게 해결할 수 있나요?"

A: "static_configs는 모니터링 대상의 IP를 직접 하드코딩하는 방식이라, Auto Scaling이나 Kubernetes처럼 IP가 동적으로 변하는 클라우드 환경에서는 사용할 수 없습니다. 타겟이 추가되거나 변경될 때마다 설정을 수동으로 바꾸고 프로메테우스를 재시작해야 하므로 운영 부담과 장애 발생 위험이 큽니다. 이 문제를 해결하기 위해 프로메테우스의 Service Discovery 기능을 사용합니다. 예를 들어, Kubernetes 환경에서는 kubernetes_sd_config를 사용하여 Pod나 Service를 동적으로 탐지하고, 클라우드 VM 환경에서는 ec2_sd_configfile_sd_config 등을 사용하여 타겟 목록을 자동으로 갱신할 수 있습니다."


Q: "프로메테우스 Exporter란 무엇이며, 어떤 경우에 사용해야 하나요? 사용해본 Exporter가 있다면 설명해주세요."

A: "Exporter는 Spring Boot Actuator처럼 자체적으로 프로메테우스 메트릭을 노출하지 않는 시스템을 모니터링하기 위한 '번역기' 같은 프로그램입니다. 대상 시스템의 내부 지표를 가져와 프로메테우스가 수집할 수 있는 포맷으로 변환하고 HTTP 엔드포인트로 노출하는 역할을 합니다. 예를 들어, 서버의 CPU나 메모리 사용량 같은 OS 레벨의 지표를 수집하기 위해 Node Exporter를 사용해야 하고, MySQL 데이터베이스의 커넥션 풀이나 쿼리 성능을 모니터링하기 위해 mysqld_exporter를 사용해야 합니다. 저는 모든 서버에 기본적으로 Node Exporter를 설치하여 시스템 리소스 모니터링의 기반을 마련한 경험이 있습니다."


Q: "프로메테우스의 Relabeling(재레이블링)에 대해 설명하고, 어떤 경우에 유용한지 예를 들어 설명해주세요."

A: "Relabeling은 Service Discovery를 통해 발견한 타겟의 레이블을 스크랩하기 전에 동적으로 수정하는 기능입니다. SD를 통해 얻은 풍부한 메타데이터(예: 쿠버네티스 Pod의 레이블, AWS EC2 인스턴스의 태그)를 실제 메트릭에 유용한 레이블로 변환하는 데 주로 사용됩니다. 예를 들어, kubernetes_sd_config로 발견한 타겟에는 __meta_kubernetes_pod_name이라는 임시 레이블이 붙는데, 이를 relabel_configs를 이용해 실제 pod_name이라는 정식 레이블로 바꿀 수 있습니다. 또한, 'test' 환경 태그가 붙은 EC2 인스턴스는 모니터링 대상에서 제외(drop)하는 등의 필터링 규칙을 정의할 때도 매우 유용하여, 대규모 환경에서 모니터링 대상을 체계적으로 관리하는 데 필수적입니다."