Skip to content

Giới Thiệu Prometheus & Grafana trên Kubernetes

👁️ Góc nhìn DevOps Lead - Observability Specialist

Module này được viết từ góc nhìn của DevOps Lead chuyên về Observability tại HPN. Mục tiêu: "You can't fix what you can't see" - Không thể sửa những gì bạn không nhìn thấy.

🎯 Tại Sao Cần Observability?

text
[SRE On-Call - 2:00 AM]
🚨 Alert: Response time spiked to 5 seconds!
❓ Câu hỏi: Vấn đề ở đâu?
   - Database chậm?
   - CPU/Memory thiếu?
   - Network issue?
   - Application bug?

Không có Observability = "Đoán mò" 🎲
Có Observability = "Nhìn thẳng vào vấn đề" 🎯

Ba trụ cột của Observability:

Trụ cộtCông cụTrả lời câu hỏi
MetricsPrometheus"Hệ thống đang như thế nào?" (CPU, Memory, RPS)
LogsLoki / EFK"Chuyện gì đã xảy ra?" (Error messages)
TracesJaeger / Tempo"Request đi qua đâu?" (Distributed tracing)

🏗️ Kiến Trúc Prometheus: Pull Model

💡 ĐIỂM KHÁC BIỆT QUAN TRỌNG

Traditional Monitoring (Push Model):

  • Agents trên mỗi server ĐẨY metrics đến central server
  • Vấn đề: Central server có thể bị overwhelm

Prometheus (Pull Model):

  • Prometheus KÉO (scrape) metrics từ targets
  • Targets expose metrics tại endpoint /metrics

Kiến trúc tổng quan

Các thành phần chính

ComponentVai tròMetrics cung cấp
Prometheus ServerThu thập & lưu trữ metricsTime-series database (TSDB)
Node ExporterMetrics từ hardware/OSCPU, Memory, Disk, Network của node
kube-state-metricsMetrics từ K8s objectsPod status, Deployment replicas, etc.
AlertmanagerXử lý alertsGửi notification (Slack, Email, PagerDuty)
GrafanaVisualizationDashboards, Graphs, Panels

📡 Exporters: Nguồn Cung Cấp Metrics

Node Exporter (Hardware Metrics)

Chạy như DaemonSet trên mỗi node, thu thập metrics về:

  • CPU usage per core
  • Memory usage (used, free, cached)
  • Disk I/O, Disk space
  • Network throughput
yaml
# Được cài tự động với kube-prometheus-stack
# Xem metrics tại: http://node-exporter:9100/metrics

# Ví dụ metrics:
node_cpu_seconds_total{cpu="0",mode="idle"} 123456.78
node_memory_MemTotal_bytes 16777216000
node_filesystem_avail_bytes{mountpoint="/"} 50000000000

kube-state-metrics (Cluster Metrics)

Thu thập metrics từ Kubernetes API về trạng thái các objects:

yaml
# Ví dụ metrics:
kube_deployment_status_replicas_available{deployment="myapp"} 3
kube_pod_status_phase{pod="myapp-xxx", phase="Running"} 1
kube_node_status_condition{node="worker-1", condition="Ready"} 1

Application Exporters (Custom Metrics)

Ứng dụng của bạn cần expose /metrics endpoint:

python
# Python với prometheus_client
from prometheus_client import Counter, Histogram, start_http_server

REQUEST_COUNT = Counter('http_requests_total', 'Total HTTP Requests', ['method', 'endpoint'])
REQUEST_LATENCY = Histogram('http_request_duration_seconds', 'Request latency')

@app.route('/api/orders')
def orders():
    REQUEST_COUNT.labels(method='GET', endpoint='/api/orders').inc()
    with REQUEST_LATENCY.time():
        return handle_orders()

# Expose metrics at :8000/metrics
start_http_server(8000)
java
// Java với Micrometer (Spring Boot)
// application.yml
management:
  endpoints:
    web:
      exposure:
        include: prometheus
  metrics:
    export:
      prometheus:
        enabled: true

📊 PromQL: Ngôn Ngữ Truy Vấn

💡 PromQL là gì?

Prometheus Query Language - ngôn ngữ để query và aggregate metrics từ Prometheus.

Query cơ bản: rate()

promql
# ❓ Câu hỏi: CPU đang được sử dụng bao nhiêu?

# Raw metric (không hữu ích lắm - chỉ là counter tăng dần)
container_cpu_usage_seconds_total

# ✅ Với rate() - tính TỐC ĐỘ THAY ĐỔI trong 5 phút
rate(container_cpu_usage_seconds_total[5m])

rate() làm gì?

text
Time 0:00 → container_cpu_usage_seconds_total = 1000s
Time 5:00 → container_cpu_usage_seconds_total = 1300s

rate() = (1300 - 1000) / 300 seconds = 1 CPU core

Ý nghĩa: Container đang sử dụng 1 CPU core (100% của 1 core)

Các query hữu ích khác

promql
# 📈 CPU usage theo namespace
sum(rate(container_cpu_usage_seconds_total[5m])) by (namespace)

# 💾 Memory usage hiện tại
sum(container_memory_usage_bytes) by (pod)

# 🚀 Request rate (RPS)
sum(rate(http_requests_total[5m])) by (service)

# ❌ Error rate (%)
sum(rate(http_requests_total{status=~"5.."}[5m])) 
/ 
sum(rate(http_requests_total[5m])) * 100

# ⏱️ 99th percentile latency
histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))

📺 Grafana: The Face of Observability

💡 Grafana là gì?

Grafana là công cụ visualization - biến data từ Prometheus thành dashboards đẹp và dễ hiểu.

Golden Signals Dashboard

Google SRE Book định nghĩa 4 Golden Signals - 4 metrics quan trọng nhất để monitor:

SignalMô tảPromQL Example
LatencyThời gian xử lý requesthistogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m]))
TrafficSố lượng requestssum(rate(http_requests_total[5m]))
ErrorsTỷ lệ lỗisum(rate(http_requests_total{status=~"5.."}[5m])) / sum(rate(http_requests_total[5m]))
SaturationMức độ "đầy" của resourcescontainer_memory_usage_bytes / container_spec_memory_limit_bytes

Pre-built Dashboards

Grafana có hàng ngàn dashboards được cộng đồng tạo sẵn:

Dashboard IDTênMục đích
315Kubernetes Cluster MonitoringOverview toàn cluster
6417Kubernetes PodsDetail từng pod
1860Node Exporter FullHardware metrics
7249Kubernetes API ServerControl plane health

Import dashboard:

  1. Vào Grafana → Dashboards → Import
  2. Nhập Dashboard ID (vd: 315)
  3. Chọn Prometheus datasource
  4. Done! 🎉

📝 Logging: Đừng SSH vào Node!

🚫 ANTI-PATTERN

bash
# ❌ SAI: SSH vào từng node để đọc logs
ssh node-1
docker logs container-xxx
cat /var/log/...

# Vấn đề:
# - Không scale (10 nodes = 10 lần SSH?)
# - Container restart = logs mất
# - Không thể search cross-service

Centralized Logging Solutions

StackComponentsĐặc điểm
EFKElasticsearch + Fluentd + KibanaPowerful search, high resource
LokiLoki + Promtail + GrafanaLightweight, label-based, low cost
ELKElasticsearch + Logstash + KibanaEnterprise standard

Loki: The Lightweight Choice

Tại sao Loki?

  • Không index full-text (như Elasticsearch) → 10x ít storage
  • Query bằng labels (giống Prometheus) → Familiar syntax
  • Native Grafana integration → 1 dashboard for all
logql
# LogQL query example
{namespace="production", app="myapp"} |= "error" | json | status >= 500

🚀 Cài Đặt: kube-prometheus-stack

📦 KHUYẾN NGHỊ

Dùng kube-prometheus-stack Helm chart - đã được pre-configured với:

  • Prometheus Server
  • Alertmanager
  • Grafana (với nhiều dashboards sẵn)
  • Node Exporter
  • kube-state-metrics

Quick Install

bash
# Thêm Helm repo
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

# Cài đặt full stack
helm install kube-prometheus prometheus-community/kube-prometheus-stack \
  --namespace monitoring \
  --create-namespace \
  --set grafana.adminPassword=admin123

# Kiểm tra
kubectl get pods -n monitoring

Access Dashboards

bash
# Grafana (mặc định: admin/prom-operator)
kubectl port-forward -n monitoring svc/kube-prometheus-grafana 3000:80

# Prometheus UI
kubectl port-forward -n monitoring svc/kube-prometheus-prometheus 9090:9090

# Alertmanager
kubectl port-forward -n monitoring svc/kube-prometheus-alertmanager 9093:9093

📊 Tổng Kết

Khái niệmMô tả
Pull ModelPrometheus scrape metrics từ targets
ExportersNguồn cung cấp metrics (Node, kube-state, App)
PromQLNgôn ngữ query (rate, sum, histogram_quantile)
Golden SignalsLatency, Traffic, Errors, Saturation
GrafanaVisualization & Dashboards
LokiLightweight centralized logging

⚠️ NHỮNG ĐIỀU CẦN NHỚ

  1. Metrics ≠ Logs - Metrics cho "how much", Logs cho "what happened"
  2. Pull model - Prometheus kéo data, không phải app đẩy
  3. Labels are powerful - Filter, aggregate, group by labels
  4. Don't reinvent - Dùng kube-prometheus-stack đã có sẵn
  5. Golden Signals - Bắt đầu với 4 metrics cơ bản này

🔗 Liên kết