Kubernetes 환경에서 SpringBoot Actuator을 통해 Prometheus로 어플리케이션 모니터링하기

이숭늉·2025년 3월 15일
0

DevOps

목록 보기
5/19
post-thumbnail

🌏 Kubernetes 환경에서 SpringBoot Actuator을 통해 Prometheus로 어플리케이션 모니터링하기

Prometheus 같은 모니터링 툴 부분 수업은 들으면서 잘 와닿지가 않았다. 그래서 크게 흥미도 못 느끼고 완전히 습득도 안된 느낌이었는데, 이번 프로젝트에서 다른 팀원분과 모니터링을 구상하면서 흐름을 좀 알게된 것 같아 글로 정리를 해보려고 한다.

일단 큰 흐름은 Spring Actuator - Prometheus - Grafana 이러하다.
우선 Spring Actuator에 대해 알아보자.


🍃 Spring Actuator란?

  • 실행 중인 어플리케이션의 내부 상태를 모니터링하고 관리할 수 있도록 도와주는 라이브러리
  • 주요 기능으로는 헬스 체크, 어플리케이션 정보 제공, 메트릭 수집 및 트레이싱 등이 있다.
  • 특정 엔드포인트에서 위 기능을 확인할 수 있다.
    • 헬스 체크 (/actuator/health): 애플리케이션의 상태를 확인 가능
    • 메트릭 (/actuator/metrics): 애플리케이션의 성능 및 리소스 사용량 측정
    • 환경 정보 (/actuator/env): 애플리케이션의 환경 변수 및 설정 정보 제공
    • 트레이싱 (/actuator/httptrace): HTTP 요청 및 응답 추적
  • /actuator/metrics 경로에서 메트릭을 제공해주지만 Prometheus 형식이 아니라 Prometheus가 수집할 수 있는 형식으로 메트릭을 출력하기 위해 따로 /actuator/prometheus 엔드포인트도 활성화해주어야 한다.

Spring Actuator - Prometheus - Grafana 흐름

  • Spring Actuator가 /actuator/prometheus(기본값) 경로에서 메트릭 제공.
  • Prometheus가 해당 엔드포인트를 주기적으로 스크랩하여 메트릭을 수집하고 데이터를 저장.
  • Grafana가 Prometheus에서 저장된 데이터를 가져와 시각화.

⇒ Spring Boot 애플리케이션의 성능 데이터를 시각적으로 모니터링 가능


🖥️ 설정 흐름

어플리케이션 설정

  • 의존성 추가 (gradle)
    //DevOps
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    runtimeOnly 'io.micrometer:micrometer-registry-prometheus'
  • application.properties에서 Actuator 설정
    # Actuator
    management.endpoint.prometheus.access=unrestricted
    management.endpoint.health.show-details=always
    management.endpoints.web.exposure.include=health,info,prometheus,metrics
    management.server.port=9090
    management.endpoints.web.base-path=/api/management
    이때 모니터링용 포트를 9090으로 따로 분리하고, 기본 경로도 /actuator 에서 /api/management 로 변경하였다.
    9090으로 따로 분리하는 것의 이점에 대해 우선 간단하게 설명하자면, 어플리케이션 포트와 모니터링 포트를 분리하면 일반적인 클라이언트 요청(API 호출)은 8080에서 처리하고, 모니터링과 관리 기능은 9090에서만 접근 가능하게 분리된다. 이로써 Actuator 엔드포인트가 불필요하게 노출되는 위험을 줄일 수 있다. 뒤에 또 이점이 나온다.

ServiceMonitor 리소스 설정

AWS 환경, 특히 EKS 같은 Kubernetes 기반 환경에서 Prometheus가 자동으로 어플리케이션의 메트릭 엔드포인트를 스크랩하도록 만들기 위해서는 ServiceMonitor라는 CRD(Custom Resource Definition)를 사용해야 한다.

CRD란 Kubernetes에서 기본적으로 제공하는 리소스 외에, 사용자가 직접 정의하는 새로운 리소스 타입을 만들 수 있도록 해주는 기능이라고 한다.

ServiceMonitor는 Prometheus Operator가 제공하는 CRD 중 하나이다. 기본적으로 Kubernetes는 ServiceMonitor라는 리소스를 모르지만, Prometheus Operator를 설치하면 ServiceMonitor라는 새로운 리소스를 Kubernetes에서 사용할 수 있도록 확장해준다.
더불어, EKS 환경에서는 Pod의 IP가 변경될 수 있기 때문에 정적인 설정이 불가하므로, Kubernetes에서 자동으로 메트릭을 수집하려면 Kubernetes의 서비스 디스커버리 기능을 사용해야 한다. 서비스 디스커버리는 클러스터 내에서 동적으로 생성되고 변경되는 서비스(ex: app-service)를 자동으로 찾아주는 기능이다.
Prometheus는 이 서비스 디스커버리 기능을 제공하는 ServiceMonitor을 보고 어떤 서비스에서 메트릭을 수집해야 하는지 자동으로 탐색할 수 있게 된다.

⇒ 즉, ServiceMonitor는 Prometheus Operator가 제공하는 CRD(Custom Resource Definition) 중 하나로, Kubernetes의 서비스 디스커버리 기능을 활용해 Prometheus가 자동으로 타겟을 찾고 모니터링하도록 도와주는 리소스이다.

App-service.yaml (어플리케이션 서비스 정의)

apiVersion: v1
    kind: Service   
    metadata: 
      name: mv-be-app-service 
      labels: 
        app.kubernetes.io/name: mv-be
        app.kubernetes.io/instance: mv-be
        app.kubernetes.io/version: "1.0.0"
    spec:
      selector: 
        app.kubernetes.io/name: mv-be
        app.kubernetes.io/instance: mv-be
      type: ClusterIP # Service가 노출되는 방식, ClusterIP는 기본값으로 클러스터 내부에서만 접근 가능
      ports:
        - name: http 
          protocol: TCP 
          port: 8080 
          targetPort: 8080 
        - name: prometheus
          protocol: TCP
          port: 9090
          targetPort: 9090

service-monitor.yaml

apiVersion: monitoring.coreos.com/v1
    kind: ServiceMonitor
    metadata:
      name: mv-be-app-servicemonitor
      namespace: monitoring
      labels:
        app.kubernetes.io/name: mv-be
        app.kubernetes.io/instance: mv-be
    spec:
      selector: # mentoview-be 네임스페이스에서 레이블들이 일치하는 서비스 선택
        matchLabels: 
          app.kubernetes.io/name: mv-be
          app.kubernetes.io/instance: mv-be
      namespaceSelector:
        matchNames:
          - mentoview-be
      endpoints:
      - port: prometheus # 위 Service에서 정의한 'prometheus' 포트를 참조 (9090)
        path: /api/management/prometheus
        scheme: http
        interval: 30s

동작 흐름

  • Service(mv-be-app-service)가 9090 포트로 엔드포인트를 노출
  • ServiceMonitor는 mv-be-app-service의 9090 포트에서 /api/management/prometheus 엔드포인트를 주기적으로(30초 간격) 호출하여 메트릭을 가져감
  • Prometheus가 ServiceMonitor을 보고 /api/management/prometheus 로 요청을 보내 메트릭을 수집

이때 어플리케이션의 Ingress에서는 8080포트만 열어놓았기 때문에 외부에서는 9090 포트로 접근이 불가하다. 따라서, Spring Security에서 따로 Actuator 경로에 보안 조치를 취해주지 않아도 클러스터 외부에서는 접근을 할 수 없다. 이게 포트 분리의 또다른 이점~


이렇게 설정을 해주고, 그라파나에서 어플리케이션을 모니터링하기에 적합한 대시보드를 import해주면 된다. 이상으로 글을 마치겠다.

profile
부지런히 살자

0개의 댓글