Kubernetes 환경에서 Spring Boot 애플리케이션 모니터링하기: Prometheus와 Grafana 설정 가이드

오늘은 Kubernetes 환경에서 Spring Boot 애플리케이션을 Prometheus와 Grafana를 사용해 모니터링하는 방법을 상세히 알아보겠습니다.

특히 ServiceMonitor 설정 시 자주 발생하는 문제와 해결 방법에 대해 중점적으로 다루어보려 합니다.

 

이 포스트는 Kubernetes 클러스터에 배포된 Spring Boot 애플리케이션의 메트릭을 Prometheus로 수집하고, Grafana를 통해 시각화하는 과정을 다룹니다.
이 설정은 Helm을 이용해 Prometheus와 Grafana를 설치한 상태에서 진행됩니다.

 


1. Spring Boot 서버 설정

1.1 Actuator 및 Prometheus 라이브러리 추가

먼저 Spring Boot 애플리케이션이 Prometheus 메트릭을 제공하려면 spring-boot-starter-actuator와 micrometer-registry-prometheus 라이브러리를 추가해야 합니다.

// build.gradle
implementation 'org.springframework.boot:spring-boot-starter-actuator'
implementation 'io.micrometer:micrometer-registry-prometheus'

 

1.2 Prometheus 메트릭 엔드포인트 활성화

application.yml 또는 application.properties 파일에 아래 설정을 추가하여 /actuator/prometheus 엔드포인트를 활성화합니다.

management:
  endpoints:
    web:
      exposure:
        include: health, info, prometheus
  endpoint:
    prometheus:
      enabled: true

 

1.3 Kubernetes 설정: Prometheus 스크래핑 어노테이션 추가

Kubernetes에서 Prometheus가 Spring Boot 서버의 메트릭을 자동으로 스크래핑할 수 있도록 아래 어노테이션을 모니터링할 서비스에 추가합니다.

metadata:
  annotations:
    prometheus.io/scrape: "true"
    prometheus.io/port: "8080"  # Spring Boot 서버의 포트
    prometheus.io/path: "/actuator/prometheus"

 

2. Prometheus에서 Spring Boot 메트릭 수집 확인

Helm으로 Prometheus를 설치한 후 프로메테우스 웹사이트에 접속해 Targets 탭에서 Spring Boot 서버가 타겟으로 등록되어 있는지 확인합니다.

 

만약 에러가 발생할 경우, Prometheus 로그에서 원인을 확인할 수 있습니다.

 

저는 kubelet 관련 메트릭의 중복 스크래핑 설정으로 인한 에러가 확인되었습니다. 이는 Prometheus가 동일한 kubelet 메트릭을 여러 ServiceMonitor에서 동시에 수집하려고 시도할 때 발생합니다.

err="found duplicate series for the match group {instance=\\\\"192.168.0.101:10250\\\\"} ...

 

이 문제는 Prometheus가 동일한 kubelet 메트릭을 중복으로 수집하려고 시도할 때 발생합니다.

이를 해결하기 위해 중복된 ServiceMonitor 또는 Service 설정을 수정하거나 삭제해 주었습니다.

해결 방법

  1. 중복된 ServiceMonitor 확인
    kubectl get servicemonitor -n monitoring
  2. 먼저 Kubernetes 내에서 중복된 ServiceMonitor가 있는지 확인합니다.
  3. 중복된 ServiceMonitor 삭제 또는 수정
    kubectl delete servicemonitor prometheus-operator-kube-p-kubelet -n monitoring
  4. 중복된 ServiceMonitor를 삭제하거나 레이블을 수정하여 중복을 제거합니다. 예를 들어, 중복된 prometheus-operator-kube-p-kubelet ServiceMonitor를 삭제하려면 다음과 같이 합니다:
  5. ServiceMonitor의 레이블 수정
  6. 중복을 피할 수 있도록 필요한 경우 남아있는 ServiceMonitor의 레이블을 조정하여 Prometheus가 동일한 kubelet 메트릭을 중복 수집하지 않도록 합니다.
  7. Prometheus 파드 재시작
    kubectl rollout restart statefulset prometheus-monitoring-kube-prometheus-prometheus -n monitoring
  8. 변경 사항을 적용하려면 Prometheus 파드를 재시작합니다.

이렇게 설정을 수정하면 중복 스크래핑 에러가 해결되고, Prometheus가 kubelet 메트릭을 정상적으로 수집하게 됩니다.

 


 

3. Grafana에서 Prometheus 데이터 시각화

3.1 Grafana에서 Prometheus 데이터 소스 추가

Grafana에 접속하여 Prometheus를 데이터 소스로 추가합니다.

  1. Configuration > Data Sources로 이동합니다.
  2. Prometheus를 선택하고 URL을 http://prometheus-server.monitoring.svc.cluster.local:9090로 설정합니다.

 

3.2 Spring Boot 모니터링 대시보드 추가

Grafana에서 Spring Boot Actuator 대시보드를 가져오거나 직접 생성하여 CPU, 메모리, 요청 수 등의 메트릭을 실시간으로 시각화합니다.

저는 Spring Boot 2.1 System Monitor 라는 대시보드를 가져와 사용해주었습니다.

 


 

4. ServiceMonitor 이해하기

ServiceMonitor는 Prometheus Operator에서 제공하는 커스텀 리소스로, Prometheus가 어떤 서비스를 모니터링할지 정의합니다. 

 

물론 prometheus/values.yaml 설정 파일을 직접 수정하여 구성할 수도 있습니다. 하지만 저의 경우에는 이 방법으로는 문제를 해결하지 못했고, 알아보다가 ServiceMonitor를 사용하는 방법을 알게 되었습니다. 

ServiceMonitor 사용의 장점

  1. 자동 서비스 디스커버리: 레이블을 기반으로 모니터링할 서비스를 자동으로 찾습니다.
  2. 선언적 설정 관리: Prometheus 설정 파일을 직접 수정하지 않고, Kubernetes 리소스로 모니터링 대상을 관리합니다.
  3. 자동화된 변경 적용: 설정 변경 시 Prometheus 재시작 없이 자동 적용됩니다.

 


 

5. ServiceMonitor와 Service 설정 예시

ServiceMonitor와 Service 설정의 레이블이 일치해야 Prometheus가 타겟을 인식할 수 있습니다. 레이블이 일치하지 않을 경우 Prometheus가 타겟을 찾지 못할 수 있으므로 주의가 필요합니다.

ServiceMonitor 설정

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: spring-boot-monitor
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app: spring-boot-app
  endpoints:
  - port: web
    path: /actuator/prometheus
    interval: 15s

Spring Boot 서비스 설정

apiVersion: v1
kind: Service
metadata:
  name: spring-boot-app-svc
  namespace: grass-diary-backend-release
  labels:
    app: spring-boot-app
spec:
  selector:
    app: spring-boot-app
  ports:
    - name: web
      port: 80
      targetPort: 8080

Service의 metadata.labels와 ServiceMonitor의 selector.matchLabels가 일치하도록 설정하는 것이 중요합니다.

 

트러블슈팅

ServiceMonitor를 설정했는데도 메트릭이 수집되지 않는 가장 흔한 원인은 레이블 불일치입니다.

다음 사항들을 꼭 확인해보세요.

  1. Service의 레이블과 ServiceMonitor의 selector가 정확히 일치하는지 확인
  2. 포트 이름이 ServiceMonitor의 설정과 일치하는지 확인
  3. 네임스페이스 설정이 올바른지 확인

문제 해결 예시

수정 전 Service:

metadata:
  labels:
    app.kubernetes.io/instance: grass-diary-backend-release  # 문제: 필요한 레이블 없음

 

수정 후 Service:

metadata:
  labels:
    app: spring-boot-app  # 해결: ServiceMonitor가 찾는 레이블 추가
    app.kubernetes.io/instance: grass-diary-backend-release

 

레이블 수정은 다음 명령어로 가능합니다.

 

혹은 직접 edit 명령어로 수정하셔도 됩니다. 저는 직접 edit 명령어로 수정 해주었습니다.

kubectl patch svc spring-boot-app-svc -n your-namespace -p '{"metadata":{"labels":{"app":"spring-boot-app"}}}'

 


 

6. 최종 설정 순서

  1. 먼저 Spring Boot 애플리케이션의 의존성과 설정을 완료합니다.
  2. Kubernetes Service를 올바른 레이블과 함께 생성합니다.
  3. ServiceMonitor를 생성하고 Service와 레이블이 일치하는지 확인합니다.
  4. Prometheus 타겟 페이지에서 정상적으로 인식되는지 확인합니다.
  5. Grafana에서 Spring Boot 2.1 System Monitor 대시보드를 import하여 시각화합니다.

7. 문제 해결 및 확인

 

Prometheus와 Grafana의 타겟 페이지에서 Spring Boot 애플리케이션의 메트릭이 정상적으로 수집되는지 확인할 수 있습니다.

이 과정을 통해 Kubernetes 클러스터에서 Spring Boot 애플리케이션의 모니터링을 구축할 수 있습니다.

프로메테우스 UI Target에서도 어떤 것들을 모니터링하고 있는지 볼 수 있습니다.

 

이상으로 Kubernetes 환경에서 Spring Boot 애플리케이션 모니터링 설정 방법에 대한 설명을 마치겠습니다.

추가 질문이나 피드백이 있으시다면 댓글로 남겨주세요! 😊