Dynamic alert routing with Prometheus and Alertmanager

Bài tóm tắt Loveholidays 2021 3. Quy mô lớn Độ khó: Trung bình

Loveholidays · 2021 · 3. Quy mô lớn · Độ khó: Trung bình — bài gốc

Đọc toàn văn qua trình duyệt (blog Medium custom domain, fetch và Wayback đều lỗi).

Bối cảnh

  • Văn hoá "you build it, you run it"; team Platform Infrastructure lo phần dùng chung (CI/CD, IaC, observability). Phần lớn service chạy trên GKE; service hướng khách chạy trên cụm dùng chung. Stack giám sát: Prometheus (hơn 1 triệu time series từ khoảng 100 nguồn, giữ gần 3 năm, 10 TB), Thanos, Grafana, Loki, Tempo, Alertmanager.
  • Prometheus có bộ alert mặc định tốt (ví dụ HPA chạy sát max replicas trong 15 phút: sắp hết khả năng autoscale). Nhưng alert chung không có chủ, rơi vào kênh chung.
  • Cách cũ: mỗi team chép alert với nhãn team riêng, kèm danh sách cho/chặn kiểu hpa!~"app1|app2" (trùng lặp, app mới phải sửa nhiều rule, dễ quên); định tuyến theo namespace (team thay đổi, namespace sống lâu hơn team).

Thay đổi chính

  • Gắn nhãn team lên chính resource Kubernetes (HPA, CronJob, Pod...). kube-state-metrics xuất các series kube_*_labels (giá trị luôn bằng 1) mang nhãn đó, ví dụ kube_hpa_labels{hpa, namespace, label_team}.
  • Kéo nhãn team vào alert bằng phép nhân: kube_hpa_labels * on (hpa, namespace) group_right(label_team) (<query gốc>). Nhân với 1 không đổi giá trị, chỉ thêm nhãn; phải khớp cả namespace vì hai HPA trùng tên ở hai namespace sẽ làm hỏng rule. Lõi query giữ nguyên, rule vẫn dễ viết.
  • Rule gắn team: "{{ $labels.label_team }}"; Alertmanager có một receiver mỗi team (Slack/PagerDuty). Số receiver tỉ lệ số team, ít và ít đổi hơn nhiều so với số ứng dụng.
  • Việc gắn nhãn đồng nhất được ép bằng GitOps + Conftest/Rego; theo bài, nhãn team vốn cần cho trách nhiệm, bảo mật, FinOps nên không phải thêm việc.

Vì sao

Bài học cho SWE

  • Định tuyến alert theo metadata sở hữu gắn trên resource; đừng nhân bản rule theo team hay dựa vào namespace.
  • Nền tảng cung cấp rule mặc định, team chỉ cần gắn nhãn đúng; ép nhãn bằng policy-as-code.

Liên quan