Ver3.0 ๐ ์๋ฒ ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง์ ์๋ฒฝํ ์กฐํฉ! Prometheus์ Grafana ํ์ฉ ๊ฐ์ด๋

๐ ์๋ฒ ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง์ ์๋ฒฝํ ์กฐํฉ! Prometheus์ Grafana ํ์ฉ ๊ฐ์ด๋
์๋ ! ํน์ ์๋ฒ๊ฐ ๊ฐ์๊ธฐ ๋ค์ด๋๊ฑฐ๋ ๋๋ ค์ ธ์ ์์๋ ํ๋ฆฐ ๊ฒฝํ ์์ด? ๐ฐ ์๋๋ฉด "์ ์ด๋ ๊ฒ ๋๋ฆฌ์ง?"๋ผ๊ณ ๊ณ ๋ฏผํ๋ค๊ฐ ์์ธ์ ์ฐพ์ง ๋ชปํด ๋ฐค์ ์์ด ์ ์? ์๋ฒ ๊ด๋ฆฌ์๋ผ๋ฉด ๋๊ตฌ๋ ํ ๋ฒ์ฏค ๊ฒช๋ ์ ๋ชฝ ๊ฐ์ ์๊ฐ๋ค์ด์ง. ๊ทธ๋ฐ๋ฐ ๋ง์ด์ผ, ์ด๋ฐ ๋ฌธ์ ๋ค์ ๋ฏธ๋ฆฌ ์๋ฐฉํ๊ณ ์ค์๊ฐ์ผ๋ก ๋ชจ๋ํฐ๋งํ ์ ์๋ค๋ฉด ์ด๋จ๊น? ์ค๋์ ๊ทธ ํด๋ต์ธ Prometheus์ Grafana์ ๋ํด ์น๊ตฌ์ฒ๋ผ ํธํ๊ฒ ์ด์ผ๊ธฐํด๋ณผ๊ฒ!
๐ฏ ์ ๋ชจ๋ํฐ๋ง์ด ํ์ํ ๊น?
์๋ฒ๋ฅผ ์ด์ํ๋ค๋ ๊ฑด ๋ง์น ๋นํ๊ธฐ๋ฅผ ์กฐ์ข ํ๋ ๊ฒ๊ณผ ๋น์ทํด. ๊ณ๊ธฐํ ์์ด ๋นํ๊ธฐ๋ฅผ ์กฐ์ข ํ๋ค๊ณ ์์ํด๋ด. ๊ณ ๋๋ ๋ชจ๋ฅด๊ณ , ์๋๋ ๋ชจ๋ฅด๊ณ , ์ฐ๋ฃ๊ฐ ์ผ๋ง๋ ๋จ์๋์ง๋ ๋ชจ๋ฅด๋ ์ํ๋ก ๋ ์๊ฐ๋ค๋ฉด? ์๊ฐ๋ง ํด๋ ์์ฐํ์ง? ๐ฑ
์๋ฒ๋ ๋ง์ฐฌ๊ฐ์ง์ผ. CPU ์ฌ์ฉ๋ฅ , ๋ฉ๋ชจ๋ฆฌ ์ํ, ๋์คํฌ ์ฉ๋, ๋คํธ์ํฌ ํธ๋ํฝ... ์ด๋ฐ ์ ๋ณด๋ค์ ์ค์๊ฐ์ผ๋ก ๋ชจ๋ํฐ๋งํ์ง ์์ผ๋ฉด ์ธ์ ๋ฌธ์ ๊ฐ ํฐ์ง์ง ์ ์ ์์ด. ๊ทธ๋์ ์ฐ๋ฆฌ์๊ฒ๋ Prometheus์ Grafana๋ผ๋ ๊ฐ๋ ฅํ ๋๊ตฌ๊ฐ ํ์ํ ๊ฑฐ์ง!
1. ๋ฌธ์ ์๋ฐฉ: ์ฅ์ ๊ฐ ๋ฐ์ํ๊ธฐ ์ ์ ๋ฏธ๋ฆฌ ๊ฐ์ง
2. ๋น ๋ฅธ ๋์: ๋ฌธ์ ๋ฐ์ ์ ์ฆ๊ฐ์ ์ธ ์์ธ ํ์
3. ์ฑ๋ฅ ์ต์ ํ: ๋ณ๋ชฉ ์ง์ ์ ์ฐพ์ ๊ฐ์
4. ์ฉ๋ ๊ณํ: ๋ฆฌ์์ค ์ฆ์ค ์์ ์ ์ ํํ ์์ธก
5. ๋น์ฉ ์ ๊ฐ: ๋ถํ์ํ ๋ฆฌ์์ค ๋ญ๋น ๋ฐฉ์ง
๐ Prometheus๋ ๋ฌด์์ธ๊ฐ?
Prometheus(ํ๋ก๋ฉํ ์ฐ์ค)๋ 2012๋ SoundCloud์์ ๊ฐ๋ฐํ ์คํ์์ค ๋ชจ๋ํฐ๋ง ์์คํ ์ด์ผ. ๊ทธ๋ฆฌ์ค ์ ํ์ ๋์ค๋ ํ๋ก๋ฉํ ์ฐ์ค์ฒ๋ผ ์ธ๋ฅ(๊ฐ๋ฐ์๋ค)์๊ฒ ๋ถ(๋ชจ๋ํฐ๋ง ๋ฅ๋ ฅ)์ ๊ฐ์ ธ๋ค์ค ์กด์ฌ๋ผ๊ณ ํ ์ ์์ง! ๐ฅ
Prometheus์ ๊ฐ์ฅ ํฐ ํน์ง์ ์๊ณ์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค(Time Series Database)๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ค๋ ๊ฑฐ์ผ. ์ฝ๊ฒ ๋งํ๋ฉด, ์๊ฐ์ ํ๋ฆ์ ๋ฐ๋ผ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ๋ถ์ํ๋ ๋ฐ ํนํ๋์ด ์๋ค๋ ๋ป์ด์ง. CPU ์ฌ์ฉ๋ฅ ์ด ์ค์ 10์์ 50%์๋ค๊ฐ ์คํ 2์์ 80%๋ก ์ฌ๋ผ๊ฐ๋ค๋ ์์ ์ ๋ณด๋ฅผ ์์ฃผ ํจ์จ์ ์ผ๋ก ์ ์ฅํ๊ณ ์กฐํํ ์ ์์ด.
๐จ Prometheus์ ํต์ฌ ํน์ง
Prometheus๊ฐ ์ง์ ํ๊ฒ ์๋ฒ์ ์ ์ํด์ ๋ฉํธ๋ฆญ์ ๊ฐ์ ธ์. ์ด๊ฒ Push ๋ฐฉ์๋ณด๋ค ์์ ์ ์ด๊ณ ๊ด๋ฆฌํ๊ธฐ ์ฌ์!
๋ ์ด๋ธ(Label)์ ์ฌ์ฉํด์ ๊ฐ์ ๋ฉํธ๋ฆญ๋ ๋ค์ํ ๊ด์ ์์ ๋ถ๋ฅํ ์ ์์ด. ์๋ฅผ ๋ค์ด HTTP ์์ฒญ์ URL๋ณ, ์ํ์ฝ๋๋ณ๋ก ๊ตฌ๋ถ ๊ฐ๋ฅ!
PromQL์ด๋ผ๋ ์์ฒด ์ฟผ๋ฆฌ ์ธ์ด๋ก ๋ณต์กํ ๋ฐ์ดํฐ ๋ถ์๋ ๊ฐ๋จํ๊ฒ! SQL์ฒ๋ผ ๋ฐฐ์ฐ๋ฉด ์ ๋ง ๊ฐ๋ ฅํ ๋ฌด๊ธฐ๊ฐ ๋ผ.
๐๏ธ Prometheus ์ํคํ ์ฒ ์ดํดํ๊ธฐ
Prometheus์ ๊ตฌ์กฐ๋ฅผ ์ดํดํ๋ฉด ํ์ฉ๋๊ฐ ํจ์ฌ ๋์์ ธ. ์ฃผ์ ๊ตฌ์ฑ ์์๋ค์ ์ดํด๋ณผ๊น?
| ๊ตฌ์ฑ ์์ | ์ญํ | ์ค๋ช |
|---|---|---|
| Prometheus Server | ํต์ฌ ์์ง | ๋ฉํธ๋ฆญ ์์ง, ์ ์ฅ, ์ฟผ๋ฆฌ ์ฒ๋ฆฌ๋ฅผ ๋ด๋นํ๋ ๋ฉ์ธ ์๋ฒ |
| Exporter | ๋ฐ์ดํฐ ์ ๊ณต์ | ๋ค์ํ ์์คํ ์ ๋ฉํธ๋ฆญ์ Prometheus ํ์์ผ๋ก ๋ณํ |
| Pushgateway | ์์ ์์ ์ง์ | ์งง์ ์๊ฐ ๋์ ์คํ๋๋ ๋ฐฐ์น ์์ ์ ๋ฉํธ๋ฆญ ์์ง |
| Alertmanager | ์๋ฆผ ๊ด๋ฆฌ | ์๊ณ๊ฐ ์ด๊ณผ ์ ์ด๋ฉ์ผ, ์ฌ๋ ๋ฑ์ผ๋ก ์๋ฆผ ๋ฐ์ก |
| Service Discovery | ์๋ ํ์ง | Kubernetes, Consul ๋ฑ๊ณผ ์ฐ๋ํ์ฌ ๋ชจ๋ํฐ๋ง ๋์ ์๋ ๋ฐ๊ฒฌ |
๐ Grafana, ๋ฐ์ดํฐ๋ฅผ ์์ ๋ก ๋ง๋ค๋ค
Prometheus๊ฐ ๋ฐ์ดํฐ๋ฅผ ์์งํ๊ณ ์ ์ฅํ๋ ์ญํ ์ด๋ผ๋ฉด, Grafana๋ ๊ทธ ๋ฐ์ดํฐ๋ฅผ ์๋ฆ๋ต๊ณ ์ง๊ด์ ์ธ ์๊ฐํ๋ก ๋ณด์ฌ์ฃผ๋ ์ญํ ์ ํด. ๋ง์น ํ๋ฅญํ ์๋ฆฌ์ฌ๊ฐ ์ ์ ํ ์ฌ๋ฃ(Prometheus ๋ฐ์ดํฐ)๋ฅผ ๋ฉ์ง ์๋ฆฌ(๋์๋ณด๋)๋ก ๋ง๋ค์ด๋ด๋ ๊ฒ์ฒ๋ผ ๋ง์ด์ผ! ๐จโ๐ณ
Grafana๋ 2014๋ ์ ์์๋ ์คํ์์ค ํ๋ก์ ํธ๋ก, ํ์ฌ๋ ์ ์ธ๊ณ ์๋ง์ ๊ธฐ์ ๊ณผ ๊ฐ๋ฐ์๋ค์ด ์ฌ์ฉํ๋ ํ์ค ์๊ฐํ ๋๊ตฌ๊ฐ ๋์์ด. Netflix, Uber, Bloomberg ๊ฐ์ ๊ธ๋ก๋ฒ ๊ธฐ์ ๋ค๋ Grafana๋ฅผ ์ฌ์ฉํ๊ณ ์๋ค๋, ๊ทธ ์ ๋ขฐ๋๋ฅผ ์ ์ ์์ง?
โจ Grafana์ ๋งค๋ ฅ ํฌ์ธํธ
1. ๐จ ๋ค์ํ ์๊ฐํ ์ต์
๊ทธ๋ํ, ๊ฒ์ด์ง, ํํธ๋งต, ํ ์ด๋ธ... ์์ํ ์ ์๋ ๊ฑฐ์ ๋ชจ๋ ํํ์ ์ฐจํธ๋ฅผ ์ง์ํด. ๋ฐ์ดํฐ์ ํน์ฑ์ ๋ง๋ ์ต์ ์ ์๊ฐํ๋ฅผ ์ ํํ ์ ์์ด์ ์ ๋ง ํธ๋ฆฌํด!
2. ๐ ๋ค์ค ๋ฐ์ดํฐ ์์ค ์ง์
Prometheus๋ฟ๋ง ์๋๋ผ InfluxDB, Elasticsearch, MySQL, PostgreSQL ๋ฑ 70๊ฐ ์ด์์ ๋ฐ์ดํฐ ์์ค๋ฅผ ์ง์ํด. ํ๋์ ๋์๋ณด๋์์ ์ฌ๋ฌ ์์ค์ ๋ฐ์ดํฐ๋ฅผ ํตํฉํด์ ๋ณผ ์ ์๋ค๋ ๊ฒ ์ ๋ง ํฐ ์ฅ์ ์ด์ง!
3. ๐จ ์๋ฆผ ๊ธฐ๋ฅ
ํน์ ์กฐ๊ฑด์ด ๋ง์กฑ๋๋ฉด ์๋์ผ๋ก ์๋ฆผ์ ๋ณด๋ผ ์ ์์ด. ์๋ฅผ ๋ค์ด CPU ์ฌ์ฉ๋ฅ ์ด 90%๋ฅผ ๋์ผ๋ฉด ์ฌ๋์ผ๋ก ๋ฉ์์ง๋ฅผ ๋ณด๋ด๋ ์์ผ๋ก ์ค์ ๊ฐ๋ฅํด!
4. ๐ฑ ๋ฐ์ํ ๋์์ธ
๋ชจ๋ฐ์ผ์์๋ ๊น๋ํ๊ฒ ๋ณด์ฌ์ ์ธ์ ์ด๋์๋ ์๋ฒ ์ํ๋ฅผ ํ์ธํ ์ ์์ด. ์ถ๊ทผ๊ธธ ์งํ์ฒ ์์๋ ์๋ฒ ๋ชจ๋ํฐ๋ง์ด ๊ฐ๋ฅํ๋ค๋, ํธ๋ฆฌํ์ง ์์? (๋ฌผ๋ก ๋๋ฌด ์์ฃผ ๋ณด๋ฉด ์คํธ๋ ์ค๋ฐ์ ์๋... ๐ )
๐ ๏ธ Prometheus ์ค์นํ๊ณ ์ค์ ํ๊ธฐ
์, ์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก ์ค์ ์ ๋ค์ด๊ฐ๋ณผ๊น? Prometheus๋ฅผ ์ค์นํ๋ ๋ฐฉ๋ฒ์ ์ฌ๋ฌ ๊ฐ์ง๊ฐ ์์ง๋ง, ๊ฐ์ฅ ์ผ๋ฐ์ ์ธ ๋ฐฉ๋ฒ๋ค์ ์๊ฐํ ๊ฒ. ๊ฑฑ์ ํ์ง ๋ง! ์๊ฐ๋ณด๋ค ์ด๋ ต์ง ์์. ๐
๐ฆ ์ค์น ๋ฐฉ๋ฒ 1: ๋ฐ์ด๋๋ฆฌ ์ง์ ๋ค์ด๋ก๋
๊ฐ์ฅ ๊ฐ๋จํ ๋ฐฉ๋ฒ์ด์ผ. Prometheus ๊ณต์ ์น์ฌ์ดํธ์์ ์ด์์ฒด์ ์ ๋ง๋ ๋ฐ์ด๋๋ฆฌ๋ฅผ ๋ค์ด๋ก๋ํ๋ฉด ๋ผ.
# Linux ํ๊ฒฝ์์ ๋ค์ด๋ก๋ ๋ฐ ์ค์น
wget https://github.com/prometheus/prometheus/releases/download/v2.45.0/prometheus-2.45.0.linux-amd64.tar.gz
tar xvfz prometheus-2.45.0.linux-amd64.tar.gz
cd prometheus-2.45.0.linux-amd64
# Prometheus ์คํ
./prometheus --config.file=prometheus.yml
๐ณ ์ค์น ๋ฐฉ๋ฒ 2: Docker ์ฌ์ฉ
Docker๋ฅผ ์ฌ์ฉํ๋ฉด ํ๊ฒฝ ์ค์ ๊ฑฑ์ ์์ด ๊น๋ํ๊ฒ ์ค์นํ ์ ์์ด. ์์ฆ ๋์ธ์ง!
# Docker๋ก Prometheus ์คํ
docker run -d \
--name prometheus \
-p 9090:9090 \
-v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml \
prom/prometheus
# ์คํ ํ์ธ
docker ps | grep prometheus
โ๏ธ ๊ธฐ๋ณธ ์ค์ ํ์ผ ์ดํดํ๊ธฐ
Prometheus์ ํต์ฌ์ prometheus.yml ์ค์ ํ์ผ์ด์ผ. ์ด ํ์ผ์์ ๋ชจ๋ํฐ๋งํ ๋์๊ณผ ์์ง ์ฃผ๊ธฐ ๋ฑ์ ์ ์ํด. ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ฅผ ์ดํด๋ณด์:
# prometheus.yml ๊ธฐ๋ณธ ๊ตฌ์กฐ
global:
scrape_interval: 15s # ๋ฉํธ๋ฆญ ์์ง ์ฃผ๊ธฐ (๊ธฐ๋ณธ 15์ด)
evaluation_interval: 15s # ๊ท์น ํ๊ฐ ์ฃผ๊ธฐ
external_labels:
cluster: 'my-cluster'
region: 'ap-northeast-2'
# ์๋ฆผ ๊ท์น ํ์ผ ๊ฒฝ๋ก
rule_files:
- "alerts.yml"
# ๋ชจ๋ํฐ๋ง ๋์ ์ค์
scrape_configs:
# Prometheus ์์ฒด ๋ชจ๋ํฐ๋ง
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
# Node Exporter (์๋ฒ ๋ฉํธ๋ฆญ)
- job_name: 'node'
static_configs:
- targets: ['localhost:9100']
labels:
env: 'production'
team: 'backend'
โข scrape_interval: ๋๋ฌด ์งง์ผ๋ฉด ๋ถํ๊ฐ ํฌ๊ณ , ๋๋ฌด ๊ธธ๋ฉด ์ค์๊ฐ์ฑ์ด ๋จ์ด์ ธ. ๋ณดํต 15~60์ด๊ฐ ์ ๋นํด.
โข job_name: ๋ ผ๋ฆฌ์ ์ธ ๊ทธ๋ฃน ์ด๋ฆ. ๋์ค์ ์ฟผ๋ฆฌํ ๋ ์ด ์ด๋ฆ์ผ๋ก ํํฐ๋งํ ์ ์์ด.
โข targets: ์ค์ ๋ชจ๋ํฐ๋งํ ์๋ํฌ์ธํธ. IP:Port ํ์์ผ๋ก ์ง์ .
โข labels: ๋ฉํธ๋ฆญ์ ์ถ๊ฐ ์ ๋ณด๋ฅผ ๋ถ์ฌ. ํ๊ฒฝ(dev/prod), ํ, ๋ฆฌ์ ๋ฑ์ ๊ตฌ๋ถํ ๋ ์ ์ฉํด!
๐ฏ Node Exporter ์ค์นํ๊ธฐ
์๋ฒ์ CPU, ๋ฉ๋ชจ๋ฆฌ, ๋์คํฌ ๋ฑ ์์คํ ๋ฉํธ๋ฆญ์ ์์งํ๋ ค๋ฉด Node Exporter๊ฐ ํ์ํด. ์ด๊ฑด Prometheus๊ฐ ์ดํดํ ์ ์๋ ํ์์ผ๋ก ์์คํ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ ์์ด์ ํธ์ผ.
# Node Exporter ๋ค์ด๋ก๋ ๋ฐ ์ค์น
wget https://github.com/prometheus/node_exporter/releases/download/v1.6.0/node_exporter-1.6.0.linux-amd64.tar.gz
tar xvfz node_exporter-1.6.0.linux-amd64.tar.gz
cd node_exporter-1.6.0.linux-amd64
# ๋ฐฑ๊ทธ๋ผ์ด๋๋ก ์คํ
nohup ./node_exporter &
# ๋ฉํธ๋ฆญ ํ์ธ (๋ธ๋ผ์ฐ์ ๋ curl๋ก)
curl http://localhost:9100/metrics
Node Exporter๋ฅผ ์คํํ๋ฉด 9100 ํฌํธ์์ ๋ฉํธ๋ฆญ์ ์ ๊ณตํด. ๋ธ๋ผ์ฐ์ ๋ก ์ ์ํด๋ณด๋ฉด ์์ฒญ๋๊ฒ ๋ง์ ๋ฉํธ๋ฆญ๋ค์ด ํ ์คํธ ํ์์ผ๋ก ์ญ ๋์ด๋๋ ๊ฑธ ๋ณผ ์ ์์ด. ์ฒ์ ๋ณด๋ฉด ์ข ๋นํฉ์ค๋ฌ์ธ ์ ์๋๋ฐ, ๊ฑฑ์ ๋ง! Prometheus๊ฐ ์์์ ์ ํ์ฑํด์ค ๊ฑฐ์ผ. ๐
๐จ Grafana ์ค์น์ Prometheus ์ฐ๋ํ๊ธฐ
์ด์ Prometheus๋ก ๋ฐ์ดํฐ๋ฅผ ์์งํ๊ณ ์์ผ๋, Grafana๋ก ๋ฉ์ง ๋์๋ณด๋๋ฅผ ๋ง๋ค์ด๋ณผ ์ฐจ๋ก์ผ! Grafana ์ค์น๋ ์ฌ๋ฌ ๋ฐฉ๋ฒ์ด ์์ง๋ง, ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๋ค์ ์์๋ณด์.
๐ฅ Grafana ์ค์นํ๊ธฐ
๋ฐฉ๋ฒ 1: APT ํจํค์ง ๋งค๋์ ์ฌ์ฉ (Ubuntu/Debian)
# Grafana GPG ํค ์ถ๊ฐ
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
# Grafana ์ ์ฅ์ ์ถ๊ฐ
echo "deb https://packages.grafana.com/oss/deb stable main" | sudo tee /etc/apt/sources.list.d/grafana.list
# ์ค์น
sudo apt-get update
sudo apt-get install grafana
# ์๋น์ค ์์ ๋ฐ ์๋ ์์ ์ค์
sudo systemctl start grafana-server
sudo systemctl enable grafana-server
# ์ํ ํ์ธ
sudo systemctl status grafana-server
๋ฐฉ๋ฒ 2: Docker ์ฌ์ฉ
# Docker๋ก Grafana ์คํ
docker run -d \
--name=grafana \
-p 3000:3000 \
-v grafana-storage:/var/lib/grafana \
grafana/grafana-oss
# ์คํ ํ์ธ
docker logs grafana
์ค์น๊ฐ ์๋ฃ๋๋ฉด ๋ธ๋ผ์ฐ์ ์์ http://localhost:3000์ผ๋ก ์ ์ํด๋ด. Grafana ๋ก๊ทธ์ธ ํ๋ฉด์ด ๋ํ๋ ๊ฑฐ์ผ! ๐
Username: admin
Password: admin
์ฒซ ๋ก๊ทธ์ธ ํ์๋ ๋ฐ๋์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณ๊ฒฝํ๋ผ๊ณ ๋์ฌ ๊ฑฐ์ผ. ๋ณด์์ ์ํด ๊ผญ ๋ณ๊ฒฝํ์!
๐ Prometheus ๋ฐ์ดํฐ ์์ค ์ฐ๊ฒฐํ๊ธฐ
Grafana์ ๋ก๊ทธ์ธํ๋ค๋ฉด, ์ด์ Prometheus๋ฅผ ๋ฐ์ดํฐ ์์ค๋ก ์ถ๊ฐํด์ผ ํด. ๋จ๊ณ๋ณ๋ก ๋ฐ๋ผํด๋ณด์:
Step 1: ์ผ์ชฝ ๋ฉ๋ด์์ โ๏ธ Configuration โ Data Sources ํด๋ฆญ
Step 2: "Add data source" ๋ฒํผ ํด๋ฆญ
Step 3: Prometheus ์ ํ
Step 4: ๋ค์ ์ ๋ณด ์ ๋ ฅ:
Name: Prometheus
URL: http://localhost:9090
Access: Server (default)
# ๊ณ ๊ธ ์ค์ (์ ํ์ฌํญ)
Scrape interval: 15s
Query timeout: 60s
Step 5: ํ๋จ์ "Save & Test" ๋ฒํผ ํด๋ฆญ
"Data source is working" ๋ฉ์์ง๊ฐ ๋์ค๋ฉด ์ฑ๊ณต! ๐ ์ด์ Grafana์์ Prometheus์ ๋ชจ๋ ๋ฉํธ๋ฆญ์ ์ฌ์ฉํ ์ ์์ด.
1. Prometheus๊ฐ ์ ์์ ์ผ๋ก ์คํ ์ค์ธ์ง ํ์ธ (
http://localhost:9090 ์ ์ ํ
์คํธ)2. ๋ฐฉํ๋ฒฝ์์ 9090 ํฌํธ๊ฐ ์ด๋ ค์๋์ง ํ์ธ
3. Docker๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ๋คํธ์ํฌ ์ค์ ํ์ธ (๊ฐ์ ๋คํธ์ํฌ์ ์์ด์ผ ํจ)
4. URL์ http:// ํ๋กํ ์ฝ์ ์ ํํ ์ ๋ ฅํ๋์ง ํ์ธ
๐ ์ฒซ ๋ฒ์งธ ๋์๋ณด๋ ๋ง๋ค๊ธฐ
์, ์ด์ ์ง์ง ์ฌ๋ฏธ์๋ ๋ถ๋ถ์ด์ผ! ๋์๋ณด๋๋ฅผ ๋ง๋ค์ด๋ณด์. ์ฒ์๋ถํฐ ๋ณต์กํ ๊ฑธ ๋ง๋ค ํ์๋ ์์ด. ๊ฐ๋จํ CPU ์ฌ์ฉ๋ฅ ๊ทธ๋ํ๋ถํฐ ์์ํด๋ณด์.
1. ์ ๋์๋ณด๋ ์์ฑ
์ผ์ชฝ ๋ฉ๋ด์์ + ์์ด์ฝ โ Dashboard โ Add new panel ํด๋ฆญ
2. ์ฟผ๋ฆฌ ์์ฑ
Query ํญ์์ ๋ค์ PromQL ์ฟผ๋ฆฌ ์ ๋ ฅ:
# CPU ์ฌ์ฉ๋ฅ (%)
100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
3. ์๊ฐํ ์ค์
์ค๋ฅธ์ชฝ ํจ๋์์ ๋ค์ ์ค์ :
Unit: Percent (0-100)
Min: 0
Max: 100
Line width: 2
Fill opacity: 10
Gradient mode: Opacity
4. ์ ์ฅ
์ค๋ฅธ์ชฝ ์๋จ์ Apply ๋ฒํผ ํด๋ฆญ ํ, ๐พ Save dashboard ํด๋ฆญ
์ง์! ๐ ์ฒซ ๋ฒ์งธ ๊ทธ๋ํ๊ฐ ์์ฑ๋์ด! ์ค์๊ฐ์ผ๋ก CPU ์ฌ์ฉ๋ฅ ์ด ๋ณํ๋ ๊ฑธ ๋ณผ ์ ์์ ๊ฑฐ์ผ. ์ ๊ธฐํ์ง?
๐ฅ PromQL ๋ง์คํฐํ๊ธฐ
PromQL(Prometheus Query Language)์ Prometheus์ ํต์ฌ์ด์ผ. SQL์ ์๋ฉด ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ์์ ์์ฌ๋ก ๋ค๋ฃฐ ์ ์๋ฏ์ด, PromQL์ ์๋ฉด ๋ชจ๋ํฐ๋ง ๋ฐ์ดํฐ๋ฅผ ๋ง์๋๋ก ๋ถ์ํ ์ ์์ด! ์ฒ์์ ์ข ๋ฏ์ค ์ ์์ง๋ง, ๊ธฐ๋ณธ ๊ฐ๋ ๋ง ์ดํดํ๋ฉด ๊ธ๋ฐฉ ์ต์ํด์ง ๊ฑฐ์ผ. ๐ช
๐ PromQL ๊ธฐ๋ณธ ๊ฐ๋
1. ๋ฉํธ๋ฆญ ์ ํ
๊ฐ์ฅ ๊ธฐ๋ณธ์ ๋ฉํธ๋ฆญ ์ด๋ฆ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๊ฑฐ์ผ:
# ๋จ์ ๋ฉํธ๋ฆญ ์กฐํ
node_cpu_seconds_total
# ๋ ์ด๋ธ๋ก ํํฐ๋ง
node_cpu_seconds_total{mode="idle"}
# ์ฌ๋ฌ ์กฐ๊ฑด ์กฐํฉ
node_cpu_seconds_total{mode="idle", cpu="0"}
2. ์๊ฐ ๋ฒ์ ์ ํ
ํน์ ์๊ฐ ๋ฒ์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์์ด:
# ์ต๊ทผ 5๋ถ๊ฐ์ ๋ฐ์ดํฐ
node_cpu_seconds_total[5m]
# ์ต๊ทผ 1์๊ฐ
node_cpu_seconds_total[1h]
# ์ต๊ทผ 1์ผ
node_cpu_seconds_total[1d]
3. ์ง๊ณ ํจ์
์ฌ๋ฌ ์๊ณ์ด์ ํ๋๋ก ํฉ์น๊ฑฐ๋ ๊ณ์ฐํ ์ ์์ด:
# ํ๊ท
avg(node_cpu_seconds_total)
# ํฉ๊ณ
sum(node_cpu_seconds_total)
# ์ต๋๊ฐ
max(node_cpu_seconds_total)
# ์ต์๊ฐ
min(node_cpu_seconds_total)
# ๊ฐ์
count(node_cpu_seconds_total)
๐ฏ ์ค์ PromQL ์ฟผ๋ฆฌ ์์
์ด๋ก ์ ์ด ์ ๋๋ฉด ์ถฉ๋ถํด. ์ด์ ์ค์ ๋ก ์ ์ฉํ ์ฟผ๋ฆฌ๋ค์ ์ดํด๋ณด์! ์ด ์ฟผ๋ฆฌ๋ค์ ๋ฐ๋ก ๋ณต์ฌํด์ ์ฌ์ฉํ ์ ์์ด. ๐
๐ป CPU ๊ด๋ จ ์ฟผ๋ฆฌ
# CPU ์ฌ์ฉ๋ฅ (์ ์ฒด ํ๊ท )
100 - (avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# CPU ์ฝ์ด๋ณ ์ฌ์ฉ๋ฅ
100 - (avg by(cpu) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# CPU ๋ถํ (Load Average)
node_load1 # 1๋ถ ํ๊ท
node_load5 # 5๋ถ ํ๊ท
node_load15 # 15๋ถ ํ๊ท
# CPU ์ฌ์ฉ๋ฅ ์ด 80% ์ด์์ธ ์๋ฒ
avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100 < 20
๐ง ๋ฉ๋ชจ๋ฆฌ ๊ด๋ จ ์ฟผ๋ฆฌ
# ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ (%)
(1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100
# ์ฌ์ฉ ๊ฐ๋ฅํ ๋ฉ๋ชจ๋ฆฌ (GB)
node_memory_MemAvailable_bytes / 1024 / 1024 / 1024
# ์ค์ ์ฌ์ฉ๋ฅ
(node_memory_SwapTotal_bytes - node_memory_SwapFree_bytes) / node_memory_SwapTotal_bytes * 100
# ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ (GB)
(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / 1024 / 1024 / 1024
๐พ ๋์คํฌ ๊ด๋ จ ์ฟผ๋ฆฌ
# ๋์คํฌ ์ฌ์ฉ๋ฅ (%)
(1 - (node_filesystem_avail_bytes / node_filesystem_size_bytes)) * 100
# ๋์คํฌ ์ฌ์ ๊ณต๊ฐ (GB)
node_filesystem_avail_bytes{mountpoint="/"} / 1024 / 1024 / 1024
# ๋์คํฌ I/O ์ฝ๊ธฐ ์๋ (MB/s)
rate(node_disk_read_bytes_total[5m]) / 1024 / 1024
# ๋์คํฌ I/O ์ฐ๊ธฐ ์๋ (MB/s)
rate(node_disk_written_bytes_total[5m]) / 1024 / 1024
# ๋์คํฌ ์ฌ์ฉ๋ฅ ์ด 90% ์ด์์ธ ํํฐ์
(1 - (node_filesystem_avail_bytes / node_filesystem_size_bytes)) * 100 > 90
๐ ๋คํธ์ํฌ ๊ด๋ จ ์ฟผ๋ฆฌ
# ๋คํธ์ํฌ ์์ ์๋ (MB/s)
rate(node_network_receive_bytes_total[5m]) / 1024 / 1024
# ๋คํธ์ํฌ ์ก์ ์๋ (MB/s)
rate(node_network_transmit_bytes_total[5m]) / 1024 / 1024
# ์ด ๋คํธ์ํฌ ํธ๋ํฝ (์์ + ์ก์ )
(rate(node_network_receive_bytes_total[5m]) + rate(node_network_transmit_bytes_total[5m])) / 1024 / 1024
# ๋คํธ์ํฌ ์๋ฌ ๋ฐ์๋ฅ
rate(node_network_receive_errs_total[5m]) + rate(node_network_transmit_errs_total[5m])
1. Prometheus UI์ Graph ํญ์์ ์ง์ ์ฟผ๋ฆฌ๋ฅผ ํ ์คํธํด๋ด. ์ฆ์ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ ์ ์์ด์ ํ์ตํ๊ธฐ ์ข์!
2.
rate()์ irate()์ ์ฐจ์ด๋ฅผ ์ดํดํ์. rate๋ ํ๊ท , irate๋ ์๊ฐ ๋ณํ์จ์ด์ผ.3. ๋ณต์กํ ์ฟผ๋ฆฌ๋ ๋จ๊ณ๋ณ๋ก ๋๋ ์ ์์ฑํด๋ด. ํ ๋ฒ์ ์์ฑํ๋ ค๊ณ ํ์ง ๋ง๊ณ !
4. ๊ณต์ ๋ฌธ์์ ์์ ๋ค์ ์ง์ ์คํํด๋ณด๋ฉด์ ์ตํ๋ ๊ฒ ๊ฐ์ฅ ๋นจ๋ผ.
๐จ ํ๋กํ์ ๋ ๋์๋ณด๋ ๋์์ธํ๊ธฐ
์ด์ PromQL๋ ์ด๋ ์ ๋ ์ตํ์ผ๋, ์ ๋ง ๋ฉ์ง ๋์๋ณด๋๋ฅผ ๋ง๋ค์ด๋ณผ ์๊ฐ์ด์ผ! ๋จ์ํ ๊ทธ๋ํ๋ง ๋์ดํ๋ ๊ฒ ์๋๋ผ, ํ๋์ ์์คํ ์ํ๋ฅผ ํ์ ํ ์ ์๋ ์ง๊ด์ ์ด๊ณ ์๋ฆ๋ค์ด ๋์๋ณด๋๋ฅผ ๋์์ธํด๋ณด์. ๐จ
๐ ๋์๋ณด๋ ๋ ์ด์์ ์ ๋ต
์ข์ ๋์๋ณด๋๋ ์ ๋ณด์ ์ฐ์ ์์๊ฐ ๋ช ํํด. ๋ค์ ์์น์ ๋ฐ๋ผ๋ณด์:
๊ฐ์ฅ ์ค์ํ ๋ฉํธ๋ฆญ์ ํฐ ์ซ์๋ก ํ์. CPU, ๋ฉ๋ชจ๋ฆฌ, ๋์คํฌ ์ฌ์ฉ๋ฅ ๊ฐ์ ๊ฒ๋ค!
์๊ฐ์ ๋ฐ๋ฅธ ๋ณํ๋ฅผ ๋ณด์ฌ์ฃผ๋ ๊ทธ๋ํ๋ค. ํธ๋ ๋ ํ์ ์ ํ์!
ํ ์ด๋ธ์ด๋ ๋ก๊ทธ ๊ฐ์ ์์ธํ ์ ๋ณด. ๋ฌธ์ ๋ฐ์ ์ ๋๋ฆด๋ค์ด์ฉ!
๐ฏ ํจ๋ ํ์ ๋ณ ํ์ฉ๋ฒ
1. Stat ํจ๋ - ํต์ฌ ์งํ ํ์
ํฐ ์ซ์๋ก ํ์ฌ ์ํ๋ฅผ ํ๋์ ๋ณด์ฌ์ค. ์์ ์๊ณ๊ฐ์ ์ค์ ํ๋ฉด ์ํ ์ํฉ์ ์ฆ์ ์ ์ ์์ด!
โข Visualization: Stat
โข Value: Last (์ต์ ๊ฐ)
โข Unit: Percent (0-100)
โข Thresholds: 0 (green), 70 (yellow), 90 (red)
โข Color mode: Background
2. Gauge ํจ๋ - ์งํ๋ฅ ํ์
๊ฒ์ด์ง ํํ๋ก ํ์ฌ ์์น๋ฅผ ์ง๊ด์ ์ผ๋ก ํํ. ๋์คํฌ ์ฌ์ฉ๋ฅ ๊ฐ์ ๊ฑธ ํ์ํ๊ธฐ ์ข์!
3. Time Series - ์๊ฐ๋ณ ์ถ์ด
๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํ๋ ๊ทธ๋ํ ํ์ . ์๊ฐ์ ๋ฐ๋ฅธ ๋ณํ๋ฅผ ์ ๋ช ํ๊ฒ ๋ณด์ฌ์ค.
4. Heatmap - ๋ถํฌ ์๊ฐํ
์๋ต ์๊ฐ ๋ถํฌ๋ ์์ฒญ ๋น๋ ๊ฐ์ ๊ฑธ ์์์ผ๋ก ํํ. ํจํด์ ์ฐพ๊ธฐ ์ข์!
5. Table - ์์ธ ๋ฐ์ดํฐ
์ฌ๋ฌ ์๋ฒ์ ์ํ๋ฅผ ํ ๋ฒ์ ๋น๊ตํ๊ฑฐ๋, ์์ธํ ์์น๋ฅผ ๋ณด์ฌ์ค ๋ ์ ์ฉํด.
๐จ ์์๊ณผ ํ ๋ง ํ์ฉ
Grafana๋ ๋ค์ํ ์์ ์ต์ ์ ์ ๊ณตํด. ํจ๊ณผ์ ์ผ๋ก ํ์ฉํ๋ฉด ๊ฐ๋ ์ฑ์ด ํจ์ฌ ์ข์์ ธ!
# ์๊ณ๊ฐ ๊ธฐ๋ฐ ์์ ์ค์ ์์
Thresholds:
- 0: Green (#73BF69) โ ์ ์
- 70: Yellow (#FADE2A) โ ์ฃผ์
- 85: Orange (#FF9830) โ ๊ฒฝ๊ณ
- 95: Red (#F2495C) โ ์ํ
# ๊ทธ๋ผ๋์ธํธ ์์ (์๊ณ์ด ๊ทธ๋ํ)
Color scheme: Green-Yellow-Red
Gradient mode: Scheme
๐ฑ ๋ณ์(Variables) ํ์ฉํ๊ธฐ
๋ณ์๋ฅผ ์ฌ์ฉํ๋ฉด ํ๋์ ๋์๋ณด๋๋ก ์ฌ๋ฌ ์๋ฒ๋ ํ๊ฒฝ์ ๋ชจ๋ํฐ๋งํ ์ ์์ด. ์ ๋ง ๊ฐ๋ ฅํ ๊ธฐ๋ฅ์ด์ผ! ๐
๋ณ์ ์์ฑ ๋ฐฉ๋ฒ:
1. Dashboard settings (โ๏ธ) โ Variables โ Add variable
2. ๋ค์ ์ ๋ณด ์ ๋ ฅ:
# ์๋ฒ ์ธ์คํด์ค ์ ํ ๋ณ์
Name: instance
Type: Query
Data source: Prometheus
Query: label_values(node_cpu_seconds_total, instance)
Multi-value: true
Include All option: true
# ํ๊ฒฝ ์ ํ ๋ณ์
Name: env
Type: Query
Query: label_values(node_cpu_seconds_total, env)
Multi-value: false
3. ์ฟผ๋ฆฌ์์ ๋ณ์ ์ฌ์ฉ:
# ๋ณ์๋ฅผ ์ฌ์ฉํ ์ฟผ๋ฆฌ
node_cpu_seconds_total{instance="$instance", env="$env"}
# ์ ๊ทํํ์์ผ๋ก ์ฌ๋ฌ ๊ฐ ๋งค์นญ
node_cpu_seconds_total{instance=~"$instance"}
์ด์ ๋์๋ณด๋ ์๋จ์ ๋๋กญ๋ค์ด์ด ์๊ฒจ์ ์๋ฒ๋ ํ๊ฒฝ์ ์ ํํ ์ ์์ด. ํ๋์ ๋์๋ณด๋๋ก ๋ชจ๋ ์๋ฒ๋ฅผ ๋ชจ๋ํฐ๋งํ ์ ์๋ค๋, ํธ๋ฆฌํ์ง? ๐
1. ์ผ๊ด์ฑ ์ ์ง: ๊ฐ์ ์ข ๋ฅ์ ๋ฉํธ๋ฆญ์ ๊ฐ์ ์์๊ณผ ์คํ์ผ ์ฌ์ฉ
2. ์ฌ๋ฐฑ ํ์ฉ: ํจ๋ ์ฌ์ด์ ์ ์ ํ ๊ฐ๊ฒฉ์ ๋์ด ๊ฐ๋ ์ฑ ํฅ์
3. ๊ทธ๋ฃนํ: Row๋ฅผ ์ฌ์ฉํด์ ๊ด๋ จ ํจ๋๋ค์ ๋ ผ๋ฆฌ์ ์ผ๋ก ๋ฌถ๊ธฐ
4. ์ค๋ช ์ถ๊ฐ: ํจ๋ ์ ๋ชฉ๊ณผ ์ค๋ช ์ ๋ช ํํ๊ฒ ์์ฑ
5. ๋ชจ๋ฐ์ผ ๊ณ ๋ ค: ์์ ํ๋ฉด์์๋ ์ ๋ณด์ด๋๋ก ๋ ์ด์์ ์กฐ์
๐จ ์๋ฆผ(Alerting) ์ค์ ํ๊ธฐ
๋ชจ๋ํฐ๋ง์ ์ง์ ํ ๊ฐ์น๋ ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ ๋ ์ฆ์ ์๋ ค์ฃผ๋ ๊ฒ์ด์ผ. 24์๊ฐ ๋์๋ณด๋๋ฅผ ์ง์ผ๋ณผ ์๋ ์์์? ๊ทธ๋์ ์๋ฆผ ์ค์ ์ด ์ ๋ง ์ค์ํด! ๐ดโ๐ฑโ๐
๐ Prometheus Alertmanager ์ค์
Prometheus๋ Alertmanager๋ผ๋ ๋ณ๋ ์ปดํฌ๋ํธ๋ก ์๋ฆผ์ ๊ด๋ฆฌํด. ๋จผ์ Alertmanager๋ฅผ ์ค์นํ๊ณ ์ค์ ํด๋ณด์.
# Alertmanager ๋ค์ด๋ก๋ ๋ฐ ์ค์น
wget https://github.com/prometheus/alertmanager/releases/download/v0.26.0/alertmanager-0.26.0.linux-amd64.tar.gz
tar xvfz alertmanager-0.26.0.linux-amd64.tar.gz
cd alertmanager-0.26.0.linux-amd64
# ์ค์ ํ์ผ ์์ฑ (alertmanager.yml)
cat > alertmanager.yml << EOF
global:
resolve_timeout: 5m
route:
group_by: ['alertname', 'cluster']
group_wait: 10s
group_interval: 10s
repeat_interval: 12h
receiver: 'default'
receivers:
- name: 'default'
slack_configs:
- api_url: 'YOUR_SLACK_WEBHOOK_URL'
channel: '#alerts'
title: '๐จ Alert: {{ .GroupLabels.alertname }}'
text: '{{ range .Alerts }}{{ .Annotations.description }}{{ end }}'
EOF
# Alertmanager ์คํ
./alertmanager --config.file=alertmanager.yml
๐ ์๋ฆผ ๊ท์น ์์ฑํ๊ธฐ
์ด์ ์ด๋ค ์ํฉ์์ ์๋ฆผ์ ๋ณด๋ผ์ง ๊ท์น์ ์ ์ํด์ผ ํด. alerts.yml ํ์ผ์ ๋ง๋ค์ด๋ณด์:
groups:
- name: system_alerts
interval: 30s
rules:
# CPU ์ฌ์ฉ๋ฅ ๋์
- alert: HighCPUUsage
expr: 100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
for: 5m
labels:
severity: warning
annotations:
summary: "High CPU usage on {{ $labels.instance }}"
description: "CPU usage is {{ $value }}% for 5 minutes"
# ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ
- alert: HighMemoryUsage
expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 90
for: 5m
labels:
severity: critical
annotations:
summary: "High memory usage on {{ $labels.instance }}"
description: "Memory usage is {{ $value }}%"
# ๋์คํฌ ๊ณต๊ฐ ๋ถ์กฑ
- alert: DiskSpaceLow
expr: (1 - (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"})) * 100 > 85
for: 10m
labels:
severity: warning
annotations:
summary: "Low disk space on {{ $labels.instance }}"
description: "Disk usage is {{ $value }}%"
# ์๋ฒ ๋ค์ด
- alert: InstanceDown
expr: up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "Instance {{ $labels.instance }} is down"
description: "{{ $labels.instance }} has been down for more than 1 minute"
Prometheus ์ค์ ํ์ผ์ ์๋ฆผ ๊ท์น ํ์ผ์ ์ถ๊ฐํ๋ ๊ฒ๋ ์์ง ๋ง์:
# prometheus.yml์ ์ถ๊ฐ
rule_files:
- "alerts.yml"
alerting:
alertmanagers:
- static_configs:
- targets:
- localhost:9093
๐ฑ Grafana ์๋ฆผ ์ค์
Grafana์์๋ ์ง์ ์๋ฆผ์ ์ค์ ํ ์ ์์ด. ํน์ ํจ๋์ ๋ํ ์๋ฆผ์ ๋ง๋ค์ด๋ณด์!
1. Contact Point ์ค์
Alerting โ Contact points โ New contact point
# Slack ์ฐ๋ ์์
Name: Slack Alerts
Integration: Slack
Webhook URL: https://hooks.slack.com/services/YOUR/WEBHOOK/URL
Username: Grafana Bot
Channel: #monitoring
# ์ด๋ฉ์ผ ์ฐ๋ ์์
Name: Email Alerts
Integration: Email
Addresses: admin@example.com, team@example.com
2. Alert Rule ์์ฑ
ํจ๋ ํธ์ง โ Alert ํญ โ Create alert rule from this panel
Rule name: High CPU Alert
Condition: WHEN last() OF query(A) IS ABOVE 80
Evaluate every: 1m
For: 5m
Contact point: Slack Alerts
Message: CPU usage is critically high! Current: {{ $values.A }}%
๋๋ฌด ๋ง์ ์๋ฆผ์ ์คํ๋ ค ์ญํจ๊ณผ์ผ. ์ ๋ง ์ค์ํ ๊ฒ๋ง ์๋ฆผ์ผ๋ก ์ค์ ํ๊ณ , ๋๋จธ์ง๋ ๋์๋ณด๋์์ ํ์ธํ๋๋ก ํ์. ์๋ฆผ ์๊ณ๊ฐ๋ ๋๋ฌด ๋ฎ๊ฒ ์ค์ ํ๋ฉด false positive๊ฐ ๋ง์์ ธ์ ๊ฒฐ๊ตญ ๋ฌด์ํ๊ฒ ๋ผ. ์ ์ ํ ๊ท ํ์ด ์ค์ํด! ๐ฏ
๐ฏ ์๋ฆผ ์ฐ์ ์์ ์ ๋ต
| ์ฌ๊ฐ๋ | ์กฐ๊ฑด | ์๋ฆผ ๋ฐฉ๋ฒ | ์์ |
|---|---|---|---|
| Critical | ์ฆ์ ๋์ ํ์ | ์ ํ + SMS + Slack | ์๋ฒ ๋ค์ด, DB ์ ์ ๋ถ๊ฐ |
| Warning | ๊ณง ๋ฌธ์ ๋ฐ์ ๊ฐ๋ฅ | Slack + ์ด๋ฉ์ผ | CPU 80% ์ด์, ๋์คํฌ 85% ์ด์ |
| Info | ์ฐธ๊ณ ์ฉ ์ ๋ณด | ์ด๋ฉ์ผ๋ง | ๋ฐฐํฌ ์๋ฃ, ์ ๊ธฐ ๋ฐฑ์ ์๋ฃ |
๐ ์ค์ ํ์ฉ ์๋๋ฆฌ์ค
์ด๋ก ์ ์ถฉ๋ถํ ๋ฐฐ์ ์ผ๋, ์ด์ ์ค์ ์ํฉ์์ ์ด๋ป๊ฒ ํ์ฉํ๋์ง ์์๋ณด์! ์ค๋ฌด์์ ์์ฃผ ๋ง์ฃผ์น๋ ์๋๋ฆฌ์ค๋ค์ ์ค๋นํ์ด. ๐
๐ ์๋๋ฆฌ์ค 1: ์น ์๋น์ค ๋ชจ๋ํฐ๋ง
์น ์๋น์ค๋ฅผ ์ด์ํ๋ค๋ฉด ์ด๋ฐ ๊ฒ๋ค์ ๋ชจ๋ํฐ๋งํด์ผ ํด:
ํ์ ๋ชจ๋ํฐ๋ง ํญ๋ชฉ
1. ์ ํ๋ฆฌ์ผ์ด์ ๋ฉํธ๋ฆญ
# HTTP ์์ฒญ ์ (์ด๋น)
rate(http_requests_total[5m])
# ์๋ต ์๊ฐ (ํ๊ท )
histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))
# ์๋ฌ์จ
rate(http_requests_total{status=~"5.."}[5m]) / rate(http_requests_total[5m]) * 100
# ํ์ฑ ์ฌ์ฉ์ ์
http_active_connections
2. ๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฉํธ๋ฆญ
# ์ฟผ๋ฆฌ ์คํ ์๊ฐ
mysql_global_status_slow_queries
# ์ปค๋ฅ์
์
mysql_global_status_threads_connected
# ๋ฐ๋๋ฝ ๋ฐ์ ์
mysql_global_status_innodb_deadlocks
3. ๋น์ฆ๋์ค ๋ฉํธ๋ฆญ
# ํ์๊ฐ์
์ (์๊ฐ๋น)
increase(user_registrations_total[1h])
# ์ฃผ๋ฌธ ๊ฑด์
increase(orders_total[1h])
# ๊ฒฐ์ ์ฑ๊ณต๋ฅ
rate(payments_successful[5m]) / rate(payments_total[5m]) * 100
๐ณ ์๋๋ฆฌ์ค 2: Kubernetes ํด๋ฌ์คํฐ ๋ชจ๋ํฐ๋ง
Kubernetes๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ๋ ๋ง์ ๊ฒ๋ค์ ๋ชจ๋ํฐ๋งํด์ผ ํด. ๋คํํ Prometheus๋ Kubernetes์ ์๋ฒฝํ๊ฒ ํตํฉ๋ผ!
# Pod CPU ์ฌ์ฉ๋ฅ
sum(rate(container_cpu_usage_seconds_total{pod!=""}[5m])) by (pod)
# Pod ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋
sum(container_memory_usage_bytes{pod!=""}) by (pod) / 1024 / 1024 / 1024
# Pod ์ฌ์์ ํ์
kube_pod_container_status_restarts_total
# ๋
ธ๋ ์ํ
kube_node_status_condition{condition="Ready", status="true"}
# Pending ์ํ Pod
count(kube_pod_status_phase{phase="Pending"})
๐พ ์๋๋ฆฌ์ค 3: ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง
๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ์๋น์ค์ ์ฌ์ฅ์ด์ผ. ์ธ์ฌํ ๋ชจ๋ํฐ๋ง์ด ํ์ํด!
โข ์ฌ๋ก์ฐ ์ฟผ๋ฆฌ
โข ์ปค๋ฅ์ ํ ์ฌ์ฉ๋ฅ
โข ํ ์ด๋ธ ๋ฝ
โข ๋ณต์ ์ง์ฐ
โข InnoDB ๋ฒํผ ํ
โข ํธ๋์ญ์ ์
โข ์บ์ ํํธ์จ
โข ๋ฐ๋๋ฝ
โข ๋ฐฑ๊ทธ๋ผ์ด๋ ์์
โข WAL ํฌ๊ธฐ
โข ์์ ํ ๊ธธ์ด
โข ๋ณต์ ์ง์ฐ
โข ์ปค๋ฅ์ ์
โข ์ธ๋ฑ์ค ์ฌ์ฉ๋ฅ
โข ๋์คํฌ I/O
๐ฅ ์๋๋ฆฌ์ค 4: ์ฅ์ ๋์ ํ๋ก์ธ์ค
์๋ฆผ์ด ์์ ๋ ์ด๋ป๊ฒ ๋์ํด์ผ ํ ๊น? ์ฒด๊ณ์ ์ธ ํ๋ก์ธ์ค๊ฐ ์์ผ๋ฉด ๋นํฉํ์ง ์๊ณ ๋์ํ ์ ์์ด!
1๋จ๊ณ: ์ํฉ ํ์ (1-2๋ถ)
โข Grafana ๋์๋ณด๋์์ ์ ์ฒด ์์คํ ์ํ ํ์ธ
โข ์ด๋ค ์๋ฒ/์๋น์ค์์ ๋ฌธ์ ๊ฐ ๋ฐ์ํ๋์ง ์๋ณ
โข ์ํฅ ๋ฒ์ ํ์ (์ผ๋ถ ์ฌ์ฉ์? ์ ์ฒด?)
2๋จ๊ณ: ๊ธด๊ธ ์กฐ์น (2-5๋ถ)
โข ์๋น์ค ์ฌ์์ ๋๋ ํธ๋ํฝ ์ฐํ
โข ์ค์ผ์ผ ์์ (ํ์์)
โข ๊ด๋ จ ํ์ ์ํฉ ๊ณต์
3๋จ๊ณ: ์์ธ ๋ถ์ (10-30๋ถ)
โข ๋ก๊ทธ ํ์ธ
โข ๋ฉํธ๋ฆญ ํ์คํ ๋ฆฌ ๋ถ์
โข ์ต๊ทผ ๋ฐฐํฌ๋ ์ค์ ๋ณ๊ฒฝ ํ์ธ
4๋จ๊ณ: ๊ทผ๋ณธ ํด๊ฒฐ (์๊ฐ ๊ฐ๋ณ)
โข ์์ ์กฐ์น๋ฅผ ์๊ตฌ ํด๊ฒฐ์ฑ ์ผ๋ก ์ ํ
โข ์ฌ๋ฐ ๋ฐฉ์ง ๋์ฑ ์๋ฆฝ
โข ๋ฌธ์ํ ๋ฐ ํ ๊ณต์
โก ์ฑ๋ฅ ์ต์ ํ์ ๋ฒ ์คํธ ํ๋ํฐ์ค
Prometheus์ Grafana๋ฅผ ํจ์จ์ ์ผ๋ก ์ด์ํ๋ ค๋ฉด ๋ช ๊ฐ์ง ์ต์ ํ ๊ธฐ๋ฒ์ ์์์ผ ํด. ์์คํ ์ด ์ปค์ง์๋ก ์ด๋ฐ ๊ฒ๋ค์ด ์ ๋ง ์ค์ํด์ ธ! ๐ช
๐ฏ Prometheus ์ต์ ํ
1. ๋ฉํธ๋ฆญ ์์ง ์ต์ ํ
# ๋ถํ์ํ ๋ฉํธ๋ฆญ ์ ์ธ
scrape_configs:
- job_name: 'node'
metric_relabel_configs:
# ์ฌ์ฉํ์ง ์๋ ๋ฉํธ๋ฆญ ๋๋กญ
- source_labels: [__name__]
regex: 'node_network_receive_bytes_total|node_network_transmit_bytes_total'
action: drop
# ํน์ ๋ ์ด๋ธ ์ ๊ฑฐ
- regex: 'unnecessary_label'
action: labeldrop
์ ์ค์ํ ๊น? ๋ฉํธ๋ฆญ์ด ๋ง์์ง์๋ก ์ ์ฅ ๊ณต๊ฐ๊ณผ ์ฟผ๋ฆฌ ์ฑ๋ฅ์ ์ํฅ์ ์ค. ์ ๋ง ํ์ํ ๋ฉํธ๋ฆญ๋ง ์์งํ์!
2. ์ ์ฅ์ ๊ด๋ฆฌ
# Prometheus ์คํ ์ ์คํ ๋ฆฌ์ง ์ต์
์ค์
./prometheus \
--config.file=prometheus.yml \
--storage.tsdb.path=/data/prometheus \
--storage.tsdb.retention.time=30d \
--storage.tsdb.retention.size=50GB \
--storage.tsdb.wal-compression
๋ณด๊ด ๊ธฐ๊ฐ ์ ๋ต:
โข ์์ธ ๋ฐ์ดํฐ: 7-30์ผ
โข ์ง๊ณ ๋ฐ์ดํฐ: 90์ผ-1๋
โข ์ฅ๊ธฐ ๋ณด๊ด์ด ํ์ํ๋ฉด Thanos๋ Cortex ๊ฐ์ ์๋ฃจ์
๊ณ ๋ ค
3. ์ฟผ๋ฆฌ ์ฑ๋ฅ ๊ฐ์
# ๋๋ฌด ๊ธด ์๊ฐ ๋ฒ์
rate(http_requests_total[1d])
# ๋ถํ์ํ ์ง๊ณ
sum(rate(http_requests_total[5m])) without (instance)
# ์ ์ ํ ์๊ฐ ๋ฒ์
rate(http_requests_total[5m])
# ํ์ํ ๋ ์ด๋ธ๋ง ์ ์ง
sum(rate(http_requests_total[5m])) by (job, method)
๐ Grafana ์ต์ ํ
1. ๋์๋ณด๋ ์ฑ๋ฅ ๊ฐ์
์ฟผ๋ฆฌ ์ต์ ํ:
โข ํจ๋๋น ์ฟผ๋ฆฌ ์๋ฅผ ์ต์ํ (๊ฐ๋ฅํ๋ฉด 1-2๊ฐ)
โข ๋ณ์๋ฅผ ํ์ฉํด์ ๋์ ์ผ๋ก ํํฐ๋ง
โข ๋ถํ์ํ ์๊ณ์ด ์ ๊ฑฐ (topk, bottomk ํ์ฉ)
# ์์ 10๊ฐ๋ง ํ์
topk(10, rate(http_requests_total[5m]))
# ํน์ ์๊ณ๊ฐ ์ด์๋ง ํ์
rate(http_requests_total[5m]) > 100
์๋ก๊ณ ์นจ ๊ฐ๊ฒฉ ์กฐ์ :
โข ์ค์๊ฐ ๋ชจ๋ํฐ๋ง: 5-10์ด
โข ์ผ๋ฐ ๋ชจ๋ํฐ๋ง: 30์ด-1๋ถ
โข ํ์คํ ๋ฆฌ ๋ถ์: ์๋ ์๋ก๊ณ ์นจ
2. ๋์๋ณด๋ ๊ตฌ์ฑ ๋ฒ ์คํธ ํ๋ํฐ์ค
โข ์ผ๊ด๋ ์์ ์คํค๋ง
โข ๋ช ํํ ํจ๋ ์ ๋ชฉ
โข ์ ์ ํ ๋จ์ ํ์
โข ํดํ ์ค๋ช ์ถ๊ฐ
โข ์ค์๋ ์์ผ๋ก ๋ฐฐ์น
โข Row๋ก ๋ ผ๋ฆฌ์ ๊ทธ๋ฃนํ
โข ๋ชจ๋ฐ์ผ ์นํ์ ํฌ๊ธฐ
โข ์ ์ ํ ์ฌ๋ฐฑ ์ ์ง
โข ๋ณ์๋ก ์ ์ฐ์ฑ ํ๋ณด
โข ๋งํฌ๋ก ๋๋ฆด๋ค์ด
โข ์ฃผ์์ผ๋ก ์ด๋ฒคํธ ํ์
โข ํ ํ๋ฆฟ ํ์ฉ
๐ ๋ณด์ ๋ฒ ์คํธ ํ๋ํฐ์ค
1. ์ธ์ฆ ๋ฐ ๊ถํ:
โข ๊ธฐ๋ณธ admin ๋น๋ฐ๋ฒํธ ์ฆ์ ๋ณ๊ฒฝ
โข LDAP/OAuth ์ฐ๋์ผ๋ก ์ค์ ์ธ์ฆ ๊ด๋ฆฌ
โข ์ญํ ๊ธฐ๋ฐ ์ ๊ทผ ์ ์ด(RBAC) ์ค์
โข API ํค ์ ๊ธฐ์ ๊ฐฑ์
2. ๋คํธ์ํฌ ๋ณด์:
โข HTTPS ์ฌ์ฉ (Let's Encrypt ํ์ฉ)
โข ๋ฐฉํ๋ฒฝ์ผ๋ก ์ ๊ทผ ์ ํ
โข VPN ๋๋ ํ๋ผ์ด๋น ๋คํธ์ํฌ ์ฌ์ฉ
โข ๋ฆฌ๋ฒ์ค ํ๋ก์ ์ค์ (Nginx, Apache)
3. ๋ฐ์ดํฐ ๋ณดํธ:
โข ๋ฏผ๊ฐํ ๋ฉํธ๋ฆญ ๋ ์ด๋ธ ๋ง์คํน
โข ์ ๊ธฐ์ ์ธ ๋ฐฑ์
โข ๊ฐ์ฌ ๋ก๊ทธ ํ์ฑํ
โข ๋ฐ์ดํฐ ๋ณด๊ด ์ ์ฑ ์๋ฆฝ
๐ ํ์ฅ์ฑ ๊ณ ๋ ค์ฌํญ
์์คํ ์ด ์ฑ์ฅํ๋ฉด์ ๋ชจ๋ํฐ๋ง ์ธํ๋ผ๋ ํจ๊ป ์ฑ์ฅํด์ผ ํด. ๋ฏธ๋ฆฌ ์ค๋นํ๋ฉด ๋์ค์ ๊ณ ์ํ์ง ์์!
| ๊ท๋ชจ | ๋ฉํธ๋ฆญ ์ | ๊ถ์ฅ ๊ตฌ์ฑ | ๊ณ ๋ ค์ฌํญ |
|---|---|---|---|
| ์๊ท๋ชจ | ~100K | ๋จ์ผ Prometheus + Grafana | ๊ธฐ๋ณธ ์ค์ ์ผ๋ก ์ถฉ๋ถ |
| ์ค๊ท๋ชจ | 100K~1M | Prometheus HA + ๋ก๋๋ฐธ๋ฐ์ | ์ ์ฅ์ ์ฉ๋ ๋ชจ๋ํฐ๋ง ํ์ |
| ๋๊ท๋ชจ | 1M~10M | Prometheus Federation + Thanos | ์ค๋ฉ ๋ฐ ์ฅ๊ธฐ ์ ์ฅ์ ํ์ |
| ์ด๋๊ท๋ชจ | 10M+ | Cortex ๋๋ Mimir | ์ ๋ฌธ ์ปจ์คํ ๊ถ์ฅ |
๐ ๊ณ ๊ธ ๊ธฐ๋ฅ๊ณผ ํ์ฅ
๊ธฐ๋ณธ์ ๋ง์คํฐํ๋ค๋ฉด, ์ด์ ๋ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ๋ค์ ํ์ฉํด๋ณผ ์๊ฐ์ด์ผ! ์ด๋ฐ ๊ณ ๊ธ ๊ธฐ๋ฅ๋ค์ ์๋ฉด ์ง์ง ์ ๋ฌธ๊ฐ๊ฐ ๋ ์ ์์ด. ๐
๐ Recording Rules๋ก ์ฟผ๋ฆฌ ์ต์ ํ
๋ณต์กํ ์ฟผ๋ฆฌ๋ฅผ ๋งค๋ฒ ์คํํ๋ ๊ฑด ๋นํจ์จ์ ์ด์ผ. Recording Rules๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฏธ๋ฆฌ ๊ณ์ฐํด์ ์ ์ฅํ ์ ์์ด!
# recording_rules.yml
groups:
- name: cpu_rules
interval: 30s
rules:
# CPU ์ฌ์ฉ๋ฅ ์ ๋ฏธ๋ฆฌ ๊ณ์ฐ
- record: instance:cpu_usage:rate5m
expr: 100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# ์๋ฒ๋ณ ํ๊ท ์๋ต ์๊ฐ
- record: instance:http_response_time:avg
expr: histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))
# ์ผ๋ณ ์์ฒญ ์ ์ง๊ณ
- record: job:http_requests:rate1h
expr: sum by(job) (rate(http_requests_total[1h]))
์ด์ ๋์๋ณด๋์์ ๋ณต์กํ ์ฟผ๋ฆฌ ๋์ instance:cpu_usage:rate5m ๊ฐ์ ๊ฐ๋จํ ๋ฉํธ๋ฆญ ์ด๋ฆ๋ง ์ฌ์ฉํ๋ฉด ๋ผ. ํจ์ฌ ๋น ๋ฅด๊ณ ํจ์จ์ ์ด์ง! โก
๐จ ์ปค์คํ Exporter ๋ง๋ค๊ธฐ
๊ธฐ๋ณธ Exporter๋ก ๋ถ์กฑํ๋ค๋ฉด? ์ง์ ๋ง๋ค ์ ์์ด! Python์ผ๋ก ๊ฐ๋จํ ์์ ๋ฅผ ๋ง๋ค์ด๋ณด์.
# custom_exporter.py
from prometheus_client import start_http_server, Gauge
import time
import psutil
# ๋ฉํธ๋ฆญ ์ ์
cpu_usage = Gauge('custom_cpu_usage', 'CPU usage percentage')
memory_usage = Gauge('custom_memory_usage', 'Memory usage percentage')
disk_usage = Gauge('custom_disk_usage', 'Disk usage percentage', ['partition'])
def collect_metrics():
"""์์คํ
๋ฉํธ๋ฆญ ์์ง"""
while True:
# CPU ์ฌ์ฉ๋ฅ
cpu_usage.set(psutil.cpu_percent(interval=1))
# ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ฅ
memory = psutil.virtual_memory()
memory_usage.set(memory.percent)
# ๋์คํฌ ์ฌ์ฉ๋ฅ (ํํฐ์
๋ณ)
for partition in psutil.disk_partitions():
try:
usage = psutil.disk_usage(partition.mountpoint)
disk_usage.labels(partition=partition.device).set(usage.percent)
except:
pass
time.sleep(15) # 15์ด๋ง๋ค ์์ง
if __name__ == '__main__':
# 8000 ํฌํธ์์ ๋ฉํธ๋ฆญ ์ ๊ณต
start_http_server(8000)
print("Exporter running on port 8000")
collect_metrics()
์ด๋ ๊ฒ ๋ง๋ Exporter๋ฅผ Prometheus ์ค์ ์ ์ถ๊ฐํ๋ฉด ๋ฐ๋ก ์ฌ์ฉํ ์ ์์ด!
๐ Service Discovery ํ์ฉ
์๋ฒ๊ฐ ๋์ ์ผ๋ก ์ถ๊ฐ/์ ๊ฑฐ๋๋ ํ๊ฒฝ์ด๋ผ๋ฉด Service Discovery๊ฐ ํ์์ผ. Kubernetes ์์ ๋ฅผ ๋ณด์:
# Kubernetes Service Discovery ์ค์
scrape_configs:
- job_name: 'kubernetes-pods'
kubernetes_sd_configs:
- role: pod
relabel_configs:
# prometheus.io/scrape ์ด๋
ธํ
์ด์
์ด ์๋ Pod๋ง ์์ง
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
action: keep
regex: true
# ํฌํธ ์ค์
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port]
action: replace
target_label: __address__
regex: (.+)
replacement: $1
# ๋ฉํธ๋ฆญ ๊ฒฝ๋ก ์ค์
- source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
action: replace
target_label: __metrics_path__
regex: (.+)
# ๋ ์ด๋ธ ์ถ๊ฐ
- source_labels: [__meta_kubernetes_namespace]
target_label: kubernetes_namespace
- source_labels: [__meta_kubernetes_pod_name]
target_label: kubernetes_pod_name
๐ Grafana ํ๋ฌ๊ทธ์ธ ํ์ฉ
Grafana๋ ๋ค์ํ ํ๋ฌ๊ทธ์ธ์ผ๋ก ๊ธฐ๋ฅ์ ํ์ฅํ ์ ์์ด. ์ ์ฉํ ํ๋ฌ๊ทธ์ธ๋ค์ ์๊ฐํ ๊ฒ!
์ง๋ฆฌ์ ๋ฐ์ดํฐ๋ฅผ ์ธ๊ณ ์ง๋์ ํ์. ๊ธ๋ก๋ฒ ์๋น์ค ๋ชจ๋ํฐ๋ง์ ์๋ฒฝ!
๊ณ ๊ธ ํต๊ณ ์ฐจํธ์ 3D ์๊ฐํ. ๋ณต์กํ ๋ฐ์ดํฐ ๋ถ์์ ์ ์ฉ!
ํ์ฌ ๋ฐ์ ์ค์ธ ์๋ฆผ์ ํ๋์ ํ์. ๋์๋ณด๋์ ์ถ๊ฐํ๋ฉด ํธ๋ฆฌ!
# ํ๋ฌ๊ทธ์ธ ์ค์น ๋ช
๋ น์ด
grafana-cli plugins install grafana-worldmap-panel
grafana-cli plugins install natel-plotly-panel
grafana-cli plugins install camptocamp-prometheus-alertmanager-datasource
# ์ค์น ํ Grafana ์ฌ์์
sudo systemctl restart grafana-server
๐ Prometheus Federation
์ฌ๋ฌ Prometheus ์๋ฒ๋ฅผ ๊ณ์ธต์ ์ผ๋ก ๊ตฌ์ฑํด์ ๋๊ท๋ชจ ํ๊ฒฝ์ ๊ด๋ฆฌํ ์ ์์ด!
# ์ค์ Prometheus ์ค์
scrape_configs:
- job_name: 'federate'
scrape_interval: 15s
honor_labels: true
metrics_path: '/federate'
params:
'match[]':
- '{job="prometheus"}'
- '{__name__=~"job:.*"}' # Recording rules
static_configs:
- targets:
- 'prometheus-dc1:9090'
- 'prometheus-dc2:9090'
- 'prometheus-dc3:9090'
์ด๋ ๊ฒ ํ๋ฉด ๊ฐ ๋ฐ์ดํฐ์ผํฐ์ Prometheus๊ฐ ๋ก์ปฌ ๋ฉํธ๋ฆญ์ ์์งํ๊ณ , ์ค์ Prometheus๊ฐ ์ง๊ณ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์. ํจ์จ์ ์ด์ง? ๐
๐ฏ ์ค๋ฌด ํ๊ณผ ํธ๋ฌ๋ธ์ํ
์ค์ ๋ก ์ด์ํ๋ค ๋ณด๋ฉด ์์์น ๋ชปํ ๋ฌธ์ ๋ค์ ๋ง๋๊ฒ ๋ผ. ์์ฃผ ๋ฐ์ํ๋ ๋ฌธ์ ๋ค๊ณผ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ์ ๋ฆฌํด๋ดค์ด!
๐ง ์์ฃผ ๋ฐ์ํ๋ ๋ฌธ์ ๋ค
๋ฌธ์ 1: "Target Down" ์๋ฌ
์ฆ์: Prometheus UI์์ ํ๊ฒ์ด ๋นจ๊ฐ์์ผ๋ก ํ์๋๊ณ "context deadline exceeded" ์๋ฌ
์์ธ:
โข ๋ฐฉํ๋ฒฝ์ด๋ ๋ณด์ ๊ทธ๋ฃน์์ ํฌํธ ์ฐจ๋จ
โข ํ๊ฒ ์๋ฒ์ Exporter๊ฐ ์คํ๋์ง ์์
โข ๋คํธ์ํฌ ์ง์ฐ์ด๋ ํ์์์
โข ์๋ชป๋ IP ์ฃผ์๋ ํฌํธ ์ค์
ํด๊ฒฐ ๋ฐฉ๋ฒ:
# 1. ํ๊ฒ ์๋ฒ์์ Exporter ์ํ ํ์ธ
curl http://target-server:9100/metrics
# 2. ๋คํธ์ํฌ ์ฐ๊ฒฐ ํ
์คํธ
telnet target-server 9100
# 3. Prometheus ๋ก๊ทธ ํ์ธ
tail -f /var/log/prometheus/prometheus.log
# 4. ํ์์์ ์ค์ ์กฐ์
scrape_configs:
- job_name: 'node'
scrape_timeout: 30s # ๊ธฐ๋ณธ 10s์์ ์ฆ๊ฐ
๋ฌธ์ 2: Grafana ๋์๋ณด๋๊ฐ ๋๋ฆผ
์ฆ์: ๋์๋ณด๋ ๋ก๋ฉ์ด ์ค๋ ๊ฑธ๋ฆฌ๊ฑฐ๋ ํ์์์ ๋ฐ์
์์ธ:
โข ๋๋ฌด ๋ง์ ํจ๋์ด๋ ๋ณต์กํ ์ฟผ๋ฆฌ
โข ๊ธด ์๊ฐ ๋ฒ์ ์กฐํ
โข ๋์ ์๋ก๊ณ ์นจ ๋น๋
โข Prometheus ์๋ฒ ๊ณผ๋ถํ
ํด๊ฒฐ ๋ฐฉ๋ฒ:
# 1. ์ฟผ๋ฆฌ ์ต์ ํ - ์๊ฐ ๋ฒ์ ์ ํ
rate(http_requests_total[5m]) # โ
์ข์
rate(http_requests_total[1d]) # โ ๋์จ
# 2. ๋ถํ์ํ ์๊ณ์ด ์ ๊ฑฐ
topk(10, rate(http_requests_total[5m])) # ์์ 10๊ฐ๋ง
# 3. Recording Rules ์ฌ์ฉ
# ๋ณต์กํ ์ฟผ๋ฆฌ๋ฅผ ๋ฏธ๋ฆฌ ๊ณ์ฐํด์ ์ ์ฅ
# 4. ํจ๋ ์ ์ค์ด๊ธฐ
# ๋น์ทํ ๋ฉํธ๋ฆญ์ ํ๋์ ํจ๋์ ํตํฉ
๋ฌธ์ 3: ๋์คํฌ ๊ณต๊ฐ ๋ถ์กฑ
์ฆ์: Prometheus๊ฐ "out of disk space" ์๋ฌ์ ํจ๊ป ์ค๋จ
ํด๊ฒฐ ๋ฐฉ๋ฒ:
# 1. ํ์ฌ ์ฌ์ฉ๋ ํ์ธ
du -sh /data/prometheus
# 2. ๋ณด๊ด ๊ธฐ๊ฐ ๋จ์ถ
./prometheus \
--storage.tsdb.retention.time=15d \ # 30d โ 15d
--storage.tsdb.retention.size=30GB
# 3. ์ค๋๋ ๋ฐ์ดํฐ ์๋ ์ญ์
# Prometheus๋ฅผ ์ค์งํ๊ณ
rm -rf /data/prometheus/01XXXXXX* # ์ค๋๋ ๋ธ๋ก ์ญ์
# 4. ๋ถํ์ํ ๋ฉํธ๋ฆญ ์ ์ธ
metric_relabel_configs:
- source_labels: [__name__]
regex: 'unused_metric_.*'
action: drop
๋ฌธ์ 4: ์๋ฆผ์ด ์ค์ง ์์
์ฆ์: ์๋ฆผ ๊ท์น์ด ๋ฐ๋ํ๋๋ฐ ์๋ฆผ์ ๋ฐ์ง ๋ชปํจ
์ฒดํฌ๋ฆฌ์คํธ:
โข Prometheus UI โ Alerts ํญ์์ ๊ท์น์ด Firing ์ํ์ธ์ง ํ์ธ
2. Alertmanager ์ฐ๊ฒฐ ํ์ธ
โข Prometheus UI โ Status โ Runtime & Build Information
โข Alertmanagers ์น์ ์์ ์ฐ๊ฒฐ ์ํ ํ์ธ
3. Alertmanager ๋ก๊ทธ ํ์ธ
tail -f /var/log/alertmanager/alertmanager.log4. ์๋ฆผ ์ฑ๋ ์ค์ ํ์ธ
โข Slack Webhook URL์ด ์ฌ๋ฐ๋ฅธ์ง
โข ์ด๋ฉ์ผ SMTP ์ค์ ์ด ์ ํํ์ง
โข ๋ฐฉํ๋ฒฝ์์ ์์๋ฐ์ด๋ ์ฐ๊ฒฐ ํ์ฉ ์ฌ๋ถ
๐ก ์ฑ๋ฅ ํ๋ ํ
โข WAL ์์ถ ํ์ฑํ
โข ๋ฉ๋ชจ๋ฆฌ ๋งต ์ฒญํฌ ์ฌ์ฉ
โข ์ ์ ํ ์คํฌ๋ฉ ๊ฐ๊ฒฉ ์ค์
โข ์ค๋ฉ ๊ณ ๋ ค (๋๊ท๋ชจ ํ๊ฒฝ)
โข ์ฟผ๋ฆฌ ์บ์ฑ ํ์ฉ
โข ํจ๋๋ณ ์๋ก๊ณ ์นจ ๊ฐ๊ฒฉ ์กฐ์
โข ๋ณ์ ์ฟผ๋ฆฌ ์ต์ ํ
โข ์ด๋ฏธ์ง ๋ ๋๋ง ์๋ฒ ๋ถ๋ฆฌ
โข Recording Rules ์ ๊ทน ํ์ฉ
โข ๋ ์ด๋ธ ์นด๋๋๋ฆฌํฐ ๊ด๋ฆฌ
โข ์ง๊ณ ํจ์ ํจ์จ์ ์ฌ์ฉ
โข ๋ถํ์ํ ์ ๊ทํํ์ ์ ๊ฑฐ
๐ ์ ์ฉํ ๋ฆฌ์์ค
๊ณ์ ํ์ตํ๊ณ ์ถ๋ค๋ฉด ์ด๋ฐ ๋ฆฌ์์ค๋ค์ ํ์ฉํด๋ด:
โข Prometheus ๊ณต์ ๋ฌธ์: prometheus.io/docs
โข Grafana ๊ณต์ ๋ฌธ์: grafana.com/docs
โข PromQL ์นํธ์ํธ: promlabs.com/promql-cheat-sheet
๐ฅ ์ปค๋ฎค๋ํฐ:
โข Prometheus ์ฌ๋: slack.cncf.io
โข Grafana ํฌ๋ผ: community.grafana.com
โข Stack Overflow: prometheus, grafana ํ๊ทธ
๐ ํ์ต ์๋ฃ:
โข Prometheus Up & Running (์ฑ )
โข Grafana ๊ณต์ ํํ ๋ฆฌ์ผ
โข YouTube ์ฑ๋: Grafana Labs, Prometheus
๐ ์ ๋ฌธ๊ฐ ๋์:
โข ์ฌ๋ฅ๋ท์์ ๋ชจ๋ํฐ๋ง ์ ๋ฌธ๊ฐ ์ฐพ๊ธฐ
โข ์ปจ์คํ ์๋น์ค ํ์ฉ
โข ์จ๋ผ์ธ ๊ฐ์ ์๊ฐ
๐ฌ ๋ง๋ฌด๋ฆฌํ๋ฉฐ
์! ์ฌ๊ธฐ๊น์ง ์ฝ์๋ค๋ฉด ์ ๋ง ๋๋จํด! ๐ Prometheus์ Grafana์ ๋ํด ๊ฝค ๋ง์ ๊ฑธ ๋ฐฐ์ ์ ๊ฑฐ์ผ. ์ฒ์์ ๋ณต์กํด ๋ณด์๊ฒ ์ง๋ง, ํ๋์ฉ ๋ฐ๋ผํ๋ค ๋ณด๋ฉด ์ด๋์ ์ ๋ฌธ๊ฐ๊ฐ ๋์ด ์์ ๊ฑฐ์ผ.
๋ชจ๋ํฐ๋ง์ ๋จ์ํ ๋๊ตฌ๋ฅผ ์ค์นํ๊ณ ๋๋๋ ๊ฒ ์๋์ผ. ์ง์์ ์ธ ๊ฐ์ ๊ณผ ์ต์ ํ๊ฐ ํ์ํ ์ฌ์ ์ด์ง. ์์คํ ์ด ์ฑ์ฅํ๋ฉด์ ๋ชจ๋ํฐ๋ง๋ ํจ๊ป ์งํํด์ผ ํด. ๊ทธ๋ฆฌ๊ณ ๊ทธ ๊ณผ์ ์์ ๋ง์ ๊ฒ์ ๋ฐฐ์ฐ๊ฒ ๋ ๊ฑฐ์ผ! ๐
๐ฏ ํต์ฌ ์์ฝ
1. Prometheus๋ ๋ฐ์ดํฐ ์์ง๊ณผ ์ ์ฅ์ ๋ด๋น
โข Pull ๋ฐฉ์์ผ๋ก ๋ฉํธ๋ฆญ ์์ง
โข ์๊ณ์ด ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ํจ์จ์ ์ผ๋ก ์ ์ฅ
โข PromQL๋ก ๊ฐ๋ ฅํ ์ฟผ๋ฆฌ ๊ฐ๋ฅ
โข Alertmanager๋ก ์๋ฆผ ๊ด๋ฆฌ
2. Grafana๋ ์๊ฐํ๋ฅผ ๋ด๋น
โข ์๋ฆ๋ต๊ณ ์ง๊ด์ ์ธ ๋์๋ณด๋
โข ๋ค์ํ ๋ฐ์ดํฐ ์์ค ์ง์
โข ํ๋ถํ ์๊ฐํ ์ต์
โข ์๋ฆผ ๋ฐ ๊ณต์ ๊ธฐ๋ฅ
3. ํจ๊ป ์ฌ์ฉํ๋ฉด ์๋ฒฝํ ๋ชจ๋ํฐ๋ง ์์คํ
โข ์ค์๊ฐ ๋ชจ๋ํฐ๋ง
โข ๋ฌธ์ ์กฐ๊ธฐ ๋ฐ๊ฒฌ
โข ์ฑ๋ฅ ์ต์ ํ
โข ๋ฐ์ดํฐ ๊ธฐ๋ฐ ์์ฌ๊ฒฐ์
์๋ฒฝํ ๋ชจ๋ํฐ๋ง ์์คํ ์ ํ ๋ฒ์ ๊ตฌ์ถํ๋ ค๊ณ ํ์ง ๋ง. ์๊ฒ ์์ํด์ ์ ์ง์ ์ผ๋ก ๊ฐ์ ํด๋๊ฐ๋ ๊ฒ ์ข์. ๊ธฐ๋ณธ์ ์ธ ์์คํ ๋ฉํธ๋ฆญ๋ถํฐ ์์ํด์, ํ์์ ๋ฐ๋ผ ์ ํ๋ฆฌ์ผ์ด์ ๋ฉํธ๋ฆญ, ๋น์ฆ๋์ค ๋ฉํธ๋ฆญ์ ์ถ๊ฐํด๊ฐ๋ฉด ๋ผ.
๊ทธ๋ฆฌ๊ณ ํผ์ ๊ณ ๋ฏผํ์ง ๋ง๊ณ ์ปค๋ฎค๋ํฐ๋ฅผ ํ์ฉํ์! ์ฌ๋ฅ๋ท ๊ฐ์ ํ๋ซํผ์์ ์ ๋ฌธ๊ฐ์ ๋์์ ๋ฐ๋ ๊ฒ๋ ์ข์ ๋ฐฉ๋ฒ์ด์ผ. ๋๋ก๋ ๊ฒฝํ ๋ง์ ์ฌ๋์ ์กฐ์ธ ํ๋ง๋๊ฐ ๋ฉฐ์น ๊ฐ์ ์ฝ์ง์ ์ค์ฌ์ค ์ ์๊ฑฐ๋ ! ๐
์๋ฒ ๋ชจ๋ํฐ๋ง์ ๋ง๋ผํค์ด์ง ๋จ๊ฑฐ๋ฆฌ ๋ฌ๋ฆฌ๊ธฐ๊ฐ ์๋์ผ. ์ฒ์ฒํ, ๊พธ์คํ ๊ฐ์ ํด๋๊ฐ๋ค ๋ณด๋ฉด ์ด๋์ ์์ ์ ์ด๊ณ ํจ์จ์ ์ธ ์์คํ ์ ๊ฐ์ถ๊ฒ ๋ ๊ฑฐ์ผ. ํ์ดํ ! ๐ช
์ด ๊ธ์ด ๋์์ด ๋์๋ค๋ฉด, ์ฌ๋ฅ๋ท์์ ๋ ๋ง์ IT ์ง์์ ํํํด๋ณด์ธ์! ๐
์ง๋ฌธ์ด๋ ํผ๋๋ฐฑ์ ์ธ์ ๋ ํ์์
๋๋ค. ํจ๊ป ์ฑ์ฅํด์! ๐ช
๊ด๋ จ ํค์๋
๋๊ธ ์์ฑ
์ด ๊ธ์ ๋ํ ์ฌ๋ฌ๋ถ์ ์๊ฐ์ ๋ค๋ ค์ฃผ์ธ์
๋ก๊ทธ์ธ์ด ํ์ํฉ๋๋ค
๋๊ธ์ ์์ฑํ๋ ค๋ฉด ๋จผ์ ๋ก๊ทธ์ธํด์ฃผ์ธ์.
๋๊ธ 0
์ง์์ธ์ ์ฒ - ์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
์ง์ ์ฌ์ฐ๊ถ ๋ณดํธ ๊ณ ์ง
- ์ ์๊ถ ๋ฐ ์์ ๊ถ: ๋ณธ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ๋ ์ AI ๊ธฐ์ ๋ก ์์ฑ๋์์ผ๋ฉฐ, ๋ํ๋ฏผ๊ตญ ์ ์๊ถ๋ฒ ๋ฐ ๊ตญ์ ์ ์๊ถ ํ์ฝ์ ์ํด ๋ณดํธ๋ฉ๋๋ค.
- AI ์์ฑ ์ปจํ ์ธ ์ ๋ฒ์ ์ง์: ๋ณธ AI ์์ฑ ์ปจํ ์ธ ๋ ์ฌ๋ฅ๋ท์ ์ง์ ์ฐฝ์๋ฌผ๋ก ์ธ์ ๋๋ฉฐ, ๊ด๋ จ ๋ฒ๊ท์ ๋ฐ๋ผ ์ ์๊ถ ๋ณดํธ๋ฅผ ๋ฐ์ต๋๋ค.
- ์ฌ์ฉ ์ ํ: ์ฌ๋ฅ๋ท์ ๋ช ์์ ์๋ฉด ๋์ ์์ด ๋ณธ ์ปจํ ์ธ ๋ฅผ ๋ณต์ , ์์ , ๋ฐฐํฌ, ๋๋ ์์ ์ ์ผ๋ก ํ์ฉํ๋ ํ์๋ ์๊ฒฉํ ๊ธ์ง๋ฉ๋๋ค.
- ๋ฐ์ดํฐ ์์ง ๊ธ์ง: ๋ณธ ์ปจํ ์ธ ์ ๋ํ ๋ฌด๋จ ์คํฌ๋ํ, ํฌ๋กค๋ง, ๋ฐ ์๋ํ๋ ๋ฐ์ดํฐ ์์ง์ ๋ฒ์ ์ ์ฌ์ ๋์์ด ๋ฉ๋๋ค.
- AI ํ์ต ์ ํ: ์ฌ๋ฅ๋ท์ AI ์์ฑ ์ปจํ ์ธ ๋ฅผ ํ AI ๋ชจ๋ธ ํ์ต์ ๋ฌด๋จ ์ฌ์ฉํ๋ ํ์๋ ๊ธ์ง๋๋ฉฐ, ์ด๋ ์ง์ ์ฌ์ฐ๊ถ ์นจํด๋ก ๊ฐ์ฃผ๋ฉ๋๋ค.
์์ง ๋๊ธ์ด ์์ต๋๋ค.