[Prometheus + Grafana] Monitoring 도입하기 ( + Node Exporter)

Denia·2024년 2월 13일
0

TroubleShooting

목록 보기
19/24

저는 혼자서 개인 사이드 프로젝트를 진행하고 있습니다.

매번 AWS 혹은 EC2 Console에 ssh로 접속해서 서버의 상태를 확인하는 것을 매우 비효율적이기 때문에 이번에 Monitoring를 도입하기로 했습니다.

사용할 기술 스택은 영한님께서도 추천해주신 PrometheusGrafana를 이용하여 진행해보겠습니다.

두 기술 스택 모두 오픈소스라서 비용 문제 없이 접근할 수 있습니다. 이 점이 취준생 입장인 저에게 있어 상당히 매력적이었습니다.

그리고 두 기술 모두 커뮤니티가 잘 되어 있기 때문에 관련 자료의 접근성이 좋아서 선택했습니다


참고 블로그

Spring Boot에 Actuator 및 Prometheus 의존성 추가하기

build.gradle에 추가하기

build.gradle에 해당 의존성을 추가해줍니다. (추가 후에는 꼭 Load Gradle Changes 해주세요!!!)


//Spring Actuator
implementation 'org.springframework.boot:spring-boot-starter-actuator'
//Prometheus
implementation 'io.micrometer:micrometer-registry-prometheus'

application.yaml에 추가하기

application.yamlactuator 관련 설정을 추가해줍니다.


server:
  tomcat: #  tomcat 메트릭 설정 on. 톰캣 메트릭은 tomcat. 으로 시작
    mbeanregistry: # 톰캣 메트릭을 모두 사용하려면 다음 옵션을 켜야하며, 옵션을 켜지 않으면 tomcat.session. 관련정보만 노출됩니다
      enabled: true

management:
  endpoints:
    web:
      exposure:
        include: "*" #  이 설정은 모든 Actuator 엔드포인트를 외부에 노출
      base-path: /api/actuator # Actuator 엔드포인트의 기본 경로 지정
  server:
    port: 9090 # Actuator 엔드포인트가 서비스될 서버의 포트
    

해당 내용을 다 추가하셨으면, Build 하시고 서버에 올려주시면 됩니다!

[Optional] Security에 URL 추가하기

acturator는 서버의 정보들이 포함되므로, 노출되면 위험할 수 있습니다.

그러므로 Security에 해당 actuator URL에 대한 설정을 추가해줍니다.


@Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .csrf(AbstractHttpConfigurer::disable)
                .cors(AbstractHttpConfigurer::disable)
                .authorizeHttpRequests(req ->
                        req
                                .requestMatchers(getActuatorAllUrl()).hasRole("ACTUATOR")
                                .anyRequest().hasAnyRole("USER")
                )
                .sessionManagement(session -> session.sessionCreationPolicy(STATELESS))
                .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }
    

[Optional] Prometheus에서 사용하지 않는 Metric은 노출되지 않도록 하기

해당 Bean을 추가해주시면 해당 하는 Metric들은 노출 되지 않습니다.


@Bean
    public MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() {
        return registry -> registry.config()
                .meterFilter(MeterFilter.deny(id -> id.getName().startsWith("spring.data.repository")));
    }
    

모니터링 서버에 Prometheus 및 Grafana 설치하기

모니터링 서버에는 간편하게 사용할 수 있게 Docker-Compose를 이용하여 PrometheusGrafana를 설치하고 쓰겠습니다.

  1. 모니터링 서버에 접속 후 DockerDocker-Compose를 설치해주세요 (본인 OS에 맞춰서 설치하시면 됩니다.)

  2. docker-compose.yml에서 사용할 폴더를 추가해주겠습니다.

    
    # 현재 폴더에서 prometheus랑 grafana 폴더를 만들어 줍니다.
    mkdir prometheus
    mkdir grafana
    
    # prometheus 폴더에 들어가서 config, volume 폴더를 만들어줍니다.
    cd prometheus
    mkdir config
    mkdir volume
    
    # config 폴더에 들어가서 prometheus.yml 파일을 만들어 줍니다. (내용은 추후에 추가)
    cd config
    touch prometheus.yml
    
    # grafana 폴더에 들어가서 volume, provisioning 폴더를 만들어줍니다.
    cd ../../grafana
    mkdir volume
    mkdir provisioning
    
    # 원래 위치로 돌아오기
    cd ..
    
  3. docker에서 수정할 수 있도록 grafana 폴더 및 prometheus의 폴더의 권한을 변경합니다.

    
    sudo chmod -R 777 ./prometheus
    sudo chmod -R 777 ./grafana
    
  4. 이제 prometheus.yml에다가 내용을 추가해주겠습니다.

    
    # prometheus.yml 열기
    vi prometheus/config/prometheus.yml
    
    
    global:
      scrape_interval: 15s     # scrap target의 기본 interval을 15초로 변경 / default = 1m
      scrape_timeout: 15s      # scrap request 가 timeout waite/ default = 10s
    
      external_labels:
        monitor: 'monitor'       # 기본적으로 붙여줄 라벨
      query_log_file: query_log_file.log # prometheus의 쿼리 로그들을 기록. 설정되지않으면 기록하지않는다.
    
    # 매트릭을 수집할 엔드포인드를 지정한다.
    scrape_configs:
      # job 기준으로 메트릭을 수집한다.
      - job_name: "spring-actuator" # job_name 은 모든 scrap 내에서 고유해야한다
        metrics_path: '/api/actuator/prometheus' # 스프링부트에서 설정한 endpoint [metrics_path의 기본 경로는 '/metrics'], 뒤에 prometheus를 붙이면 prometheus의 정보를 가져온다.
        scrape_interval: 15s # global 값과 다르게 사용할려면 따로 정의하자.
        scheme: 'https' # request를 보낼 scheme 설정 [scheme의 기본값은 `http`]
        static_configs:
          - targets: ['ServerIP:Port'] # request를 보낼 server ip 그리고 actuator port를 적어주면 된다. (위에서 지정한 포트는 9090이며, 서버 IP는 EC2의 Public Ip를 적어주자)
        # 보안을 위해서 JWT를 사용. (내 Spring 서버에서 사용할 수 있는 JWT를 발급받아서 사용)
        bearer_token: 'JWT Token'
        
    • 주의 사항
      1. 내가 지정한 actuator 서버용 포트가 AWS EC2의 인바운드 포트로 잘 열려있는지 확인
      2. 내가 지정한 actuator URL이 Security에 필터링이 되지는 않는지, JWT를 제대로 발급받았는지 확인
      3. EC2에서 Docker를 이용하고 있다면, actuator 서버 포트를 잘 expose 시켰는지 확인 (제가 이 문제로 삽질을 많이 했습니다 ㅠㅠ)
  5. 다음으로 docker-compose.yml 를 작성하겠습니다.

    
    version: '3.3'  # 파일 규격 버전
    services:  # 이 항목 밑에 실행하려는 컨테이너 들을 정의
      prometheus:
        image: prom/prometheus
        container_name: prometheus
    		# 내 폴더랑 docker 폴더랑 연결
        volumes:
          - ./prometheus/config:/etc/prometheus
          - ./prometheus/volume:/prometheus
        ports:
          - 9090:9090 # 접근 포트 설정 (컨테이너 외부:컨테이너 내부)
        command: # web.enalbe-lifecycle은 api 재시작없이 설정파일들을 reload 할 수 있게 해줌
          - '--web.enable-lifecycle'
          - '--config.file=/etc/prometheus/prometheus.yml'
        restart: always
        networks:
          - promnet
      grafana:
        image: grafana/grafana
        container_name: grafana
        # user: "$GRA_UID:$GRA_GID"
        ports:
          - 3000:3000 # 접근 포트 설정 (컨테이너 외부:컨테이너 내부)
        volumes:
          - ./grafana/volume:/var/lib/grafana
          - ./grafana/provisioning/:/etc/grafana/provisioning/
        restart: always
        networks:
          - promnet
        depends_on:
          - prometheus
    
    networks:
      promnet:
        driver: bridge
        
  6. docker-compose up -d 명령어를 통해서 실행시켜 주세요. (docker-compose.yml 파일이 있는 곳에서 실행하셔야 합니다.)

  7. 정상적으로 실행이 되면, 모니터링 서버의 Public IP를 통해 prometheusgrarafa 로 접속을 해봅니다.

    • 모니터링 서버에서 인바운드 포트로 9090 포트가 열려있는지 확인!! (외부에서 아무나 접속을 하지 못하도록 내 IP만 접근이 가능하도록 합니다.)
    • prometheushttp://모니터링 서버 주소:9090 를 통해서 접속합니다.
      • 상단의 메뉴중 Status → Targets 을 누르면 메트릭을 가져올 서버가 제대로 연결이 되어있는지 확인이 가능합니다. (UP : 정상, DOWN : 실패)
      • config로 들어가시면 prometheus.yml 에 입력한 내용 확인이 가능합니다.
    • grarafahttp://모니터링 서버 주소:3000 를 통해서 접속합니다. (기본 계정 ID/PW: admin/admin)
      • 왼쪽 상단 햄버거 버튼 → Connections → Add new connection → prometheus 추가 → Connection URL에 http://prometheus:9090를 입력합니다. (같은 docker-compose network라서 가능) → Save & Test
      • 추천 Grafana DashBoard : Spring Boot 3.x Statistics

이렇게 해서 prometheus 및 grafana 설치를 완료했습니다 !!

grafana

(번외) Node Exporter를 추가하여 Cloud 서버의 Hardware 정보도 같이 수집하기

참고 블로그

Cloud 서버에 Node Exporter를 설치하고 Prometheus로 관련 메트릭을 수집하면 Cloud 서버의 하드웨어 정보도 수집하여 Grafana를 통해서 시각화가 가능합니다.

※ 저는 Spring 서버Docker로 구동 중이라, Node ExporterDocker로 구동했습니다 !

  1. EC2 서버에 접속 후 해당 명령어를 통해서 Node ExporterDocker로 실행한다.

    
    docker run -d --name node-exporter \
    --net="host" \
    --pid="host" \
    -v "/:/host:ro,rslave" \
    quay.io/prometheus/node-exporter:latest \
    --path.rootfs=/host
    

    ※ 해당 명령어에 대한 설명

    1. -d: 컨테이너를 백그라운드 모드로 실행

    2. -name node-exporter: 생성되는 컨테이너에 node-exporter라는 이름을 할당

    3. -net="host": 컨테이너가 호스트의 네트워크 네임스페이스를 사용하도록 설정. 이를 통해 컨테이너가 호스트와 동일한 네트워크 인터페이스와 포트를 사용할 수 있습니다.

    4. -pid="host": 컨테이너가 호스트의 PID 네임스페이스를 사용하도록 설정. 이는 컨테이너 내에서 호스트 시스템의 모든 프로세스 정보에 접근할 수 있게 합니다.

    5. v "/:/host:ro,rslave": 호스트의 루트 파일 시스템을 컨테이너의 /host 디렉토리에 읽기 전용(ro)으로 마운트하고 rslave 옵션은 마운트 네임스페이스의 변경사항이 마운트 포인트에 전파되도록 합니다.

    6. quay.io/prometheus/node-exporter:latest: 사용할 이미지입니다. Prometheus의 node-exporter 이미지의 최신 버전을 quay.io 레지스트리에서 가져옵니다.

    7. -path.rootfs=/hostnode-exporter에게 호스트의 파일 시스템이 /host에 마운트되었음을 알립니다. 이를 통해 node-exporter가 호스트 시스템의 메트릭을 올바르게 수집할 수 있습니다.

  2. EC2 서버의 9100 포트에 접속하면 Node Exporter가 실행중인 것을 확인할 수 있습니다. (혹시나 접속이 안되면 인바운드 포트를 열었는지 확인!!)

    1. http://EC2 서버 주소:9100/metrics 로 접속을 하시면 Node Exporter가 수집하는 메트릭에 관한 모든 정보들을 확인할 수 있습니다.
  3. 모니터링 서버가 Node Exporter데이터를 수집할 수 있도록 모니터링 서버의 Prometheus 설정에다가 해당 주소를 추가해줘야 합니다.

    1. 모니터링 서버에 접속 후 prometheus.yml 파일을 수정합니다. (아래 내용을 추가)
    
    - job_name: 'node-exporter-ocp' # AWS EC2의 하드웨어의 상태와 커널 관련 메트릭을 수집
        metrics_path: '/metrics' # endpoint
        scrape_interval: 30s # 수집 주기
        scheme: 'http' # request를 보낼 scheme 설정 | default = http
        static_configs:
        - targets: ['EC2 서버 주소:9100']
        
  4. 모니터링 서버의 Prometheus에 접속 후 Targets에 들어가 보시면 Node Exporter를 수집하고 있습니다.

  5. 추가된 데이터를 그래프로 확인하기 위해 Grafana에 접속 후 DashBoard를 추가합니다.

이렇게 해서 Node Exporter도 설치를 완료했습니다.

Node Exporter

profile
HW -> FW -> Web

0개의 댓글