(Docker) Prometheus + Grafana + Alertmanager 모니터링, 시각화 및 알림

윤준혁·2024년 8월 7일

문제 상황

  • 서비스를 모니터링과 알림없이 운영할 경우 장애의 지연된 발견과 처리, 성능 저하의 늦은 인지, 자원 사용의 비효율성 등이 큰 비용을 초래할 수 있음
  • 이러한 문제점을 해결하기 위해 Prometheus, Grafana, Alertmanager를 도입
  • Prometheus : 실시간 모니터링 및 경고를 위한 오픈 소스 시스템
  • Grafana : 다양한 데이터 소스를 시각화하는 오픈 소스 시스템
  • Alertmanager : Prometheus의 알림을 처리하고 관리하는 시스템

해결 방법

  • 현재 프로젝트는 docker-compose를 통해 컨테이너 구축 및 배포를 진행중이므로 docker-compose에 해당 프로그램들을 추가
## docker-compose.yml
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    volumes:
      - /home/ubuntu/prometheus.yml:/etc/prometheus/prometheus.yml
      - /home/ubuntu/alert.rules:/etc/prometheus/alert.rules
    ports:
      - "9090:9090"

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    ports:
      - "3001:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    depends_on:
      - prometheus
    volumes:
      - grafana-storage:/var/lib/grafana
      
  node-exporter:
    image: prom/node-exporter:latest
    container_name: node-exporter
    ports:
      - "9100:9100"

  mariadb-exporter:
    image: prom/mysqld-exporter:latest
    container_name: mariadb-exporter
    command:
      - "--mysqld.username=lotto:1234"
      - "--mysqld.address=mariadb:3306"
    ports:
      - "9104:9104"
      
  alertmanager:
    image: prom/alertmanager:latest
    container_name: alertmanager
    volumes:
      - /home/ubuntu/alertmanager.yml:/etc/alertmanager/alertmanager.yml
    environment:
      SPRING_MAIL_USERNAME: ${SPRING_MAIL_USERNAME}
      SPRING_MAIL_PASSWORD: ${SPRING_MAIL_PASSWORD}
    ports:
      - "9093:9093"
  • node-exporter, MySql-exporter를 통해 EC2와 DB에서 오는 장애나 오류를 알 수 있도록 Prometheus와 연동
## prometheus.yml
global:
  scrape_interval: 15s

alerting:
  alertmanagers:
    - static_configs:
        - targets:
            - 'alertmanager:9093'

rule_files:
  - "alert.rules"

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'backend'
    metrics_path: '/actuator/prometheus'
    static_configs:
      - targets: ['backend:8080']

  - job_name: 'node_exporter'
    static_configs:
      - targets: [ 'node-exporter:9100' ]

  - job_name: 'mariadb-exporter'
    static_configs:
      - targets: [ 'mariadb-exporter:9104' ]
  • Alertmanager를 통해 지정한 항목들의 특정 범위 초과 시 메일로 알림
## alertmanager.yml
groups:
  - name: 시스템_경고
    rules:
    - alert: CPU_사용률_높음
      expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
      for: 5m
      labels:
        severity: 경고
      annotations:
        summary: "{{ $labels.instance }}의 CPU 사용률 높음"
        description: "{{ $labels.instance }}의 CPU 사용률이 5분 동안 80%를 초과했습니다."

    - alert: 메모리_사용률_높음
      expr: (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100) < 20
      for: 5m
      labels:
        severity: 경고
      annotations:
        summary: "{{ $labels.instance }}의 메모리 사용률 높음"
        description: "{{ $labels.instance }}의 메모리 사용률이 5분 동안 80%를 초과했습니다."

    - alert: 애플리케이션_다운
      expr: up{job="your_application"} == 0
      for: 1m
      labels:
        severity: 심각
      annotations:
        summary: "애플리케이션 다운"
        description: "애플리케이션이 1분 이상 다운되었습니다."

    - alert: 데이터베이스_연결_실패
      expr: up{job="mariadb-exporter"} == 0
      for: 1m
      labels:
        severity: 심각
      annotations:
        summary: "데이터베이스 연결 실패"
        description: "데이터베이스 연결이 1분 이상 실패했습니다."

    - alert: 데이터베이스_쿼리_응답_시간_높음
      expr: rate(mysql_global_status_seconds_total[5m]) > 1
      for: 5m
      labels:
        severity: 경고
      annotations:
        summary: "데이터베이스 쿼리 응답 시간 높음"
        description: "데이터베이스 쿼리 응답 시간이 5분 이상 높습니다."

    - alert: 네트워크_트래픽_높음
      expr: rate(node_network_receive_bytes_total[5m]) > 1e9
      for: 5m
      labels:
        severity: 경고
      annotations:
        summary: "네트워크 트래픽 높음"
        description: "네트워크 트래픽이 5분 동안 1GB/s를 초과했습니다."
  • Grafana에서 Node Exporter와 MySQL Overview 대시보드를 추가

Select a Prometheus data source를 클릭해 prometheus와 연동(Node, MySQL 둘 다)

  • 대쉬보드에 두 개가 추가됨

  • 사용율은 상시 표시된다
## alert.rules
  - name: 테스트_경고
    rules:
    - alert: 테스트_알림
      expr: vector(1)
      for: 1m
      labels:
        severity: 테스트
      annotations:
        summary: "테스트 알림"
        description: "이것은 테스트 알림입니다."
  • Alertmanager의 알림 테스트(alert.rules에 해당 부분을 추가)
## alertmanager.yml
global:
  resolve_timeout: 5m
  smtp_smarthost: 'smtp.naver.com:465'
  smtp_from: ${SPRING_MAIL_USERNAME}
  smtp_auth_username: ${SPRING_MAIL_USERNAME}
  smtp_auth_password: ${SPRING_MAIL_PASSWORD}

route:
  receiver: 'default-receiver'

receivers:
  - name: 'default-receiver'
    email_configs:
      - to: 'your-email'
        require_tls: false
        tls_config:
          insecure_skip_verify: true

inhibit_rules:
  - source_match:
      severity: 'critical'
    target_match:
      severity: 'warning'
    equal: ['alertname', 'dev', 'instance']
  • 젠킨스에 등록된 환경 변수를 받아올 수 있도록 개인 정보는 변수처리 해주고
stage('Prepare Alertmanager Configuration') {
    steps {
        script {
            sh '''
                sed -i 's|\${SPRING_MAIL_USERNAME}|'${SPRING_MAIL_USERNAME}'|' alertmanager.yml
                sed -i 's|\${SPRING_MAIL_PASSWORD}|'${SPRING_MAIL_PASSWORD}'|' alertmanager.yml
            '''
        }
    }
}
stage('Deploy to AWS') {
    steps {
        script {
            sshagent(['my-ssh-key']) {
                sh 'rsync -avz -e "ssh -o StrictHostKeyChecking=no" docker-compose.yml ubuntu@ec2-43-203-173-180.ap-northeast-2.compute.amazonaws.com:/home/ubuntu/'
                sh 'rsync -avz -e "ssh -o StrictHostKeyChecking=no" prometheus.yml ubuntu@ec2-43-203-173-180.ap-northeast-2.compute.amazonaws.com:/home/ubuntu/'
                sh 'rsync -avz -e "ssh -o StrictHostKeyChecking=no" alertmanager.yml ubuntu@ec2-43-203-173-180.ap-northeast-2.compute.amazonaws.com:/home/ubuntu/'
                sh 'rsync -avz -e "ssh -o StrictHostKeyChecking=no" alert.rules ubuntu@ec2-43-203-173-180.ap-northeast-2.compute.amazonaws.com:/home/ubuntu/'
            }
        }
    }
}
  • 젠킨스파일에 해당 stage를 업데이트

  • 테스트 알림이 잘 처리된 모습

결과

  • 아직 사용자가 없는 서비스라 어떤 문제가 발생할 지 모르지만 해당 시스템을 통해 문제가 생겨도 빠르게 대처 가능

추후 개선

  • Jmeter를 통한 부하테스트 진행 후, 자원 사용율에 따라 컨테이너 추가 및 수정 가능성

혹시

  • 저도 이번 시스템을 적용하면서 소소한 오류를 많이 겪었는데 이런 부분들은 개인적으로 찾아보는 편이 실력 향상에 도움이 되는 듯 합니다.

0개의 댓글