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à:
- Bạn không cần expose Prometheus endpoint ra ngoài cluster
- Cluster firewall chỉ cần cho phép egress HTTPS đến
monitoring.googleapis.com - 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 PodMonitoring và ClusterPodMonitoring 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:
- Collector query Kubernetes API để list Pods matching selector trong node
- HTTP GET
/metrics(hoặc path tùy chỉnh) từ Pod IP - Parse Prometheus text format
- Enrich với labels tự động:
project_id,location,cluster,namespace,job,instance - 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:
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: applicationChỉ scrape Pods trong namespace production. Bạn cần tạo PodMonitoring trong từng namespace cần monitor.
ClusterPodMonitoring — Cluster-scoped:
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: 30sScrape 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 RBACClusterPodMonitoring: 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:
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:
- 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:
# 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 complexity | Thấp — enable, tạo PodMonitoring | Cao — Prometheus operator, storage class, HA, Thanos/Cortex |
| Operations | Zero — Google quản lý | Cao — upgrade, backup, scaling, sharding |
| Data durability | Monarch HA ở GCP level | Tùy thuộc vào storage setup |
| Global query | Native, cross-cluster | Cần Thanos/Cortex federation |
| Alert routing | Qua Cloud Monitoring Alerting | Alertmanager (tự config) |
| Customization | Ít hơn (không custom storage adapter) | Toàn quyền |
| Cost | Theo metric volume ingested | Infrastructure cost (VMs, storage) |
| Vendor lock-in | Tied to GCP | Portable |
| PromQL compatibility | Không 100% — một số functions không support | 100% |
| Scrape target limit | Rấ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êm | Nguồn |
|---|---|
project_id | GCP project của cluster |
location | Region/zone của cluster |
cluster | Tên GKE cluster |
namespace | Kubernetes namespace của Pod |
job | Lấ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.