مانیتورینگ سطح: متوسط

مانیتورینگ Kubernetes با Prometheus و Grafana؛ از نصب تا داشبورد Production

راه‌اندازی kube-prometheus-stack با Helm، مانیتور کردن سرویس‌های خودتان با ServiceMonitor، کوئری‌های PromQL کاربردی و داشبوردهایی که واقعاً به کار می‌آیند.

۴ دقیقه مطالعه

کلاستری که مانیتور نمی‌شود، کلاستری است که مشکلاتش را اول مشتری‌ها می‌فهمند. در پروژه‌هایی که روی آن‌ها کار کرده‌ام، راه‌اندازی درست Prometheus و Grafana یکی از دلایل اصلی رسیدن به پایداری ۹۹٫۹۵٪ و کاهش ۴۰ درصدی خطاهای Deployment بود؛ چون تیم قبل از کاربران متوجه مشکل می‌شد.

اجزای Stack

جزء وظیفه
Prometheus جمع‌آوری و ذخیره‌ی متریک‌ها به‌صورت Time Series
Alertmanager دریافت Alertها، گروه‌بندی و ارسال به Mattermost، ایمیل یا تلگرام
Grafana داشبورد و نمایش بصری
node-exporter متریک‌های سخت‌افزار و سیستم‌عامل هر Node
kube-state-metrics وضعیت اشیای Kubernetes: Podها، Deploymentها، Jobها و…
Prometheus Operator مدیریت همه‌ی موارد بالا با CRDها (ServiceMonitor، PrometheusRule)

همه‌ی این‌ها در یک Helm Chart به اسم kube-prometheus-stack بسته‌بندی شده‌اند.

نصب با Helm

اول یک فایل values.yaml برای تنظیمات Production بسازید:

prometheus:
  prometheusSpec:
    retention: 15d
    retentionSize: 45GB
    resources:
      requests: { cpu: 500m, memory: 2Gi }
      limits: { memory: 4Gi }
    storageSpec:
      volumeClaimTemplate:
        spec:
          accessModes: [ReadWriteOnce]
          resources:
            requests: { storage: 50Gi }
    # pick up ServiceMonitors from every namespace, not only this release
    serviceMonitorSelectorNilUsesHelmValues: false
    ruleSelectorNilUsesHelmValues: false

grafana:
  adminPassword: change-me
  ingress:
    enabled: true
    hosts: [grafana.example.ir]
  persistence:
    enabled: true
    size: 10Gi

alertmanager:
  alertmanagerSpec:
    storage:
      volumeClaimTemplate:
        spec:
          resources:
            requests: { storage: 5Gi }
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm upgrade --install monitoring prometheus-community/kube-prometheus-stack \
  -n monitoring --create-namespace -f values.yaml

مانیتور کردن سرویس‌های خودتان

سرویس شما باید متریک‌ها را روی یک Endpoint مثل /metrics در فرمت Prometheus منتشر کند. برای .NET کتابخانه‌ی prometheus-net.AspNetCore یا OpenTelemetry، برای Node.js prom-client، برای Go و Java هم کتابخانه‌های رسمی وجود دارد.

بعد یک ServiceMonitor تعریف کنید:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: api
  namespace: production
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: api
  endpoints:
    - port: http          # the *name* of the port in the Service
      path: /metrics
      interval: 30s

کوئری‌هایی که هر روز استفاده می‌کنم

برای سرویس‌ها از روش RED استفاده کنید (Rate، Errors، Duration):

# Requests per second, per service
sum by (service) (rate(http_requests_total[5m]))

# Error ratio (5xx) in percent
100 * sum(rate(http_requests_total{status=~"5.."}[5m]))
    / sum(rate(http_requests_total[5m]))

# p95 latency from a histogram
histogram_quantile(0.95,
  sum by (le, service) (rate(http_request_duration_seconds_bucket[5m])))

برای زیرساخت از روش USE استفاده کنید (Utilization، Saturation، Errors):

# CPU usage of each pod vs. its request
sum by (pod) (rate(container_cpu_usage_seconds_total{container!=""}[5m]))
  / sum by (pod) (kube_pod_container_resource_requests{resource="cpu"})

# Pods restarting in the last hour
increase(kube_pod_container_status_restarts_total[1h]) > 0

# Disk that will be full within 24 hours
predict_linear(node_filesystem_avail_bytes{fstype!~"tmpfs"}[6h], 24 * 3600) < 0

داشبوردهایی که ارزش دارند

kube-prometheus-stack ده‌ها داشبورد آماده نصب می‌کند. پیشنهاد من این ساختار سه‌لایه است:

  1. داشبورد سرویس (برای تیم توسعه): RPS، درصد خطا، p95 و تعداد Podهای Ready. یک داشبورد با متغیر service برای همه‌ی میکروسرویس‌ها.
  2. داشبورد کلاستر (برای تیم DevOps): مصرف CPU و Memory نسبت به Request و Limit، Podهای Pending و Nodeهای NotReady.
  3. داشبورد کسب‌وکار (برای مدیران): تعداد تراکنش موفق، زمان پاسخ درگاه پرداخت و SLA ماهانه.

برای متریک‌های Node، داشبورد معروف Node Exporter Full (شناسه‌ی 1860 در Grafana.com) نقطه‌ی شروع خوبی است.

برنامه‌ریزی برای Storage

Prometheus برای نگهداری طولانی‌مدت ساخته نشده است. چند قاعده‌ی سرانگشتی:

  • هر Time Series فعال تقریباً ۱ تا ۲ بایت در هر نمونه فضا می‌گیرد. با ۵۰۰ هزار Series و Scrape هر ۳۰ ثانیه، روزانه چند گیگابایت داده خواهید داشت.
  • Cardinality دشمن اصلی است. Labelهایی مثل user_id یا request_id را هرگز روی متریک نگذارید.
  • اگر به نگهداری ماه‌ها داده نیاز دارید، سراغ Thanos یا VictoriaMetrics بروید و Prometheus را روی Retention کوتاه نگه دارید.

جمع‌بندی

مانیتورینگ خوب یعنی بتوانید در کمتر از یک دقیقه به این سؤال جواب بدهید: «الان چه چیزی خراب است و از کی؟» با kube-prometheus-stack، ServiceMonitor برای هر سرویس و چند داشبورد درست طراحی‌شده به این نقطه می‌رسید. قدم بعدی، Alertهایی است که به‌جای سروصدا اطلاعات مفید بدهند. این موضوع مقاله‌ی بعدی است.