Search
Duplicate

모니터링 서버 구성하기 with Spring Boot, Prometheus, Grafana

글감
노트
AWS
Spring
Infra
작성자
작성 일자
2023/08/31 04:33
상태
작성 중
공개여부
공개
Date
생성자
작업자

개요

프로젝트에서 백엔드 서버를 구성하고 난 뒤에, 해당 인스턴스와 어플리케이션의 상태에 대한 모니터링과 알림이 필요했다. 이를 위해 모니터링 데이터 모델인 Prometheus, 서버 어플리케이션의 정보(Metric)를 전달하는 Spring Actuator, 서버 인스턴스의 하드웨어 정보를 전달하는 NodeExporter를 이용했다.
또, 해당 정보들을 GUI로 볼 수 있게끔 대시보드를 제공하는 모니터링 툴인 Grafana와 특정 수집 정보에 대해 알림을 전송하는 AlertManager를 이용하여 우리가 얹은 서버가 잘 돌아가고 있는지, 문제는 없는지 모니터링 및 알림을 해보려고 한다.
별도의 모니터링 서버를 또 AWS에 두기에는 비용이 꽤 많이 청구될 것 같다고 생각했고, 마침 Oracle에서 제공하는 무료 인스턴스가 있으므로, 이 인스턴스에 실제 서버가 구동중인 EC2 인스턴스를 연결하여 모니터링 서버로 구성하려고 한다.

Prometheus

Prometheus는 독립형 오픈 소스 프로젝트로서 메트릭을 시계열 데이터로 수집하고 저장합니다. 즉, 메트릭 정보는 레이블이라는 선택적 키-값 쌍과 함께 기록된 타임스탬프와 함께 저장됩니다.
메트릭 이름과 키/값 쌍으로 식별되는 시계열 데이터가 포함된 다차원 데이터 모델
이 차원을 활용하기 위한 유연한 쿼리 언어인 PromQL
분산 스토리지에 의존하지 않고 단일 서버 노드가 자율적으로 운영됨
시계열 수집은 HTTP를 통한 풀 모델을 통해 이루어집니다.
중개 게이트웨이를 통해 푸시 시계열이 지원됩니다.
서비스 검색 또는 정적 구성을 통해 대상을 검색합니다.
다양한 그래프 및 대시보드 모드 지원

설치

애플리케이션, 하드웨어 Metric을 수집하려는 서버에 Prometheus를 설치한다.
wget https://github.com/prometheus/prometheus/releases/download/v2.45.0/prometheus-2.45.0.linux-arm64.tar.gz tar xzvf [다운로드 한 zip 파일]
Shell
복사
가장 최신의 LTS인 v2.45.0을 선택했다.
sudo apt install firewalld sudo firewall-cmd --zone=public --permanent --add-port=9090/tcp sudo firewall-cmd --reload
Shell
복사

node exporter

Prometheus Node Exporter는 하드웨어의 상태와 커널 관련 메트릭을 수집하는 메트릭 수집기입니다. Prometheus는 Node Exporter의 metrics HTTP endpoint에 접근하여 해당 메트릭을 수집할 수 있습니다. Node Exporter로 부터 수집한 메트릭을 Prometheus내의 TSDB에 저장하여 PromQL로 메트릭을 쿼리해 서버 상태를 모니터링할 수 있습니다.
하드웨어 메트릭을 제공하는 것이기 때문에, 우리가 모니터링하고자 하는 서버에 설치해서 열어두어야 한다.
서버 인스턴스 자체에 대한 모니터링이 필요하므로 서버 인스턴스에 서비스로 등록한다.

구성

wget https://github.com/prometheus/node_exporter/releases/download/v1.6.1/node_exporter-1.6.1.linux-arm64.tar.gz
Bash
복사
cp node_exporter-1.6.1.linux-arm64/node_exporter /usr/local/bin
Bash
복사
chmod +x /usr/local/bin/node_exporter
Bash
복사
sudo useradd -M -r -s /bin/false node_exporter
Bash
복사
sudo chown node_exporter:node_exporter /usr/local/bin/node_exporter
Bash
복사
sudo useradd -M -r -s /bin/false node_exporter
Bash
복사
sudo chown node_exporter:node_exporter /usr/local/bin/node_exporter
Bash
복사
sudo vi /etc/systemd/system/node_exporter.service
Bash
복사
[Unit] Description=Node Exporter Service After=network.target [Service] ExecStart=/usr/local/bin/node_exporter Restart=always User=node_exporter Group=node_exporter Environment=PATH=/usr/bin:/usr/local/bin [Install] WantedBy=multi-user.target
Bash
복사
sudo systemctl daemon-reload sudo systemctl enable node_exporter.service sudo systemctl start node_exporter.service
Bash
복사
sudo firewall-cmd --zone=public --permanent --add-port=9100/tcp sudo firewall-cmd --reload
Bash
복사
새로이 node exporter에 대해서 config을 추가했으므로, systemctl restart prometheus해준다.
prometheus(오라클)과 동일하게 node exporter(EC2)도 서비스로 등록해준다.
서로 각자 접근이 가능한 open port여야 하기 때문에, 오라클이 열어주었던 것 처럼 EC2도 열어주어야 한다.
다만, 해당 정보를 수집하는 것은 모니터링 서버만 가능하게끔 하고 싶은 것이므로, 소스 IP 주소에 프로메테우스가 설치된 인스턴스의 공인 IP를 지정해준다.

oracle 인스턴스

vnc에서 포트 열고, 인스턴스 내에서 방화벽 열어줘야함.

Grafana

나의 경우 Fedora(ARM64)였기 때문에 sudo yum으로 설치했다.
설치한 후에 grafana-server 를 실행하면, 다음과 같은 문구가 뜬다.
Grafana-server Init Failed: Could not find config defaults, make sure homepath command line parameter is set or working directory is homepath
Shell
복사
sudo service grafana-server start sudo systemctl enable grafana-server
Shell
복사
sudo ss -tunlp를 통해 확인해보면, 3000 포트(그라파나)가 실행 중인 것을 알 수 있다. 아까 위에서 했던 것 처럼, 3000 포트를 오라클 인스턴스 보안 그룹에서 설정해주고, 인스턴스 자체에서 방화벽을 열어주어야 한다.
sudo firewall-cmd --zone=public --permanent --add-port=3000/tcp sudo firewall-cmd --reload
Shell
복사
node exporter 대시보드 불러오기
ID : 1860

AlertManager

대충 소개글
단계는 아래와 같다.
AlertManager를 설치, 구성하기
AlertManager가 Prometheus와 연결되도록 설정하기
알림 규칙을 Prometheus에 구성하기
sudo cp alertmanager /usr/local/bin mkdir -p /etc/alertmanager sudo cp alertmanager.yml /etc/alertmanager/alertmanager.yml sudo mkdir -p /etc/alertmanager sudo cp alertmanager.yml /etc/alertmanager/alertmanager.yml sudo adduser -M -r -s /sbin/nologin alertmanager sudo chown alertmanager:alertmanager /etc/alertmanager/ sudo chown alertmanager:alertmanager /usr/bin/alertmanager sudo chown alertmanager:alertmanager /usr/local/bin/alertmanager sudo vim /etc/systemd/system/alertmanager.service sudo systemctl daemon-reload sudo systemctl enable --now alertmanager3
Shell
복사
sudo mkdir -p /data/alertmanager sudo mv amtool /usr/local/bin sudo chown alertmanager:alertmanager /usr/local/bin/amtool /usr/local/bin/alertmanager sudo chown -R alertmanager:alertmanager /data/alertmanager/ etc/alertmanager/* sudo chown -R alertmanager:alertmanager /data/alertmanager/ etc/alertmanager sudo mv amtool /usr/local/bin sudo chown -R alertmanager:alertmanager /data/alertmanager/ /etc/alertmanager sudo chown -R alertmanager:alertmanager /data/alertmanager/ /etc/alertmanager/* sudo firewall-cmd --zone=public --permanent --add-port=9093/tcp sudo firewall-cmd --reload #9093 들어가지는지 확인해보기 sudo systemctl restart prometheus
Shell
복사

디스코드 연결하기 - 웹 훅

디스코드 웹훅
채널(어드민 권한 필) 설정 - 연동 - 웹후크 만들기 - URL 복사
alertmanager.yml에서 webhook 걸어주기
#alertmanager.yml route: group_by: ['alertname'] group_wait: 30s group_interval: 5m repeat_interval: 1h receiver: 'web.hook' receivers: - name: 'web.hook' webhook_configs: - url: 'https://discord.com/api/webhooks/1148789672076652586/XNmg-d4e9V2kDxNDYdCXQDhFKEWWZS69KHOf8G3uPxRFIzGat7nM59tg3lHYwmH5HSlZ' inhibit_rules: - source_match: severity: 'critical' target_match: severity: 'warning' equal: ['alertname', 'dev', 'instance']
YAML
복사
# alert_rules.yml groups: - name: test rules: - alert: test-alert expr: java_lang_memory_heapmemoryusage_used{job="java"} > 1000000000 for: 5m labels: severity: warning annotations: summary: "{{ $labels.groups }} {{ $labels.instance }}" description: "{{ $labels.instance }}'s heap memory is going up (current value: {{ humanize $value }}" - alert: jvm-heap-memory-over-1.5GB expr: java_lang_memory_heapmemoryusage_used{job="java"} > 1500000000 for: 5m labels: severity: warning annotations: summary: "{{ $labels.groups }} {{ $labels.instance }}" description: "{{ $labels.instance }}'s heap memory is going up (current value: {{ humanize $value }}"
YAML
복사
/usr/local/bin/promtool check rules /etc/prometheus/alert_rules.yml
로 룰 체크를 해볼 수 있다.
sudo mkdir -p /etc/prometheus/rules 를 잊지마라.. 프로메테우스는 멍청이기때문에 prometheus.yml이 있는 디렉토리를 기준으로 지정해주어야한다..
route: group_by: ['alertname'] group_wait: 30s group_interval: 5m repeat_interval: 1h receiver: 'web.hook' receivers: - name: 'web.hook' webhook_configs: - url: 'https://discord.com/api/webhooks/1148789672076652586/XNmg-d4e9V2kDxNDYdCXQDhFKEWWZS69KHOf8G3uPxRFIzGat7nM59tg3lHYwmH5HSlZ' inhibit_rules: - source_match: severity: 'critical, warning' #중복 제거하는 레벨 # target_match: # severity: 'warning' # equal: ['alertname', 'dev', 'instance']
YAML
복사
테스트를 위해 다음과 같이 alertmanager.yml을 구성해보자.

Spring Boot 설정

actuator 의존성 && application.yml에서 exposure, prometheus 의존성 또한 마찬가지.

하나의 모니터링 서버에서 여러 인스턴스를 모니터링하기(단, 알림이 구분되어서 나가야함)

amtool을 이용해서 config들(alertmanager, prometheus.yml, alert_rule 등등)을 검증하자.