[AWS] RDS Exporter로 비용 최적화하기

이동엽·2024년 4월 15일
1

aws

목록 보기
4/4

1. 개요

이전 글에서 AWS CloudWatch로 RDS를 모니터링 할 수 있도록 대시보드를 생성했다.

다만, prometheus-rds-exporter를 이용하여 매트릭을 수집하면 더 많은 정보를 확인할 수 있다.
또한 CloudWatch를 이용하는 것보다, AWS API를 호출하는 방식을 사용하므로 비용을 절감할 수 있다.

나중에 모니터링해야 할 인프라가 커진다면 CloudWatch를 이용해야만 하겠지만, 비용 최적화가 중요한 스타트업의 경우에는 rds_exporter를 이용해 충분히 모니터링 할 수 있다고 생각한다.


2. 사전 설명

사전에 docker가 설치되어 있지 않다면 설치가 필요. 설치 방법 : 도큐먼트 참고

모니터링 구축에 필요한 서비스들은 아래와 같다.

  • docker : prometheus, grafana, rds_exporter를 가상환경에서 구동
    - rds_exporter : AWS CloudWatch Metric 추출
    • prometheus : 매트릭을 수집 및 저장
    • grafana : prometheus에서 수집한 데이터를 대시보드로 시각화

3. exporter 선정

AWS RDS의 메트릭을 추출하기 위해서는 주로 3가지의 exporter가 자주 쓰이는 것으로 파악했다.

  1. prometheus/node_exporter : OS 관련 매트릭을 추출
  2. prometheus/mysqld_exporter : DB 관련 매트릭을 추출
  3. rds_exporter : OS + DB 관련 매트릭을 추출
    1. percona/rds_exporter
    2. qonto/rds_exporter

→ node_exporter & mysqld_exporter를 실행하는 것보다 rds_exporter 하나만 이용하는 것이 효율적이라고 판단하여 선택함.

우선 percona에서 제공하는 rds_exporter가 Github Star 수가 많아 채택.


4. 시스템 구축

4-1. rds_exporter 도커 환경 구성

percona/rds_exporter 소스코드 clone

$ git clone https://github.com/percona/rds_exporter.git

$ cd rds_exporter

docker image 빌드를 위한 Dockerfile 수정

$ vi Dockerfile

# 아래 내용 작성 
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
# 첫 번째 단계: 빌드 환경 준비
FROM golang:1.16 as build

# 작업 디렉토리 설정
WORKDIR /usr/src/rds_exporter

# 현재 디렉토리의 소스 코드를 컨테이너로 복사
COPY . .

# 의존성 관리 도구를 사용하여 의존성 설치 및 애플리케이션 빌드
RUN go mod download
RUN CGO_ENABLED=0 go build -o /bin/rds_exporter

# 두 번째 단계: 최종 이미지 준비
FROM alpine:latest

# 빌드 단계에서 생성된 실행 파일을 최종 이미지로 복사
# COPY --from=build /bin/rds_exporter /bin/rds_exporter
COPY --from=build /bin/rds_exporter /bin/

# 필요한 패키지 설치 및 CA 인증서 업데이트
RUN apk update && \
    apk add --no-cache ca-certificates && \
    update-ca-certificates

# 컨테이너가 리스닝할 포트 지정
EXPOSE 9042

# 컨테이너 실행 시 실행될 명령
ENTRYPOINT ["/bin/rds_exporter", "--config.file=/etc/rds_exporter/config.yml"]
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> EOF

빌드에 필요한 설정파일 작성

$ vi config.yml
>>>
instances:
  - region: ap-northeast-2
    instance: sagedb

    aws_access_key: {aws_access_key}
    aws_secret_key: {aws_secret_key}
    
    disable_basic_metrics: false
    disable_enhanced_metrics: false
<<< EOF

Docker Image Build

$ sudo docker build -t rds_exporter .

# 빌드 결과 확인
$ docker images

4-3. prometheus.yml에 scrape_configs 작성


... # (global & rule 설정)

scrape_configs:
  - job_name: RDS Exporter Basic
    scrape_interval: 60s
    scrape_timeout: 55s
    metrics_path: /basic
    honor_labels: true
    honor_timestamps: false
    scheme: "http"
    static_configs:
      - targets: ["host.docker.internal:9042"]

4-4. docker-compose.yml 작성

version: '3.8'  # 파일 규격 버전
services:       # 이 항목 밑에 실행하려는 컨테이너 들을 정의
  prometheus:
    image: prom/prometheus
    container_name: prometheus
    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
    network_mode: host
    extra_hosts:
      - host.docker.internal:host-gateway

  grafana:
    image: grafana/grafana
    container_name: grafana
    ports:
      - "6300:3000"  # 접근 포트 설정 (컨테이너 외부:컨테이너 내부)
    volumes:
      - ./grafana/volume:/var/lib/grafana
    restart: always
    links:
      - prometheus
    networks:
      - promnet

networks:
  promnet:
    driver: bridge

5. 실행

5-1. RDS Exporter 실행

Docker Image 실행

$ docker run -d -p 9042:9042  -v /{rds_exporter 위치}/config.yml:/etc/rds_exporter/config.yml --name rds_exporter rds_exporter

# 재실행 시 동일한 이름 충돌 발생하면 아래 명령어로 삭제
$ sudo docker rm -f rds_exporter

# 실행 결과 확인
$ docker ps

5-2. Grafana & Prometheus 실행

# docker-compose.yml 위치에서 실행
$ docker compose start(실행중이라면 restart)

5-3. 동작 확인

prometheus target 확인 : http://{server-ip}:{port}/targets?search=


6. 그라파나 대시보드 생성

6-1. 대시보드 커스텀

GrafanaLabs에서 제공하는 대시보드 템플릿 중 바로 사용할 수 있는 대시보드는 아쉽게도 없다.

템플릿에서 사용하는 매트릭(지표)와 위에서 사용한 rds_exporter의 매트릭 명칭이 다르기 때문.

  • 따라서 약간의 커스텀이 필요
  • → 기존에 템플릿으로 작성된 대시보드들의 지표 명만 바꾸면 그대로 이용할 수 있다.
  • → 이로써, 동시에 여러 템플릿을 비교하여 필요한 대시보드들만 가져와 사용할 수 있게 된다.

6-2. 참고한 대시보드목록

6-3. RDS Exporter가 제공하는 메트릭 확인하기


7. 메트릭 스크랩 커스텀

아래 두 글을 보면, percona 사의 rds exporter가 너무 많은 메트릭을 자주 요청하기 때문에 AWS API 요청 비용이 발생한다고 나와있다.

7-1. /basic 메트릭만 사용하기

우선 아래(8-1)에 나올 최종 대시보드 결과물을 보면, 충분히 /basic 메트릭만을 가지고도 모니터링을 구축할 수 있다.

따라서 prometheus.yml에 /enhanced 관련 메트릭 수집 job을 제거하였다.

7-2. 빈번한 스크랩을 위해 call 주기 수정하기

위에서 첨부한 블로그의 내용을 요약하면 아래와 같다.

AWS CloudWatch API가 60초마다 Refresh하는데, RDS Exporter는 10초마다 메트릭을 조회함으로써 중복 데이터를 가져온다.
따라서 주기를 수정해야 한다.

위 내용을 참고하여 rds_exporter 소스코드를 보니, enhanced 메트릭의 경우는 현재(20240403) 60초마다 refresh되며,

basic 정보는 주기가 11분인 것을 확인할 수 있었다. (1분동안 불러오고, 10분간 딜레이)

→ 따라서 커스텀 할 필요 없어보임.


8. 최종 결과물

8-1. 대시보드


9. 메트릭 알림 설정

RDS Database Connections가 95%에 도달했을 때에 Slack 알림을 받으려고 한다.

: DB Connection 최대값이 전체 커넥션 수(648)의 95%(615)를 초과할 경우 알람이 울리도록 설정

알람 발생 예시


10. 참고 자료

profile
백엔드 개발자로 등 따숩고 배 부르게 되는 그 날까지

0개의 댓글