راهاندازی مانیتورینگ سرور با Prometheus و Grafana روی سرور مجازی و اختصاصی
وقتی مصرف CPU برای چند دقیقه بالا میرود، فضای دیسک رو به پایان است یا حافظهٔ سرور بهتدریج پر میشود، ورود دستی با SSH معمولاً دیرتر از زمانی انجام میشود که مشکل بر سرویس اثر گذاشته است. یک سامانهٔ مانیتورینگ مناسب باید وضعیت فعلی را نشان دهد، دادههای گذشته را نگه دارد و پیش از بحرانیشدن شرایط هشدار بفرستد.
در این راهنما، راهاندازی مانیتورینگ سرور با Prometheus و Grafana را با Docker Compose انجام میدهیم. Prometheus معیارها را جمعآوری و ذخیره میکند، Node Exporter اطلاعات سیستمعامل را در اختیار آن میگذارد و Grafana دادهها را به نمودار و داشبورد تبدیل میکند.
این روش برای یک سرور مجازی، سرور اختصاصی یا یک ماشین مانیتورینگ مرکزی مناسب است. دستورها بر مبنای Ubuntu و Debian نوشته شدهاند، اما ساختار پیکربندی در توزیعهای دیگر نیز تفاوت زیادی ندارد.

اجزای استک مانیتورینگ چه کاری انجام میدهند؟
هر جزء مسئولیت مشخصی دارد: - Node Exporter معیارهایی مانند بار پردازنده، حافظه، فضای دیسک، ورودی و خروجی شبکه و وضعیت فایلسیستم را از لینوکس میخواند. - Prometheus در بازههای زمانی مشخص به endpoint معیارها متصل میشود، دادهها را جمع میکند و در پایگاه دادهٔ سری زمانی خود نگه میدارد. - Grafana به Prometheus متصل میشود و دادهها را در داشبوردهای قابلفهم نمایش میدهد. - Alertmanager در صورت نیاز هشدارهای Prometheus را گروهبندی و به مقصدهایی مانند ایمیل، Slack یا webhook ارسال میکند. برای شروع، سه جزء اول کافیاند. Alertmanager را پس از اطمینان از صحت جمعآوری معیارها اضافه میکنیم.
منابع موردنیاز برای Prometheus و Grafana
میزان مصرف منابع به تعداد سرورها، تعداد معیارها، فاصلهٔ scrape و مدت نگهداری داده وابسته است. برای مانیتورینگ یک تا پنج سرور با فاصلهٔ جمعآوری ۱۵ ثانیه، مقادیر زیر نقطهٔ شروع مناسبی هستند:
| تعداد سرور | پردازنده پیشنهادی | حافظهٔ پیشنهادی | فضای ذخیرهسازی اولیه |
|---|---|---|---|
| ۱ تا ۵ | ۲ هسته | ۲ تا ۴ گیگابایت | ۲۰ تا ۴۰ گیگابایت SSD |
| ۶ تا ۲۰ | ۴ هسته | ۸ گیگابایت | ۸۰ تا ۱۵۰ گیگابایت SSD |
| بیش از ۲۰ | وابسته به تعداد سریها | حداقل ۸ گیگابایت | بر اساس نرخ رشد داده |
این اعداد قطعی نیستند. اگر exporterهای متعدد، سرویسهای Kubernetes یا معیارهای برنامه را نیز جمعآوری کنید، تعداد سریهای زمانی و مصرف دیسک بیشتر میشود. بعد از چند روز، حجم دایرکتوری دادهٔ Prometheus و نرخ رشد آن را بررسی کنید. بهتر است استک مانیتورینگ روی ماشینی جدا از سرویس اصلی اجرا شود. در این حالت، اختلال یا پرشدن منابع سرور برنامه، دسترسی شما به داشبورد مانیتورینگ را هم از بین نمیبرد.
پیشنیازهای نصب
پیش از شروع مطمئن شوید که:
- یک سرور لینوکسی با دسترسی sudo دارید.
- Docker Engine و افزونهٔ Docker Compose نصب شدهاند.
- پورتهای موردنیاز در فایروال مشخص شدهاند.
- ساعت سیستم با NTP همگام است.
- برای محیط عمومی، دامنه و گواهی TLS یا دستکم دسترسی VPN دارید.
نسخههای نصبشده را بررسی کنید:
docker --version
docker compose version
timedatectl status
در این راهنما سرویسهای زیر استفاده میشوند:
| سرویس | پورت پیشفرض | دسترسی پیشنهادی |
|---|---|---|
| Grafana | 3000 | فقط از طریق reverse proxy با HTTPS |
| Prometheus | 9090 | شبکهٔ داخلی یا VPN |
| Node Exporter | 9100 | فقط IP سرور Prometheus |
| Alertmanager | 9093 | شبکهٔ داخلی یا VPN |
پورتهای Prometheus، Node Exporter و Alertmanager را بدون محدودیت روی اینترنت باز نکنید. این endpointها ممکن است اطلاعاتی دربارهٔ نام میزبان، فایلسیستم و ساختار زیرساخت نشان دهند.
ساخت ساختار پروژه
ابتدا یک دایرکتوری برای فایلهای پیکربندی بسازید:
sudo mkdir -p /opt/monitoring/{prometheus,grafana/provisioning/datasources}
sudo chown -R "$USER":"$USER" /opt/monitoring
cd /opt/monitoring
ساختار نهایی چنین خواهد بود:
/opt/monitoring/
├── compose.yaml
├── prometheus/
│ ├── prometheus.yml
│ └── alerts.yml
└── grafana/
└── provisioning/
└── datasources/
└── prometheus.yml
پیکربندی Prometheus و هدفهای scrape
فایل prometheus/prometheus.yml را ایجاد کنید:
global:
scrape_interval: 15s
evaluation_interval: 15s
rule_files:
- /etc/prometheus/alerts.yml
scrape_configs:
- job_name: prometheus
static_configs:
- targets:
- prometheus:9090
- job_name: linux-servers
static_configs:
- targets:
- node-exporter:9100
labels:
environment: production
server_role: monitoring
در این فایل، Prometheus هر ۱۵ ثانیه معیارها را میخواند. نامهای environment و server_role برچسبهای اختیاریاند، اما هنگام ساخت داشبورد یا فیلترکردن هشدارها مفید هستند.
اگر Node Exporter روی سرورهای دیگری نصب شده است، IP خصوصی یا نام DNS آنها را به فهرست اضافه کنید:
- job_name: linux-servers
static_configs:
- targets:
- 10.10.0.11:9100
- 10.10.0.12:9100
labels:
environment: production
برای جلوگیری از خطاهای YAML از فاصله استفاده کنید و سراغ Tab نروید. همچنین هر بار پس از تغییر فایل، پیکربندی Prometheus را بررسی کنید:
docker run --rm \
-v "$PWD/prometheus:/etc/prometheus:ro" \
prom/prometheus:latest \
promtool check config /etc/prometheus/prometheus.yml
در محیط تولید بهتر است بهجای latest یک نسخهٔ مشخص و آزمایششده را در فایل Compose ثبت کنید تا ارتقای ناخواسته رخ ندهد.
تعریف سرویسها در Docker Compose
فایل compose.yaml را با محتوای زیر بسازید:
services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
restart: unless-stopped
command:
- --config.file=/etc/prometheus/prometheus.yml
- --storage.tsdb.path=/prometheus
- --storage.tsdb.retention.time=30d
volumes:
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
- ./prometheus/alerts.yml:/etc/prometheus/alerts.yml:ro
- prometheus-data:/prometheus
ports:
- "127.0.0.1:9090:9090"
networks:
- monitoring
node-exporter:
image: prom/node-exporter:latest
container_name: node-exporter
restart: unless-stopped
command:
- --path.rootfs=/host
volumes:
- /:/host:ro,rslave
ports:
- "127.0.0.1:9100:9100"
networks:
- monitoring
grafana:
image: grafana/grafana-oss:latest
container_name: grafana
restart: unless-stopped
environment:
GF_SECURITY_ADMIN_USER: admin
GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD}
GF_USERS_ALLOW_SIGN_UP: "false"
volumes:
- grafana-data:/var/lib/grafana
- ./grafana/provisioning:/etc/grafana/provisioning:ro
ports:
- "127.0.0.1:3000:3000"
networks:
- monitoring
networks:
monitoring:
volumes:
prometheus-data:
grafana-data:
محدودکردن پورتها به 127.0.0.1 باعث میشود سرویسها مستقیماً از اینترنت در دسترس نباشند. برای مشاهدهٔ Grafana میتوانید از SSH tunnel استفاده کنید:
ssh -L 3000:127.0.0.1:3000 user@server-ip
سپس http://localhost:3000 را در مرورگر باز کنید. در محیط دائمی، Nginx یا Caddy را جلوی Grafana قرار دهید و HTTPS را فعال کنید.
رمز عبور Grafana را در فایل .env بگذارید:
GRAFANA_ADMIN_PASSWORD=replace-with-a-long-random-password
از commitکردن این فایل در مخزن Git خودداری کنید.
افزودن خودکار Prometheus به Grafana
برای اینکه پس از هر بار ساخت کانتینر مجبور به تعریف دستی data source نباشید، فایل grafana/provisioning/datasources/prometheus.yml را بسازید:
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
editable: false
یک فایل اولیه برای قوانین هشدار نیز ایجاد کنید تا mount مربوط به آن معتبر باشد:
touch prometheus/alerts.yml
اکنون سرویسها را بالا بیاورید:
docker compose up -d
docker compose ps
لاگها را برای خطاهای احتمالی بررسی کنید:
docker compose logs --tail=100 prometheus
docker compose logs --tail=100 node-exporter
docker compose logs --tail=100 grafana

بررسی جمعآوری داده و ساخت داشبورد اول
ابتدا در رابط Prometheus به بخش Status > Targets بروید. وضعیت هدفهای prometheus و linux-servers باید UP باشد. با SSH tunnel جداگانه میتوانید رابط Prometheus را باز کنید:
ssh -L 9090:127.0.0.1:9090 user@server-ip
برای آزمایش، پرسوجوهای زیر را در Prometheus اجرا کنید:
up
100 - (
avg by (instance) (
rate(node_cpu_seconds_total{mode="idle"}[5m])
) * 100
)
پرسوجوی دوم درصد تقریبی مصرف CPU را برای هر سرور نشان میدهد. برای محاسبهٔ درصد حافظهٔ مصرفشده میتوان از این عبارت استفاده کرد:
100 * (
1 - (
node_memory_MemAvailable_bytes
/
node_memory_MemTotal_bytes
)
)
در Grafana وارد بخش ساخت داشبورد شوید، یک visualization اضافه کنید و data source را روی Prometheus قرار دهید. یکی از پرسوجوهای بالا را وارد کنید و نوع نمایش را Time series یا Gauge بگذارید.
برای رسیدن سریعتر به یک داشبورد کامل، میتوانید داشبوردهای آمادهٔ Node Exporter را از کاتالوگ Grafana وارد کنید. قبل از استفاده در محیط تولید، پرسوجوها، متغیرها و شناسهٔ job داشبورد را با پیکربندی خود تطبیق دهید؛ هر داشبورد عمومی لزوماً با نام برچسبها و نسخهٔ exporter شما سازگار نیست.
مانیتورینگ چند سرور
در معماری چندسروری معمولاً Prometheus و Grafana فقط روی سرور مانیتورینگ اجرا میشوند و Node Exporter روی هر ماشین مقصد قرار میگیرد. در این حالت، پورت 9100 هر سرور باید فقط برای IP خصوصی سرور Prometheus مجاز باشد. اگر UFW فعال است، روی سرور مقصد میتوانید دسترسی را محدود کنید:
sudo ufw allow from 10.10.0.5 to any port 9100 proto tcp
در این مثال 10.10.0.5 آدرس خصوصی سرور Prometheus است. اگر شبکهٔ خصوصی ندارید، از VPNهایی مانند WireGuard استفاده کنید. قراردادن Node Exporter پشت نام کاربری و رمز عبور بهتنهایی جای شبکهٔ محدودشده و TLS را نمیگیرد.
برای نصب Node Exporter روی میزبانهای دیگر، میتوانید همان سرویس Compose را در یک فایل مستقل اجرا کنید. سپس IP خصوصی آن ماشین را به targets در prometheus.yml اضافه کرده و Prometheus را reload کنید:
docker kill --signal=SIGHUP prometheus
پس از reload دوباره صفحهٔ Targets را بررسی کنید.
تعریف هشدار برای قطعی و کمبود فضای دیسک
فایل prometheus/alerts.yml را به شکل زیر تکمیل کنید:
groups:
- name: server-health
rules:
- alert: ServerTargetDown
expr: up{job="linux-servers"} == 0
for: 2m
labels:
severity: critical
annotations:
summary: "دسترسی Prometheus به سرور قطع شده است"
description: "هدف {{ $labels.instance }} بیش از دو دقیقه در دسترس نیست."
- alert: DiskSpaceLow
expr: |
(
node_filesystem_avail_bytes{
fstype!~"tmpfs|overlay|squashfs"
}
/
node_filesystem_size_bytes{
fstype!~"tmpfs|overlay|squashfs"
}
) * 100 < 15
for: 10m
labels:
severity: warning
annotations:
summary: "فضای آزاد دیسک کمتر از ۱۵ درصد است"
description: "فضای فایلسیستم {{ $labels.mountpoint }} روی {{ $labels.instance }} رو به پایان است."
فایل قوانین را اعتبارسنجی کنید:
docker exec prometheus \
promtool check rules /etc/prometheus/alerts.yml
سپس Prometheus را reload کنید. وضعیت قوانین در بخش Alerts قابل مشاهده است. این قوانین فقط هشدار را در Prometheus فعال میکنند؛ برای ارسال پیام باید Alertmanager را به استک اضافه و مقصد اعلان را تنظیم کنید.
آستانهها را متناسب با رفتار واقعی سرویس انتخاب کنید. هشدار CPU با عبور لحظهای از ۸۰ درصد معمولاً نویز زیادی تولید میکند. استفاده از شرط زمانی مانند for: 10m کمک میکند فقط وضعیت پایدار گزارش شود.
نگهداری، امنیت و پشتیبانگیری
دادههای Prometheus با گزینهٔ retention.time در نمونهٔ بالا برای ۳۰ روز نگه داشته میشوند. اگر فضای دیسک محدود است، این بازه را کاهش دهید یا سقف حجمی تعیین کنید. فضای volume را مرتب بررسی کنید:
docker system df -v
docker exec prometheus du -sh /prometheus
برای پشتیبانگیری، تنظیمات Compose، فایلهای Prometheus و provisioning گرافانا را نگه دارید. داشبوردهایی که فقط از رابط Grafana ساخته شدهاند در volume گرافانا قرار دارند؛ آنها را به JSON صادر کنید یا provisioning داشبورد را به پروژه بیفزایید.
چند اقدام ضروری دیگر عبارتاند از:
- imageها را با نسخهٔ مشخص pin و ارتقا را ابتدا در محیط آزمایشی بررسی کنید.
- Grafana را پشت HTTPS قرار دهید و ثبتنام عمومی را غیرفعال نگه دارید.
- دسترسی مدیر Grafana را محدود و رمز اولیه را تعویض کنید؛ برای سختکردن کل سرور نیز میتوانید از راهنمای افزایش امنیت سرور لینوکس کمک بگیرید.
- برای دیسک خود سامانهٔ مانیتورینگ نیز هشدار بسازید.
- فایل .env و اطلاعات webhook را وارد Git نکنید.
- بعد از هر تغییر، targets، قوانین هشدار و لاگ کانتینرها را بررسی کنید.
خطاهای رایج
اگر target در وضعیت DOWN است، از داخل کانتینر Prometheus اتصال را بررسی کنید:
docker exec prometheus \
wget -qO- http://node-exporter:9100/metrics | head
خطای connection refused معمولاً به اجرا نبودن exporter، اشتباهبودن آدرس یا بستهبودن پورت مربوط است. خطای timeout بیشتر به فایروال، route شبکه یا آدرس خصوصی اشتباه اشاره دارد.
اگر Grafana دادهای نشان نمیدهد، ابتدا در Explore عبارت up را اجرا کنید. نبودن نتیجه در این بخش معمولاً مشکل data source یا Prometheus است؛ وجود نتیجه همراه با پنل خالی، بیشتر از ناسازگاری query یا متغیرهای داشبورد میآید.
اگر Prometheus پیوسته restart میشود، لاگ آن و نتیجهٔ promtool را ببینید. تورفتگی اشتباه YAML و mountشدن فایل در مسیر نادرست از علتهای پرتکرار هستند.
انتخاب سرور مناسب برای استک مانیتورینگ
برای چند ماشین و حجم متعارف معیارها، یک VPS با دیسک SSD معمولاً کافی است. اگر قرار است دادههای تعداد زیادی سرور را با retention طولانی ذخیره کنید، سرعت و ظرفیت دیسک اهمیت بیشتری پیدا میکند. در زیرساختهای بزرگتر نیز میتوان Prometheus را با راهکارهای ذخیرهسازی بلندمدت یا معماری توزیعشده تکمیل کرد. برای شروع یک نود مانیتورینگ مستقل، میتوانید مشخصات سرور مجازی ابری آریاسرویس را بررسی کنید. اندازهٔ پلن را بر اساس تعداد targetها، مدت نگهداری داده و نرخ رشد مصرف دیسک انتخاب کنید.
جمعبندی
با اجرای Node Exporter، Prometheus و Grafana یک مسیر کامل از جمعآوری معیار تا نمایش داشبورد در اختیار دارید. راهاندازی اولیه پایان کار نیست: محدودکردن دسترسی شبکه، تنظیم retention، تعریف هشدارهای کمنویز، پشتیبانگیری از داشبوردها و کنترل رشد دیسک برای استفادهٔ پایدار ضروریاند. کار را با معیارهای اصلی CPU، حافظه، دیسک و شبکه شروع کنید. پس از شناخت رفتار عادی سرورها، هشدارها و exporterهای بیشتر را مرحلهبهمرحله اضافه کنید. این رویکرد هم عیبیابی را سادهتر میکند و هم مانع تبدیل سامانهٔ هشدار به مجموعهای از اعلانهای بیاستفاده میشود.
معیارها فقط نیمی از تصویر مانیتورینگ را نشان میدهند؛ برای بررسی علت دقیق یک خطا معمولاً به لاگ هم نیاز دارید. در این باره راهاندازی سیستم لاگ متمرکز با Grafana Loki و Alloy را بخوانید.




