Grafana چیست؟ ساخت داشبورد مانیتورینگ با Prometheus و Docker Compose
در این آموزش عملی Grafana و Prometheus را با Docker Compose اجرا میکنید، دادهمنبع را بهصورت خودکار میسازید، نخستین داشبورد و Query را ایجاد میکنید و نکات امنیت و نگهداری را میآموزید.
وقتی یک سرویس کند میشود، پاسخهایی مثل «CPU بالا بود» یا «احتمالاً Database مشکل داشت» برای تصمیمگیری کافی نیست. باید بتوانیم مصرف منابع، نرخ درخواست، خطا و زمان پاسخ را در یک بازه زمانی ببینیم و تغییرها را با رخدادهای واقعی مقایسه کنیم. Grafana همین دادهها را از سامانههای ذخیرهسازی میخواند و در Dashboardهای قابل فهم نمایش میدهد.
در این راهنما یک آزمایشگاه مانیتورینگ محلی میسازیم: Prometheus متریکهای خودش را جمعآوری میکند، Grafana آن را بهعنوان Data Source میشناسد و ما با PromQL یک Panel میسازیم. همه سرویسها با Docker Compose اجرا میشوند و تنظیمات مهم بهصورت فایل نگهداری میشوند تا نتیجه قابل تکرار باشد.
Grafana چیست و چه کاری انجام نمیدهد؟
Grafana یک پلتفرم Visualization و Observability است. این ابزار به Data Sourceهایی مانند Prometheus، Loki، Tempo، PostgreSQL و منابع دیگر متصل میشود، Query را اجرا میکند و نتیجه را در Panel، Dashboard یا Alert نمایش میدهد. Grafana بهطور معمول محل اصلی تولید یا ذخیره متریک نیست؛ Prometheus در سناریوی این مقاله متریک را Scrape و نگهداری میکند.
این جداسازی مهم است: اگر Dashboard خالی است، مشکل ممکن است در Exporter، تنظیم Scrape، خود Prometheus، شبکه میان کانتینرها، Data Source یا Query باشد. شناخت مسیر داده باعث میشود بهجای تغییر تصادفی تنظیمات، مرحله خراب را پیدا کنید.
مسیر یک متریک تا داشبورد
- برنامه یا Exporter یک endpoint متریک ارائه میکند.
- Prometheus طبق فایل تنظیمات endpoint را در فاصله زمانی مشخص Scrape میکند.
- Grafana با URL داخلی شبکه Docker به Prometheus Query میزند.
- Panel نتیجه PromQL را به نمودار، Gauge یا جدول تبدیل میکند.
- Alert Rule میتواند وضعیت Query را ارزیابی و Notification تولید کند.
تفاوت Grafana، Prometheus، Loki و Tempo
| ابزار | داده اصلی | نقش در معماری |
|---|---|---|
| Grafana | Query و Visualization | داشبورد، Explore و Alerting روی Data Sourceها |
| Prometheus | Metrics زمانمحور | Scrape، ذخیره و Query با PromQL |
| Loki | Log | گردآوری و جستوجوی Log با Label |
| Tempo | Trace توزیعشده | ردیابی مسیر درخواست میان سرویسها |
برای شروع لازم نیست همه اجزا را همزمان نصب کنید. ابتدا متریک و داشبورد را درست کنید؛ سپس در صورت نیاز Log و Trace را اضافه کنید. معماری کوچکتر، عیبیابی و کنترل هزینه نگهداری را سادهتر میکند.
پیشنیازهای آزمایشگاه Docker Compose
- Docker Engine یا Docker Desktop با Compose Plugin
- حداقل دو گیگابایت حافظه آزاد برای یک آزمایش کوچک
- Portهای محلی 3000 و 9090 آزاد
- یک پوشه پروژه با زیرپوشههای
prometheusوgrafana/provisioning/datasources
نسخه Imageها را برای محیط قابل تکرار Pin کنید و پیش از Production نسخه پشتیبانیشده را از مستندات رسمی بررسی کنید. استفاده از Tag شناور در تمرین سریع است، اما تغییر ناگهانی نسخه میتواند نتیجه اجرای بعدی را متفاوت کند.
فایل Docker Compose برای Grafana و Prometheus
فایل زیر دو سرویس را در یک شبکه داخلی Compose اجرا میکند. Volumeهای نامدار، داده Grafana و Prometheus را پس از Restart نگه میدارند. Portها فقط برای دسترسی محلی Bind شدهاند تا سرویس آزمایشی ناخواسته روی همه Interfaceهای میزبان منتشر نشود.
services: prometheus: image: prom/prometheus:v3.5.0 restart: unless-stopped ports: - "127.0.0.1:9090:9090" volumes: - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro - prometheus_data:/prometheus grafana: image: grafana/grafana:13.2.0 restart: unless-stopped ports: - "127.0.0.1:3000:3000" volumes: - grafana_data:/var/lib/grafana - ./grafana/provisioning:/etc/grafana/provisioning:ro depends_on: - prometheus volumes: prometheus_data: grafana_data:شماره نسخههای نمونه باید هنگام اجرا با نسخه Stable مورد تأیید مستندات جایگزین شوند. نکته کلیدی ساختار است: دادهها داخل Volume قرار دارند و Provisioning فقطخواندنی Mount شده است. اگر Container حذف شود، Volume حذف نمیشود مگر اینکه صریحاً آن را پاک کنید.
تنظیم Prometheus برای Scrape
Prometheus میتواند متریکهای داخلی خودش را از endpoint محلی جمعآوری کند. این هدف برای اطمینان از سالمبودن زنجیره کافی است و بعداً میتوانید Node Exporter یا endpoint برنامه خود را اضافه کنید.
global: scrape_interval: 15s evaluation_interval: 15s scrape_configs: - job_name: prometheus static_configs: - targets: - prometheus:9090در شبکه Compose، نام سرویس prometheus نقش DNS داخلی را دارد. استفاده از localhost:9090 داخل Container Grafana اشتباه است، چون localhost به همان Container Grafana اشاره میکند، نه Container Prometheus.
Provisioning خودکار Data Source در Grafana
میتوانید Data Source را از رابط کاربری بسازید، اما فایل Provisioning نتیجه را نسخهپذیر و قابل تکرار میکند. فایل زیر را در مسیر grafana/provisioning/datasources/prometheus.yml قرار دهید.
apiVersion: 1 datasources: - name: Prometheus uid: prometheus type: prometheus access: proxy url: http://prometheus:9090 isDefault: true editable: false jsonData: httpMethod: POST timeInterval: 15sوقتی Data Source با Provisioning ساخته شود، تغییر آن از UI محدود است و فایل منبع حقیقت خواهد بود. مقدار timeInterval را با Scrape Interval واقعی هماهنگ کنید؛ ناهماهنگی میتواند Queryهای مبتنی بر rate() را کمداده یا خالی نشان دهد.
اجرای سرویسها و بررسی سلامت
docker compose configdocker compose pulldocker compose up -ddocker compose psdocker compose logs --tail=100 grafanadocker compose logs --tail=100 prometheusابتدا http://127.0.0.1:9090/targets را باز کنید و مطمئن شوید Target پرومتئوس UP است. سپس به http://127.0.0.1:3000 بروید. در نخستین ورود، Credential پیشفرض را فوراً تغییر دهید و آن را در فایل Compose یا مخزن ثبت نکنید.
ساخت نخستین Dashboard و Panel
- از منوی Dashboards گزینه New dashboard و سپس Add visualization را انتخاب کنید.
- Data Source با نام Prometheus را برگزینید.
- در Query Editor، حالت Code را انتخاب و عبارت
rate(prometheus_http_requests_total[5m])را وارد کنید. - Visualization را روی Time series قرار دهید و بازه زمانی مناسب را انتخاب کنید.
- برای Panel عنوان روشن، واحد مناسب و توضیح کوتاه بنویسید.
- Dashboard را با نامی شامل سرویس و محیط ذخیره کنید.
sum ( rate(prometheus_http_requests_total[5m])) by (code)این Query نرخ درخواستهای HTTP داخلی Prometheus را بر اساس Status Code نمایش میدهد. برای Counterها معمولاً مقدار خام کافی نیست؛ تابع rate() سرعت تغییر در یک بازه را محاسبه میکند. بازه پنج دقیقهای باید حداقل چند نمونه Scrape را در خود داشته باشد.
Dashboard خوب چه ویژگیهایی دارد؟
- هر Panel به یک پرسش عملی پاسخ میدهد، نه اینکه صرفاً نموداری زیبا باشد.
- واحد، Legend و Threshold خوانا هستند و نام محیط مشخص است.
- نرخ خطا، Latency و Traffic کنار نشانههای مصرف منابع دیده میشوند.
- بازه زمانی و Refresh Interval با ماهیت سرویس هماهنگ است.
- متغیرها امکان انتخاب سرویس، Instance یا محیط را بدون کپی Dashboard میدهند.
Alert چه زمانی ارزش دارد؟
هر نمودار نباید Alert داشته باشد. Alert خوب نشانهای قابل اقدام را تشخیص میدهد، مالک مشخص دارد و Runbook آن معلوم است. برای مثال، بالا رفتن کوتاه CPU بدون اثر کاربری شاید هشدار مناسبی نباشد؛ اما نسبت خطای پایدار همراه با افت درخواست موفق میتواند نیازمند بررسی فوری باشد.
در Grafana Alerting، Query و Condition ارزیابی میشوند و در صورت تغییر State، Notification Policy مسیر ارسال را تعیین میکند. قبل از Production حالتهای No Data و Error، مدت Pending، گروهبندی هشدارها و جلوگیری از Alert Storm را آزمایش کنید.
امنیت Grafana در محیط واقعی
- Port 3000 را مستقیم روی اینترنت عمومی منتشر نکنید؛ Reverse Proxy با TLS و کنترل دسترسی قرار دهید.
- Anonymous Access را فقط با نیاز روشن و حداقل Permission فعال کنید.
- Credential پیشفرض Admin را فوراً تغییر دهید و Secret را بیرون از Compose و Git نگه دارید.
- برای تیمها از SSO، Role و Folder Permission متناسب استفاده کنید.
- Data Source Credential را با Secret Store و فیلدهای امن Provisioning مدیریت کنید.
- Backup منظم Database و Pluginها را آزمایش و فرایند Restore را مستند کنید.
- نسخه Image و Pluginها را کنترلشده ارتقا دهید و Release Note را بخوانید.
Grafana از طریق Data Source میتواند به دادههای حساس دسترسی پیدا کند. کاربری که اجازه Query روی Data Source دارد ممکن است بیش از آنچه Dashboard نشان میدهد داده ببیند؛ بنابراین Permission داشبورد بهتنهایی جای کنترل دسترسی Data Source را نمیگیرد.
عیبیابی مشکلات رایج
| نشانه | علت محتمل | بررسی پیشنهادی |
|---|---|---|
| Data Source وصل نمیشود | استفاده از localhost داخل Container | URL را به http://prometheus:9090 تغییر دهید |
| Dashboard خالی است | Target پایین یا بازه زمانی نامناسب | صفحه Targets و Time Range را بررسی کنید |
| rate داده ندارد | بازه کوچکتر از فاصله نمونهها | Scrape Interval و Range Vector را هماهنگ کنید |
| داده پس از حذف Container از بین رفت | Volume پایدار متصل نبوده است | Mount و فهرست Volumeها را بررسی کنید |
| Provisioning اعمال نمیشود | مسیر Mount یا YAML نادرست | Log آغاز Grafana و فایل Compose را ببینید |
| مصرف Storage زیاد است | Retention یا Cardinality بالا | Labelها و سیاست نگهداری Prometheus را بازبینی کنید |
چه زمانی از این آزمایشگاه عبور کنیم؟
این Compose برای یادگیری و یک محیط محلی مناسب است، اما Production به معماری پایدارتر نیاز دارد: High Availability، Storage و Retention برنامهریزیشده، Backup، TLS، SSO، مدیریت Secret، کنترل دسترسی، مانیتورینگ خود سامانه و مسیر ارتقای آزمایششده. برای شناخت استقرار کلاستری، راهنمای Kubernetes و Minikube را بخوانید. برای الگوی سادهتر یک سرویس کانتینری نیز نصب امن n8n با Docker Compose مفید است.
چکلیست پایان تمرین
- هر دو Container در خروجی Compose وضعیت Running دارند.
- Target پرومتئوس UP است و Query ساده نتیجه میدهد.
- Data Source در Grafana از فایل Provisioning ساخته شده است.
- Dashboard پس از Restart Container باقی میماند.
- Panel نرخ درخواست را در بازه زمانی درست نمایش میدهد.
- Portها فقط روی Loopback میزبان Bind شدهاند.
- Credential پیشفرض تغییر کرده و Secret داخل Git نیست.
- نسخه Imageها مشخص و مسیر Backup Volumeها مستند شده است.
جمعبندی
Grafana به داده خام معنا و قابلیت مشاهده میدهد، اما نتیجه سالم به کل زنجیره وابسته است: Export، Scrape، Storage، Data Source، Query و Visualization. با آزمایشگاه این مقاله میتوانید این مسیر را در مقیاس کوچک ببینید و قبل از افزودن Loki، Tempo یا Alertهای پیچیده، مبانی را درست کنید.
همین امروز Stack محلی را اجرا کن، یک Panel بر پایه نرخ درخواست بساز و با Restart کانتینرها ماندگاری Dashboard و داده را آزمایش کن.