[AlertManager] 서버 다운에 대한 실시간 알림

최인준·2025년 3월 19일
0
post-thumbnail

문제 상황

Prometheus와 Grafana를 활용하여 서버에 대한 모니터링 환경을 구성해놓았다.

그래서 서버의 리소스를 계속 파악할 수 있고 서버가 다운이 된다면 모니터링 화면을 통해 알아낼 수 있다.

하지만 서버가 다운된 즉시 알 수 있는 것은 아니다. 직접 들어가서 보아야 다운된 것을 확인할 수 있고 최악의 상황은 사용자가 나보다 먼저 서버다운을 경험하는 것이다.

그래서 서버가 다운되면 그 즉시 알림을 받을 수 있도록 구현해달라는 요구사항이 들어왔다.

Prometheus를 쓰고 있었기에 AlertManager를 활용하기로 했고 Discord webhook으로 알림을 보내게 했다.

AlertManager란?

AlertManager는 Prometheus의 알림 관리를 담당하는 구성 요소로, Prometheus에서 감지한 이상 징후(예: 서버 다운, 응답 속도 지연 등)에 대한 알림을 정의하고, 이를 이메일, Slack, Discord, PagerDuty 등의 다양한 채널로 전송하는 역할을 한다.

핵심 기능은 다음과 같다:

  • 알림 그룹화: 유사한 알림을 묶어서 관리
  • Silencing: 특정 조건에 따라 알림을 일시적으로 비활성화
  • 중복 제거: 동일한 알림을 중복 전송하지 않도록 방지
  • 다양한 수신 채널 지원: Slack, Discord, Webhook 등 다양한 알림 전송 옵션 제공

공식 홈페이지에서 더 자세한 내용을 확인할 수 있다.

https://prometheus.io/docs/alerting/latest/alertmanager/

아키텍처

아키텍처는 위 이미지와 같다. 이미지에는 email로 돼있지만 discord로 바꿔주면 나와 같다.

prometheus의 메트릭을 기반으로 alertmanager가 작동되도록 구현했다.

AlertManager 적용

먼저 첫번째 스텝으론 당연하게도 alertmanager를 설치해준다.

https://github.com/prometheus/alertmanager

자신에게 맞는 아키텍처, 버전을 골라서 설치한다.

설치하고 가장 먼저 해준 일은 systemd에 alertmanager 서비스를 정의해 실행, 정지를 간편하게 한다.

/etc/systemd/system.alertmanager.service

[Unit]
Description=Alertmanager
After=network.target

[Service]
User=root
ExecStart=/opt/alertmanager/alertmanager --config.file=/opt/alertmanager/alertmanager.yml
Restart=always

[Install]
WantedBy=multi-user.target

등록된 스크립트를 보면 alertmanager.yml을 기반으로 실행한다.

그렇기에 alertmanager.yml을 정의 해야한다. 그전에 alert rule을 먼저 정의해보자.

여기에는 어떤 메트릭을 기반으로 어떤 알림 메세지를 보낼 지 정의한다.

/etc/prometheus/alert.rules.yml

groups:
  - name: server_down__alerts
    rules:
      - alert: HighCPUUsage
        expr: up{job="homepage_actuator", instance="backend.sssupport.shop:443"} == 0  # 백엔드 서버가 다운되었을 경우
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "🚨서버 다운 경고!"
          description: " 서버가 다운되었습니다."
          message: "서버 다운되엇습니다."

prometheus.yml에서 어떤 rule_files를 참고할 것인 지 정의해야해서 prometheus.yml과 같은 경로에 파일을 생성했다.

위의 내용으로는 expr에 메트릭 조건(PromQL 표현식)을 지정한다. 나의 경우에는 서버가 다운되는 지를 감지해야 하기 때문에 up 상태를 확인하였다.

for 조건을 통해 내가 지정한 조건이 얼마나 지속됐는 지에 대한 조건도 설정할 수 있다.

2m으로 설정돼있기 때문에 서버 다운이 2분간 지속되면 알림이 가는 규칙이 설정된 것이다.

annotations에 알림 메세지를 설정한다. 이 메세지를 alertmanager.yml에서 활용할 것이다.

이제 prometheus.yml에 정의한 규칙을 넣어줘야한다. 다음 두 줄을 추가한다.

rule_files:
  - "/etc/prometheus/alert.rules.yml"

이제 alertmanager를 실행시킬 기반이 될 config 파일을 작성하자.

/opt/alertmanager/alertmanager.yml

route:
  group_by: ['alertname', 'job']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 1h
  receiver: 'discord_webhook'
receivers:
  - name: 'discord_webhook'
    discord_configs:
      - webhook_url: {디스코드 웹훅 URL}
        title: '{{ .CommonAnnotations.summary }}'
        message: '{{ .CommonAnnotations.description }}'
        #content: '{{ .CommonAnnotations.message }}'
        username: 'Server Alert Bot'
        #avatar_url: 'https://example.com/avatar.png'
inhibit_rules:
  - source_match:
      severity: 'critical'
    target_match:
      severity: 'warning'
    equal: ['alertname', 'dev', 'instance']

주요 필드를 확인해보면 다음과 같다.

route.reciever : 알림을 보낼 채널을 정의한다.

이제 receivers에서 채널들을 정의하면 된다. 현재는 하나뿐이다.

webhook_url : 디스코드 채널에 알림을 보낼거니 해당 채널의 웹훅 URL을 정의한다.

title, message : 여기서 CommonAnnotations는 alert.rules.yml에 정의한 제목과 설명을 가져오는 것이다.

username : 채널에서 알림을 보내는 알림봇의 이름을 정의한다.

avatar_url : 알림봇의 이미지를 지정하는데 굳이 필요없어 주석 처리했다.

이제 systemctl start alertmanager로 실행시켜보자.

실행 후 staus를 확인하면 위 이미지와 같아야한다.

{서버ip}:9093/#/status에 접속하여 UI로도 확인할 수 있다. 다음과 같이 alertmanager가 어떤 Config 파일을 참조하여 실행되고 있는 지 확인할 수 있다.

테스트

알림이 잘 오는 지 테스트 해보기 위해 서버 다운을 고의적으로 할 수는 없어서 반대로 테스트 해봤다.

서버가 다운이 안된 상태로 2분이 지속되면 알림이 가게 하였고 결과는 다음과 같다.

팀원들이 보고 서버가 다운된 줄 알까봐 메세지 내용은 약간 바꿨다!

0개의 댓글

관련 채용 정보