prometheus와 grafana를 이용한 DB 모니터링 구축하기
- 서버 1에는 2개 이상의 db 인스턴스 띄우기
- node exporter는 서버당 한개, db exporter는 db 인스턴스별로 띄우기
- 그라파나 로그인해서 접속하면 대시보드에서 인스턴스 상태 확인할 수 있도록 구축
MySQL DB 인스턴스를 2개 이상 띄우는 방법으로 Docker Container를 사용하는 방법을 채택하였습니다.
먼저 Docker를 설치해준 후 CentOS 7 도커 이미지를 사용하여 CentOS 7 컨테이너를 2개 생성하였습니다.
docker run --privileged --name mysql-server-1 -d -p 3306:3306 -p 9104:9104 centos:7 /sbin/init
docker run --privileged --name mysql-server-2 -d -p 13306:3306 -p 9105:9104 centos:7 /sbin/init
1번 DB는 MySQL을 위해 컨테이너의 3306번 포트를 서버의 3306번 포트로 매핑, MySQLD Exporter를 위해 컨테이너의 9104번 포트를 서버의 9104 포트로 매핑해주었습니다.
2번 DB는 MySQL을 위해 컨테이너의 3306번 포트를 서버의 13306번 포트로 매핑, MySQLD Exporter를 위해 컨테이너의 9104번 포트를 서버의 9105 포트로 매핑해주었습니다.
*MySQL 기본 포트 3306, MySQLD Exporter 기본 포트 9104
두 컨테이너 모두 동일하게 8.0.33 버전의 MySQL을 설치해주었습니다.
별도의 초기 구성을 진행하지 않았습니다.
출처: https://prometheus.io/docs/introduction/overview/#architecture
Prometheus는 오픈소스 시스템 모니터링 및 경고 툴킷입니다.
메트릭 수집, 시각화, 알림, 서비스 디스커버리 기능을 모두 가지고 있는 오픈소스 모니터링 툴으로 시계열 데이터를 수집하고 저장하는 데 사용됩니다. 값은 레이블이라는 Key-Value 쌍으로 타임스탬프와 함께 저장되어 시계열 데이터가 형상화됩니다.
수집하려는 대상 서버에 Exporter를 설치하여 Pull 방식으로 다른 곳의 데이터를 가져옵니다.
Data-Backend에서 어떤 메트릭이든지 수집할 수 있도록 구현되어 있어, 추후 새로운 Application에 대한 모니터링 수요가 발생하더라도 해당 앱에 대한 써드파티 Exporter만 설치해주면 모니터링 가능하다는 장점이 있습니다.
PromQL 쿼리 언어를 제공하여 HTTP API에서 쿼리에 맞게 시계열 데이터를 정제할 수 있다. PromQL로 대상 데이터를 조회하거나 Grafana와 연동하여 시각화해서 볼 수 있습니다.
하지만 데이터 백엔드와 저장소가 결합된 싱글 호스트 아키텍처로 HA 구성을 위한 개발은 써드 파티 앱을 통해 구성해야합니다. 또한 풀링 주기를 기반으로 메트릭을 수집하므로 풀링 순간의 스냅샷을 수집하기 때문에 수집 데이터는 근사치라는 단점이 있습니다.
Push vs. Pull
- Push
- 데이터를 가진 곳에서 필요한 곳으로 보냄
- Nagios, Zabbix 등
- 중앙 집중형으로 중앙 모니터링 시스템이 데이터 수집 항목, 수집 대상 서버를 모두 관리
- 수집 대상이 Auto-Scaling 등으로 가변적인 경우 유리
- 새로운 수집 대상 Host가 추가되어도 중앙에서는 전송된 데이터를 받기만 하면 됨
- 보안 측면에서 유리
- 중앙 폴러가 접근할 포트, IP 등에 대한 설정 및 수신 대기가 없음
- Pull
- 데이터가 필요한 곳에서 가진 곳에 접속하여 데이터를 긁어감
- Prometheus, Datadog, Collected 등
- 분산형으로 중앙시스템은 에이전트가 보내주는 데이터를 수동적으로 긁어가기만 하며, 어떤 데이터를 수집할 지 중앙에서 변경 가능
- 수집 대상의 유연성 측면에서 유리
- 중앙에서는 수동적으로 긁어가기만 하고 언제든지 새로운 데이터를 수용할 수 있도록 모든 메트릭을 요청할 수 있게 구현되어 있음
- HA 측면에서 유리
- 중앙에서 장애가 발생해도 수집 Host에 영향이 없음
Prometheus Install: https://prometheus.io/docs/introduction/first_steps/
Prometheus Download: https://prometheus.io/download/
# 현재 최신 버전 v2.44.0 (2023.05.17 기준) 다운로드
wget https://github.com/prometheus/prometheus/releases/download/v2.44.0/prometheus-2.44.0.linux-amd64.tar.gz
tar xvfz prometheus-*.tar.gz
cd prometheus-*
./prometheus --config.file=prometheus.yml
prometheus.service
서비스 파일 생성sudo vi /etc/systemd/system/prometheus.service
[Unit]
Description=Prometheus Server
Wants=network-online.target
After=network-online.target
[Service]
User=root
Group=root
Type=simple
ExecStart=/home/centos/prometheus-2.44.0.linux-amd64/prometheus --config.file=/home/centos/prometheus-2.44.0.linux-amd64/prometheus.yml
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable prometheus.service
sudo systemctl start prometheus.service
sudo systemctl restart prometheus.service
sudo systemctl status prometheus.service
systemd service 변경시 systemctl daemon-reload 명령어로 수정사항 반영 필요
config 파일을 수정했다면 systemctl restart prometheus.service 명령어로 재시작하기
모니터링 에이전트로 타겟 시스템에서 메트릭을 읽어서, Prometheus에서 Pull 방식으로 모니터링 대상 서버의 데이터를 가져갈 수 있도록 시계열 데이터를 제공하는 역할을 합니다.
HTTP GET
으로 메트릭을 텍스트 형태로 프로메테우스에 반환하며 히스토리 저장의 기능은 없습니다.
그 중 Node Exporter는 필요한 모니터링 정보 중에 node의 cpu, memory 등의 정보를 노출합니다.
Node Exporter Download: https://prometheus.io/download/#node_exporter
# 현재 최신 버전 v1.5.0 (2023.05.17 기준) 다운로드
wget https://github.com/prometheus/node_exporter/releases/download/v1.5.0/node_exporter-1.5.0.linux-amd64.tar.gz
# 압축 풀기
tar xzvf node_exporter-1.5.0.linux-amd64.tar.gz
cd node_exporter-1.5.0.linux-amd64
# Node Exporter 실행
./node_exporter
node_exporter.service
서비스 파일을 생성합니다.sudo vi /etc/systemd/system/node_exporter.service
[Unit]
Description=Node Exporter
Wants=network-online.target
After=network-online.target
[Service]
User=root
Group=root
Type=simple
ExecStart=/home/centos/node_exporter-1.5.0.linux-amd64/node_exporter
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable node_exporter.service
sudo systemctl start node_exporter.service
sudo systemctl restart node_exporter.service
sudo systemctl status node_exporter.service
Metrics
로 접속하면 Node Exporter가 수집하는 매트릭에 관한 정보를 확인할 수 있습니다.prometheus.yaml
파일 내용을 추가합니다.scrape_configs:
- job_name: "node-exporter"
static_configs:
- targets: ["133.186.144.9:9100"]
sudo systemctl restart prometheus.service
sudo systemctl status prometheus.service
MySQLD Exporter Download: https://prometheus.io/download/#mysqld_exporter
# 현재 최신 버전 v0.14.0 (2023.05.17 기준) 다운로드
wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.14.0/mysqld_exporter-0.14.0.linux-amd64.tar.gz
tar xzvf mysqld_exporter-0.14.0.linux-amd64.tar.gz
cd mysqld_exporter-0.14.0.linux-amd64
CREATE USER 'exporter'@'localhost' IDENTIFIED BY 'exporter_password' WITH MAX_USER_CONNECTIONS 2;
GRANT PROCESS, REPLICATION CLIENT, SELECT ON *.* TO 'exporter'@'localhost';
FLUSH PRIVILEGES;
EXIT;
vi mysqld_exporter.cnf
[client]
user=exporter
password=exporter_password
mysqld_exporter.service
서비스 파일을 생성합니다.sudo vi /etc/systemd/system/mysqld_exporter.service
[Unit]
Description=MySQL Exporter
Wants=network-online.target
After=network-online.target
[Service]
[Service]
User=root
Group=root
Type=simple
Restart=always
ExecStart=/home/centos/mysqld_exporter-0.14.0.linux-amd64/mysqld_exporter \
--config.my-cnf /home/centos/mysqld_exporter-0.14.0.linux-amd64/mysqld_exporter.cnf \
--collect.global_status \
--collect.info_schema.innodb_metrics \
--collect.auto_increment.columns \
--collect.info_schema.processlist \
--collect.binlog_size \
--collect.info_schema.tablestats \
--collect.global_variables \
--collect.info_schema.query_response_time \
--collect.info_schema.userstats \
--collect.info_schema.tables \
--collect.perf_schema.tablelocks \
--collect.perf_schema.file_events \
--collect.perf_schema.eventswaits \
--collect.perf_schema.indexiowaits \
--collect.perf_schema.tableiowaits \
--collect.slave_status \
--web.listen-address=0.0.0.0:9104
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl start mysqld_exporter
systemctl enable mysqld_exporter
systemctl restart mysqld_exporter
systemctl status mysqld_exporter
Metrics
로 접속하여 MySQLD Exporter가 수집하는 매트릭에 관한 정보를 확인할 수 있습니다.prometheus.yaml
파일에 내용을 추가합니다.scrape_configs:
- job_name: "mysqld-exporter"
static_configs:
- targets: ["133.186.144.9:9104", "133.186.144.9:9105"]
sudo systemctl restart prometheus.service
sudo systemctl status prometheus.service
프로메테우스가 메트릭의 정보를 가져오는 모니터링 툴이었다면, 그라파나는 가져온 메트릭 정보를 시각화 해주는 오픈소스 도구입니다.
Graphite, Prometheus, InfluxDB등 다양한 데이터베이스와 메트릭수집 시스템을 지원합니다. 하나의 대시보드에 여러 메트릭 시스템들의 지표를 표시할 수 있으며, notification 기능을 이용하여 슬랙, 이메일, 라인 등 웹훅을 연동할 수 있습니다.
Grafana Install: https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/
Grafana Download: https://grafana.com/grafana/download
# 현재 최신 버전 v9.5.2 (2023.05.17 기준) 다운로드
sudo yum install -y https://dl.grafana.com/enterprise/release/grafana-enterprise-9.5.2-1.x86_64.rpm
systemctl start grafana-server.service
systemctl enable grafana-server.service
systemctl stop grafana-server.service
systemctl restart grafana-server.service
netstat -ntap | grep LISTEN | grep 3000
<IP주소>:3000/login
에 접속하여 로그인 후 Web UI를 볼 수 있습니다.(sum(node_filesystem_size_bytes{job="node-exporter"} - node_filesystem_avail_bytes{job="node-exporter"}) / sum(node_filesystem_size_bytes{job="node-exporter"})) * 100
참고) MySQLD Exporter 지표: https://github.com/prometheus/mysqld_exporter
메트릭에 특정 조건을 설정하여 알람 제공해주는 도구입니다. Prometheus에서 발생한 알람을 Alert Manager에 전달하게 됩니다. Slack, Email, Webhook 등과 연동 가능합니다.
Alert Manager Download: https://prometheus.io/download/#alertmanager
# 현재 최신 버전 v0.25.0 (2023.05.17 기준) 다운로드
wget https://github.com/prometheus/alertmanager/releases/download/v0.25.0/alertmanager-0.25.0.linux-amd64.tar.gz
# 압축 풀기
tar xzvf alertmanager-0.25.0.linux-amd64.tar.gz
cd alertmanager-0.25.0.linux-amd64
alertmanager.service
서비스 파일을 생성합니다.sudo vi /etc/systemd/system/alertmanager.service
[Unit]
Description=Alert Manager
Wants=network-online.target
After=network-online.target
[Service]
User=root
Group=root
Type=simple
ExecStart=/home/centos/alertmanager-0.25.0.linux-amd64/alertmanager --config.file=/home/centos/alertmanager-0.25.0.linux-amd64/alertmanager.yml
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable alertmanager.service
sudo systemctl start alertmanager.service
sudo systemctl restart alertmanager.service
sudo systemctl status alertmanager.service
vi /home/centos/alertmanager-0.25.0.linux-amd64/alertmanager.yml
global:
resolve_timeout: 5m
route: # 라우트 대상 설정
group_by: ['alertname'] # prometheus.yml의 targets-labels > label_name
group_wait: 10s # 알림 발생 전 대기시간
group_interval: 5m # 알림 간 시간 간격 설정
repeat_interval: 10m # 알림 재발생
receiver: 'webhook' # 알림 설정 대상
receivers: # 알림 설정 대상
- name: 'webhook'
webhook_configs:
- url: '생성한 웹훅 URL' # 웹훅 URL
inhibit_rules:
- source_match: # inhibit rule을 적용하기 위해 존재해야 하는 조건
severity: 'critical'
target_match: # 음소거 대상
severity: 'warning'
vi rules/alert_rules.yaml
groups:
- name: AllInstances
rules:
- alert: InstanceDown
expr: up == 0
for: 1m
annotations:
title: 'Instance {{ $labels.instance }} down'
description: '{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 1 minute.'
labels:
severity: 'critical'
alert_rules.yml
InstanceDown
: 호스트 시스템의 인스턴스가 1분 이상 다운된 경우HostOutOfMemory
: 호스트 시스템의 메모리가 부족한 경우 (10% 이하가 남은 경우)HostHighCpuLoad
: 호스트 시스템의 CPU 부하가 발생한 경우 (80% 이상인 경우)HostSystemdServiceCrashed
: 호스트 시스템의 systemd 서비스가 충돌한 경우HostRequiresReboot
: 호스트 시스템 재부팅이 필요한 경우mysqld_alert_rules.yml
MysqlDown
: MySQL 인스턴스가 다운된 경우MysqlTooManyConnections
: MySQL connections이 너무 많은 경우 (max 값 기준 80% 이상)MysqlSlowQueries
: MySQL에 새로운 Slow Query가 발생한 경우MysqlInnodbLogWaits
: MySQL innodb 로그 쓰기 지연이 발생한 경우MysqlRestarted
: MySQL이 재시작된 경우 (uptime < 60)prometheus.yml
) 수정# Alertmanager configuration
alerting:
alertmanagers:
- static_configs:
- targets:
- localhost:9093
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
- "/home/centos/prometheus-2.44.0.linux-amd64/rules/alert_rules.yml"
- "/home/centos/prometheus-2.44.0.linux-amd64/rules/mysqld_alert_rules.yml"
sudo systemctl restart prometheus.service
sudo systemctl status prometheus.service
Grafana에서 MysqlDown과 MysqlRestarted에 대한 Alert Rule을 설정
Contact points에 Dooray! 웹훅을 등록
Notification policies에 설정한 Dooray Contact point 설정
MySQL 서버 중 하나를 재시작하여 테스트 진행
Alert 메세지가 정상적으로 수신되는 것을 확인할 수 있었습니다.
https://prometheus.io/docs/introduction/
https://prometheus.io/download/
https://github.com/prometheus/mysqld_exporter
https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/
https://grafana.com/grafana/download
https://grafana.com/grafana/dashboards/
https://github.com/prometheus/alertmanager
https://samber.github.io/awesome-prometheus-alerts/rules