Grafana چیست؟ ساخت داشبورد مانیتورینگ با Prometheus و Docker Compose

در این آموزش عملی Grafana و Prometheus را با Docker Compose اجرا می‌کنید، داده‌منبع را به‌صورت خودکار می‌سازید، نخستین داشبورد و Query را ایجاد می‌کنید و نکات امنیت و نگهداری را می‌آموزید.

وقتی یک سرویس کند می‌شود، پاسخ‌هایی مثل «CPU بالا بود» یا «احتمالاً Database مشکل داشت» برای تصمیم‌گیری کافی نیست. باید بتوانیم مصرف منابع، نرخ درخواست، خطا و زمان پاسخ را در یک بازه زمانی ببینیم و تغییرها را با رخدادهای واقعی مقایسه کنیم. همین داده‌ها را از سامانه‌های ذخیره‌سازی می‌خواند و در Dashboardهای قابل فهم نمایش می‌دهد.

در این راهنما یک آزمایشگاه محلی می‌سازیم: متریک‌های خودش را جمع‌آوری می‌کند، آن را به‌عنوان Data Source می‌شناسد و ما با یک Panel می‌سازیم. همه سرویس‌ها با اجرا می‌شوند و تنظیمات مهم به‌صورت فایل نگهداری می‌شوند تا نتیجه قابل تکرار باشد.

چیست و چه کاری انجام نمی‌دهد؟

یک پلتفرم Visualization و Observability است. این ابزار به Data Sourceهایی مانند ، Loki، Tempo، PostgreSQL و منابع دیگر متصل می‌شود، Query را اجرا می‌کند و نتیجه را در Panel، Dashboard یا Alert نمایش می‌دهد. به‌طور معمول محل اصلی تولید یا ذخیره متریک نیست؛ در سناریوی این مقاله متریک را Scrape و نگهداری می‌کند.

این جداسازی مهم است: اگر Dashboard خالی است، مشکل ممکن است در Exporter، تنظیم Scrape، خود ، شبکه میان کانتینرها، Data Source یا Query باشد. شناخت مسیر داده باعث می‌شود به‌جای تغییر تصادفی تنظیمات، مرحله خراب را پیدا کنید.

مسیر یک متریک تا داشبورد

  1. برنامه یا Exporter یک endpoint متریک ارائه می‌کند.
  2. طبق فایل تنظیمات endpoint را در فاصله زمانی مشخص Scrape می‌کند.
  3. با URL داخلی شبکه Docker به Query می‌زند.
  4. Panel نتیجه را به نمودار، Gauge یا جدول تبدیل می‌کند.
  5. Alert Rule می‌تواند وضعیت Query را ارزیابی و Notification تولید کند.

تفاوت ، ، Loki و Tempo

ابزارداده اصلینقش در معماری
Query و Visualizationداشبورد، Explore و Alerting روی Data Sourceها
Metrics زمان‌محورScrape، ذخیره و Query با
LokiLogگردآوری و جست‌وجوی Log با Label
TempoTrace توزیع‌شدهردیابی مسیر درخواست میان سرویس‌ها

برای شروع لازم نیست همه اجزا را هم‌زمان نصب کنید. ابتدا متریک و داشبورد را درست کنید؛ سپس در صورت نیاز Log و Trace را اضافه کنید. معماری کوچک‌تر، عیب‌یابی و کنترل هزینه نگهداری را ساده‌تر می‌کند.

پیش‌نیازهای آزمایشگاه

  • Docker Engine یا Docker Desktop با Compose Plugin
  • حداقل دو گیگابایت حافظه آزاد برای یک آزمایش کوچک
  • Portهای محلی 3000 و 9090 آزاد
  • یک پوشه پروژه با زیرپوشه‌های prometheus و grafana/provisioning/datasources

نسخه Imageها را برای محیط قابل تکرار Pin کنید و پیش از Production نسخه پشتیبانی‌شده را از مستندات رسمی بررسی کنید. استفاده از Tag شناور در تمرین سریع است، اما تغییر ناگهانی نسخه می‌تواند نتیجه اجرای بعدی را متفاوت کند.

فایل برای و

فایل زیر دو سرویس را در یک شبکه داخلی Compose اجرا می‌کند. Volumeهای نام‌دار، داده و را پس از Restart نگه می‌دارند. Portها فقط برای دسترسی محلی Bind شده‌اند تا سرویس آزمایشی ناخواسته روی همه Interfaceهای میزبان منتشر نشود.

compose.yamlYAML
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:
UTF-8YAML

شماره نسخه‌های نمونه باید هنگام اجرا با نسخه Stable مورد تأیید مستندات جایگزین شوند. نکته کلیدی ساختار است: داده‌ها داخل Volume قرار دارند و Provisioning فقط‌خواندنی Mount شده است. اگر Container حذف شود، Volume حذف نمی‌شود مگر اینکه صریحاً آن را پاک کنید.

تنظیم برای Scrape

می‌تواند متریک‌های داخلی خودش را از endpoint محلی جمع‌آوری کند. این هدف برای اطمینان از سالم‌بودن زنجیره کافی است و بعداً می‌توانید Node Exporter یا endpoint برنامه خود را اضافه کنید.

.ymlYAML
global:  scrape_interval: 15s  evaluation_interval: 15s scrape_configs:  - job_name: prometheus    static_configs:      - targets:          - prometheus:9090
UTF-8YAML

در شبکه Compose، نام سرویس prometheus نقش DNS داخلی را دارد. استفاده از localhost:9090 داخل Container اشتباه است، چون localhost به همان Container اشاره می‌کند، نه Container .

Provisioning خودکار Data Source در

می‌توانید Data Source را از رابط کاربری بسازید، اما فایل Provisioning نتیجه را نسخه‌پذیر و قابل تکرار می‌کند. فایل زیر را در مسیر grafana/provisioning/datasources/prometheus.yml قرار دهید.

.ymlYAML
apiVersion: 1 datasources:  - name: Prometheus    uid: prometheus    type: prometheus    access: proxy    url: http://prometheus:9090    isDefault: true    editable: false    jsonData:      httpMethod: POST      timeInterval: 15s
UTF-8YAML

وقتی Data Source با Provisioning ساخته شود، تغییر آن از UI محدود است و فایل منبع حقیقت خواهد بود. مقدار timeInterval را با Scrape Interval واقعی هماهنگ کنید؛ ناهماهنگی می‌تواند Queryهای مبتنی بر rate() را کم‌داده یا خالی نشان دهد.

اجرای سرویس‌ها و بررسی سلامت

start-monitoring.shBash
docker compose configdocker compose pulldocker compose up -ddocker compose psdocker compose logs --tail=100 grafanadocker compose logs --tail=100 prometheus
UTF-8Bash

ابتدا http://127.0.0.1:9090/targets را باز کنید و مطمئن شوید Target پرومتئوس UP است. سپس به http://127.0.0.1:3000 بروید. در نخستین ورود، Credential پیش‌فرض را فوراً تغییر دهید و آن را در فایل Compose یا مخزن ثبت نکنید.

ساخت نخستین Dashboard و Panel

  1. از منوی Dashboards گزینه New dashboard و سپس Add visualization را انتخاب کنید.
  2. Data Source با نام را برگزینید.
  3. در Query Editor، حالت Code را انتخاب و عبارت rate(prometheus_http_requests_total[5m]) را وارد کنید.
  4. Visualization را روی Time series قرار دهید و بازه زمانی مناسب را انتخاب کنید.
  5. برای Panel عنوان روشن، واحد مناسب و توضیح کوتاه بنویسید.
  6. Dashboard را با نامی شامل سرویس و محیط ذخیره کنید.
requests.
sum (  rate(prometheus_http_requests_total[5m])) by (code)
UTF-8

این Query نرخ درخواست‌های HTTP داخلی را بر اساس Status Code نمایش می‌دهد. برای Counterها معمولاً مقدار خام کافی نیست؛ تابع rate() سرعت تغییر در یک بازه را محاسبه می‌کند. بازه پنج دقیقه‌ای باید حداقل چند نمونه Scrape را در خود داشته باشد.

Dashboard خوب چه ویژگی‌هایی دارد؟

  • هر Panel به یک پرسش عملی پاسخ می‌دهد، نه اینکه صرفاً نموداری زیبا باشد.
  • واحد، Legend و Threshold خوانا هستند و نام محیط مشخص است.
  • نرخ خطا، Latency و Traffic کنار نشانه‌های مصرف منابع دیده می‌شوند.
  • بازه زمانی و Refresh Interval با ماهیت سرویس هماهنگ است.
  • متغیرها امکان انتخاب سرویس، Instance یا محیط را بدون کپی Dashboard می‌دهند.

Alert چه زمانی ارزش دارد؟

هر نمودار نباید Alert داشته باشد. Alert خوب نشانه‌ای قابل اقدام را تشخیص می‌دهد، مالک مشخص دارد و Runbook آن معلوم است. برای مثال، بالا رفتن کوتاه CPU بدون اثر کاربری شاید هشدار مناسبی نباشد؛ اما نسبت خطای پایدار همراه با افت درخواست موفق می‌تواند نیازمند بررسی فوری باشد.

در Alerting، Query و Condition ارزیابی می‌شوند و در صورت تغییر State، Notification Policy مسیر ارسال را تعیین می‌کند. قبل از Production حالت‌های No Data و Error، مدت Pending، گروه‌بندی هشدارها و جلوگیری از Alert Storm را آزمایش کنید.

امنیت در محیط واقعی

  • 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 را بخوانید.

از طریق Data Source می‌تواند به داده‌های حساس دسترسی پیدا کند. کاربری که اجازه Query روی Data Source دارد ممکن است بیش از آنچه Dashboard نشان می‌دهد داده ببیند؛ بنابراین Permission داشبورد به‌تنهایی جای کنترل دسترسی Data Source را نمی‌گیرد.

عیب‌یابی مشکلات رایج

نشانهعلت محتملبررسی پیشنهادی
Data Source وصل نمی‌شوداستفاده از localhost داخل ContainerURL را به http://:9090 تغییر دهید
Dashboard خالی استTarget پایین یا بازه زمانی نامناسبصفحه Targets و Time Range را بررسی کنید
rate داده نداردبازه کوچک‌تر از فاصله نمونه‌هاScrape Interval و Range Vector را هماهنگ کنید
داده پس از حذف Container از بین رفتVolume پایدار متصل نبوده استMount و فهرست Volumeها را بررسی کنید
Provisioning اعمال نمی‌شودمسیر Mount یا YAML نادرستLog آغاز و فایل Compose را ببینید
مصرف Storage زیاد استRetention یا Cardinality بالاLabelها و سیاست نگهداری را بازبینی کنید

چه زمانی از این آزمایشگاه عبور کنیم؟

این Compose برای یادگیری و یک محیط محلی مناسب است، اما Production به معماری پایدارتر نیاز دارد: High Availability، Storage و Retention برنامه‌ریزی‌شده، Backup، TLS، SSO، مدیریت Secret، کنترل دسترسی، خود سامانه و مسیر ارتقای آزمایش‌شده. برای شناخت استقرار کلاستری، راهنمای Kubernetes و Minikube را بخوانید. برای الگوی ساده‌تر یک سرویس کانتینری نیز نصب امن n8n با Docker Compose مفید است.

چک‌لیست پایان تمرین

  1. هر دو Container در خروجی Compose وضعیت Running دارند.
  2. Target پرومتئوس UP است و Query ساده نتیجه می‌دهد.
  3. Data Source در از فایل Provisioning ساخته شده است.
  4. Dashboard پس از Restart Container باقی می‌ماند.
  5. Panel نرخ درخواست را در بازه زمانی درست نمایش می‌دهد.
  6. Portها فقط روی Loopback میزبان Bind شده‌اند.
  7. Credential پیش‌فرض تغییر کرده و Secret داخل Git نیست.
  8. نسخه Imageها مشخص و مسیر Backup Volumeها مستند شده است.

جمع‌بندی

به داده خام معنا و قابلیت مشاهده می‌دهد، اما نتیجه سالم به کل زنجیره وابسته است: Export، Scrape، Storage، Data Source، Query و Visualization. با آزمایشگاه این مقاله می‌توانید این مسیر را در مقیاس کوچک ببینید و قبل از افزودن Loki، Tempo یا Alertهای پیچیده، مبانی را درست کنید.

همین امروز Stack محلی را اجرا کن، یک Panel بر پایه نرخ درخواست بساز و با Restart کانتینرها ماندگاری Dashboard و داده را آزمایش کن.

منابع رسمی