ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ECS Fargate 환경에서 JMX Exporter 이용한 prometheus metric 수집
    AWS 2023. 6. 25. 09:22

    1. awsvpc network를 사용하는 fargate task definition 생성

    awsvpc를 선택한 이유는

    bridge 모드로 선택하게 되면, 나중에 service discovery를 만들 때, srv 레코드를 기반으로 만들어야 한다.

    srv 레코드를 사용하려면 app단의 수정이 필요해지고 나의 경우에는 app단 수정을 안하기 위해, awsvpc 모드를 선택했다. 

     

    fargate를 선택한 이유는 서버 관리가 필요없다는 이점도 있겠지만, 

    awsvpc와 ec2기반 ECS를 사용하게 되면, ec2 사양에 맞게 ip개수가 결정된다. 

    현재 사용 중인 ec2로는 ip 개수를 맞추기 힘들어 fargate를 사용했다.  

     

    2. service 생성할 때 service discovery 설정하기 

    service discovery를 생성하면 private dns를 만들어지고 해당 dns를 통해서 prometheus가 scrap을 할 수 있다.

    따라서 service 생성하는 시점에 service discovery를 설정해주어야 한다.

     

    나의 경우에는 service discovery를 A 레코드, TTL을 5초로 주었다. 

    TTL을 낮게 설정했는데 TTL이 높으면 container가 scale하는 상황이 될 때,

    dns가 캐싱되어 없는 ip를 참조하거나 있는 ip를 참조하지 않아 의도대로 동작하지 않는다. 

     

    참고로 service connect는 service discovery 기능이긴 한데,

    얘는 위에서 TTL 문제 같은 것들을 고려한 그 이상의 기능으로 이를 설정하기 위한 별도의 컨테이너가 추가로 배포된다. 

    나는 해당 기능은 사용하지 않았다. 

     

    3. jmx_exporter_config.yaml 작성하기

    jmx exporter를 실행하기 위한 config 파일로 Dockerfile에 추가한 후, 

    jmx exporter jar를 실행시킬 때 함께 실행시킬 것이다. 

    ---
    startDelaySeconds: 5 # JMX Exporter가 모든 초기화 작업을 완료하고 준비 상태가 될 시간을 주기 위해 사용
    ssl: false
    lowercaseOutputName: true # 모든 메트릭 이름이 소문자로 출력
    lowercaseOutputLabelNames: true # 모든 레이블 이름이 소문자로 출력

     

     

    4. dockerfile에 JMX exporter를 agent로 추가하기

    jmx exporter는 agent방식으로 동작하기 때문에 jar 파일을 다운받아 실행시켜야 한다. 

    실행 방식은 Dockerfile 내부를 참고하자. 

    FROM openjdk:17-jdk-alpine AS build
    
    WORKDIR /app
    
    COPY . .
    
    WORKDIR /app/test-app
    
    RUN ./gradlew build --exclude-task test
    
    FROM openjdk:17-jdk-alpine
    
    # Set environment variables
    ENV JMX_EXPORTER_VERSION 0.16.0
    ENV JMX_EXPORTER_CONFIG jmx_exporter_config.yaml
    ENV JMX_EXPORTER_PORT 9091
    ENV JAVA_OPTS "-javaagent:/app/jmx_prometheus_javaagent-${JMX_EXPORTER_VERSION}.jar=${JMX_EXPORTER_PORT}:${JMX_EXPORTER_CONFIG}"
    ENV JMX_EXPORTER_DOWNLOAD_URL "https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/${JMX_EXPORTER_VERSION}/jmx_prometheus_javaagent-${JMX_EXPORTER_VERSION}.jar"
    ENV TZ=Asia/Seoul
    ENV SPRING_PROFILES_ACTIVE=default
    
    WORKDIR /app
    
    # Download JMX Exporter
    ADD ${JMX_EXPORTER_DOWNLOAD_URL} /app/
    
    # Add the configuration file for the JMX exporter
    COPY --from=build /app/jmx_exporter_config.yaml ${JMX_EXPORTER_CONFIG}
    
    # Copy the application jar file
    COPY --from=build /app/test-app/build/libs/test-app-0.0.1-SNAPSHOT.jar app.jar
    
    # Install tzdata and set timezone
    RUN apk add --no-cache tzdata && \
        ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \
        echo $TZ > /etc/timezone
    
    EXPOSE 9090  8080
    
    ENTRYPOINT ["sh", "-c", "java ${JAVA_OPTS} -jar app.jar --spring.profiles.active=${SPRING_PROFILES_ACTIVE}"]

     

    5. prometheus.yaml 작성 후, prometheus 재시작 

    참고로 나의 경우

    prometheus는 fargate를 공유하는 같은 vpc에서 ec2 인스턴스로 동작시키며   

    scrap을 할 때 포인트는 dns service discovery를 사용한다,  

    # my global config
    global:
      scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
      evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
      # scrape_timeout is set to the global default (10s).
    
    # Alertmanager configuration
    alerting:
      alertmanagers:
        - static_configs:
            - targets:
              # - alertmanager:9093
    
    # Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
    rule_files:
      # - "first_rules.yml"
      # - "second_rules.yml"
    
    # A scrape configuration containing exactly one endpoint to scrape:
    # Here it's Prometheus itself.
    scrape_configs:
      # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
      - job_name: "prometheus"
    
        # metrics_path defaults to '/metrics'
        # scheme defaults to 'http'.
    
        static_configs:
          - targets: ["localhost:9090"]
    
      - job_name: "node-exporter"
        static_configs:
          - targets: ["localhost:9100"]
          
      - job_name: "test-app"
        dns_sd_configs:
          - names: ['app.test.local']
            type: 'A'
            port: 8080

     

    이후 prometheus를 재시작한다. 

    systemctl restart prometheus

     

    7. prometheus에서 메트릭 수집되는 것을 확인

    다음과 같이 jvm으로 시작하는 metric을 확인할 수 있다면, 잘 scrap을 하고 있다는 것이다. 

     

    반응형

    'AWS' 카테고리의 다른 글

    다중 AWS Profile 사용  (0) 2023.10.31
    ALB에 ACM으로 생성한 공인 인증서 적용 절차(feat.terraform)  (0) 2023.03.21
    AWS Auto Scaling 실습  (0) 2021.08.02
    NAT Instance port-forwarding  (0) 2021.08.01
    AWS ELB(ALB, NLB) 실습  (0) 2021.07.30

    댓글

Designed by Tistory.