Skip to content

Managed Service for Prometheus (GMP)

Tại sao GMP tồn tại

Prometheus là tiêu chuẩn de facto cho Kubernetes metrics. Nhưng self-managed Prometheus ở production scale có nhiều vấn đề nghiêm trọng:

  • Durability: Prometheus lưu dữ liệu local trên disk — nếu Pod crash, dữ liệu mất
  • Global query scope: Prometheus chỉ thấy data trong cluster của nó. Để query cross-cluster, cần Thanos hoặc Cortex — thêm ops complexity
  • Scaling: Khi số targets tăng lên, một Prometheus instance không đủ. Horizontal sharding phức tạp
  • Operations toil: Version upgrades, config management, storage management, HA setup — tất cả đều thêm vào toil của platform team

GMP (Managed Service for Prometheus) giải quyết tất cả điều này bằng cách giữ lại Prometheus scraping model (pull-based, /metrics endpoint, PromQL) nhưng offload toàn bộ storage và query infrastructure lên Google's Monarch — hệ thống time series database nội bộ của Google vận hành ở quy mô hành tinh.

Kiến trúc bên trong của GMP

Luồng dữ liệu tổng thể

Prometheus exporter (in Pod)
        ↓ /metrics HTTP endpoint
collector DaemonSet (gmp-system namespace)
        ↓ push via gRPC
Monarch (Google's global time series DB)
        ↓ query
Cloud Monitoring API / Grafana / PromQL endpoint

Điểm quan trọng: dữ liệu đi theo hướng push từ cluster ra ngoài, không phải GCP pull vào cluster. Theo tài liệu GMP chính thức: "Google Cloud never directly accesses your cluster to pull or scrape metric data; your collectors push data to Google Cloud." Điều này có nghĩa là:

  1. Bạn không cần expose Prometheus endpoint ra ngoài cluster
  2. Cluster firewall chỉ cần cho phép egress HTTPS đến monitoring.googleapis.com
  3. Không có GCP component nào cần quyền truy cập vào cluster network

Collector DaemonSet — Thu thập trong node

Triển khai: gmp-operator (một Deployment trong gmp-system namespace) quản lý toàn bộ lifecycle của collector DaemonSet.

Kiến trúc node-local: Mỗi collector Pod trong DaemonSet chỉ scrape các target trên cùng node với nó. Đây là thiết kế có chủ đích:

  • Không có cross-node network traffic cho scraping
  • Scale tự nhiên cùng với số nodes
  • Fault isolation: collector Pod lỗi chỉ ảnh hưởng metrics của node đó

Cách collector biết target nào để scrape:

Collector đọc PodMonitoringClusterPodMonitoring CRDs từ Kubernetes API server, sau đó dùng label selectors để tìm Pods cần scrape trên node của mình. Collector không cần endpoint discovery toàn cluster — chỉ cần discovery trong node.

Quá trình scrape:

  1. Collector query Kubernetes API để list Pods matching selector trong node
  2. HTTP GET /metrics (hoặc path tùy chỉnh) từ Pod IP
  3. Parse Prometheus text format
  4. Enrich với labels tự động: project_id, location, cluster, namespace, job, instance
  5. Batch và gửi lên Monarch qua gRPC streaming

Authentication: Collector dùng Workload Identity (nếu cluster có WIF enabled) hoặc service account key để authenticate với Cloud Monitoring API khi push data.

PodMonitoring và ClusterPodMonitoring CRDs

Đây là cách bạn configure GMP để biết cần scrape gì. Đây là Kubernetes CRDs, không phải config file của Prometheus.

PodMonitoring — Namespace-scoped:

yaml
apiVersion: monitoring.googleapis.com/v1
kind: PodMonitoring
metadata:
  name: my-app-metrics
  namespace: production
spec:
  selector:
    matchLabels:
      app: my-app
  endpoints:
    - port: metrics        # tên port hoặc số port
      interval: 30s        # scrape interval
      path: /metrics       # path đến metrics endpoint
      scheme: http
  targetLabels:
    fromPod:
      - from: app          # copy pod label "app" vào metric label
        to: application

Chỉ scrape Pods trong namespace production. Bạn cần tạo PodMonitoring trong từng namespace cần monitor.

ClusterPodMonitoring — Cluster-scoped:

yaml
apiVersion: monitoring.googleapis.com/v1
kind: ClusterPodMonitoring
metadata:
  name: all-apps-metrics
spec:
  selector:
    matchLabels:
      monitoring: enabled   # label selector cross-namespace
  endpoints:
    - port: metrics
      interval: 30s

Scrape tất cả Pods có label monitoring: enabled trong mọi namespace. Yêu cầu RBAC cluster-level, thường dùng bởi platform team để monitor system components.

Khi nào dùng PodMonitoring vs ClusterPodMonitoring:

  • PodMonitoring: application teams tự monitor service của mình, không cần cluster-level RBAC
  • ClusterPodMonitoring: platform team monitor system components (kube-state-metrics, CoreDNS, DCGM GPU exporter), hoặc khi muốn một resource duy nhất cover toàn cluster

Rule Evaluator — Alerting và Recording Rules

Rule Evaluator là một Deployment riêng biệt (không phải DaemonSet) trong gmp-system namespace. Nó đảm nhận chức năng tương đương prometheus --rules.evaluation-interval nhưng query từ Monarch thay vì local Prometheus.

Hai loại rules:

Recording rules — Tính toán trước kết quả query phức tạp:

yaml
apiVersion: monitoring.googleapis.com/v1
kind: Rules
metadata:
  name: app-recording-rules
  namespace: production
spec:
  groups:
    - name: request_metrics
      interval: 60s
      rules:
        - record: job:http_requests:rate5m
          expr: sum(rate(http_requests_total[5m])) by (job)

Recording rules giảm query latency cho dashboard: thay vì recalculate rate(http_requests_total[5m]) mỗi lần dashboard refresh, kết quả được pre-compute mỗi 60 giây và lưu dưới tên metric mới.

Alerting rules — Trigger alerts:

yaml
- alert: HighErrorRate
  expr: |
    job:http_requests:rate5m{status="5xx"}
    / job:http_requests:rate5m
    > 0.05
  for: 5m
  labels:
    severity: critical
  annotations:
    summary: "High error rate on {{ $labels.job }}"

Alerting rules trong GMP được evaluate bởi Rule Evaluator, nhưng alerts được route qua Cloud Monitoring Alerting, không qua standalone Alertmanager (trừ khi bạn cấu hình managed Alertmanager).

Global Query Scope — Lợi thế lớn nhất của GMP

Prometheus thông thường chỉ thấy data trong cluster của nó. GMP lưu tất cả data vào Monarch với labels project_id, cluster, location — điều này cho phép query cross-cluster, cross-region từ một PromQL endpoint duy nhất:

promql
# Query tổng request rate từ TẤT CẢ clusters trong project
sum(rate(http_requests_total[5m])) by (cluster)

# Filter chỉ lấy production clusters
sum(rate(http_requests_total{cluster=~"prod-.*"}[5m])) by (cluster, namespace)

Đây là tính năng không có ở self-hosted Prometheus và là lý do chính tại sao GMP được adopt nhanh ở tổ chức có nhiều cluster.

PromQL query interface: GMP expose PromQL-compatible API tại https://monitoring.googleapis.com/v1/projects/{PROJECT}/location/global/prometheus. Bạn có thể dùng Grafana với Prometheus data source trỏ vào endpoint này, hoặc dùng Cloud Monitoring Query UI trong Console.

GMP vs Self-hosted Prometheus: Trade-offs thực tế

Tiêu chíGMP (Managed)Self-hosted Prometheus
Setup complexityThấp — enable, tạo PodMonitoringCao — Prometheus operator, storage class, HA, Thanos/Cortex
OperationsZero — Google quản lýCao — upgrade, backup, scaling, sharding
Data durabilityMonarch HA ở GCP levelTùy thuộc vào storage setup
Global queryNative, cross-clusterCần Thanos/Cortex federation
Alert routingQua Cloud Monitoring AlertingAlertmanager (tự config)
CustomizationÍt hơn (không custom storage adapter)Toàn quyền
CostTheo metric volume ingestedInfrastructure cost (VMs, storage)
Vendor lock-inTied to GCPPortable
PromQL compatibilityKhông 100% — một số functions không support100%
Scrape target limitRất cao (theo capacity GCP)Phụ thuộc vào instance sizing

PromQL functions không support trong GMP:

GMP không support toàn bộ PromQL spec. Một số functions như subquery syntax phức tạp, @ modifier, một số _over_time variants có thể behave khác hoặc không support. Luôn test queries trong môi trường GMP, không assume Prometheus-local query sẽ work.

Khi nào nên tự host Prometheus thay vì GMP

  • Strict data sovereignty: Data Prometheus không được rời khỏi on-premises environment
  • Multi-cloud với non-GCP primary: Nếu stack chủ yếu là AWS/Azure, GMP lock-in không phù hợp
  • Custom storage adapter: Cần long-term storage với custom backend (OpenTelemetry Collector với custom exporter)
  • Cost tối ưu: Tổ chức rất lớn với hàng trăm triệu time series có thể thấy self-hosted cheaper nếu optimized tốt
  • Prometheus ecosystem sâu: Nếu đang dùng nhiều Prometheus-native integrations (Karma, silence management) cần standalone Alertmanager

Trong hầu hết trường hợp GKE production, GMP là lựa chọn mặc định đúng.

Metric naming và label augmentation trong GMP

Khi collector scrape Prometheus metrics, nó tự động thêm các labels sau:

Label được thêmNguồn
project_idGCP project của cluster
locationRegion/zone của cluster
clusterTên GKE cluster
namespaceKubernetes namespace của Pod
jobLấy từ PodMonitoring job field
instance<Pod IP>:<port>

Các labels từ targetLabels.fromPod (định nghĩa trong PodMonitoring) cũng được copy.

Conflict handling: Nếu Prometheus exporter đã có label namespace (ví dụ), GMP rename Prometheus label thành exported_namespace để tránh conflict với resource label.

Điều này quan trọng khi migrate từ self-hosted: các query dựa trên label names có thể cần update.

Anti-patterns và failure modes

High cardinality Prometheus metrics

Một ứng dụng expose metric http_requests_total{path="/api/v1/users/<user_id>"}. Mỗi unique path với different user_id tạo một time series mới. Với 1 triệu users:

  • 1 triệu time series × rate scrape = khổng lồ
  • Cloud Monitoring bill tăng theo cardinality
  • Monarch có per-project time series limits

Phát hiện: kiểm tra số active time series với metrics monitoring.googleapis.com/billing/bytes_ingested breakdown by metric type.

Fix: dùng metricRelabeling trong PodMonitoring để replace user_id với placeholder, hoặc drop metric hoàn toàn và dùng Cloud Logging thay thế.

Scrape interval quá ngắn

Default scrape interval của Prometheus là 15s. Nếu giữ nguyên trong GMP với 1000 pods × 500 metrics:

  • 1000 × 500 = 500,000 time series
  • 4 points/phút × 43,200 phút × 500,000 = 86.4 tỉ points/tháng

Giải pháp: tăng scrape interval lên 60s cho non-critical metrics, giữ 15-30s chỉ cho RED metrics (rate, errors, duration) của services quan trọng.

Rule Evaluator CPU throttling

Rule Evaluator query Monarch mỗi evaluation interval. Với nhiều rules và complex expressions, nó có thể bị throttle hoặc timeout. Symptom: alerts không fire đúng giờ, recording rules lag behind.

Monitor: prometheus_rule_evaluation_duration_seconds từ Rule Evaluator Pod. Nếu p95 gần evaluation interval, cần optimize rules.

Tham khảo chính thức