iT邦幫忙

2025 iThome 鐵人賽

DAY 19
0
Cloud Native

EKS in Practice:IaC × GitOps 實戰 30 天系列 第 19

[Day 19] 叢集的千里眼:Prometheus & Grafana 讓一切被看見

  • 分享至 

  • xImage
  •  

前言

到目前為止,我們已經把 EKS 叢集的基礎設施打通:從 Pod → Service → Ingress → Load Balancer → DNS,都能自動化完成。接下來,問題就變成:我們怎麼知道這些東西真的有在正常運作?

這就是 Monitoring(監控) 的角色所要滿足的目標。今天的主角是 kube-prometheus-stack 這張 Helm Chart,以及他幫我們部署出來的 Prometheus、Grafana 及 AlertManager。基本上這個組合也是幾乎所有 Kubernetes 環境監控的基石。

什麼是 kube-prometheus-stack?

在開始之前,我們需要先了解 kube-prometheus-stack 這個 Helm Chart —— 它不只是簡單安裝 Prometheus,而是提供了一套完整的 Kubernetes 監控解決方案。

核心元件架構

kube-prometheus-stack 包含以下關鍵元件:

  • Prometheus Operator:和一般的 operator 用途相同(Controller + CRD),自動化管理 Prometheus 實例,透過 CRD 簡化配置
  • Prometheus:time-series database 的核心,會透過定期 scrape 各個 Exporter 或者應用程式的 /metrics 來收集、並儲存 metrics。通常也會對這個元件下 PromQL query 來對 metrics 進行聚合、計算
  • Alertmanager:告警管理系統,處理告警的路由和通知
  • Grafana:可以將 Prometheus 設置為 datasource、視覺化儀表板平台
  • Node Exporter:部署在每個節點上,收集系統層級指標
  • kube-state-metrics:收集 Kubernetes 資源的狀態指標
  • Prometheus Adapter:將自定義指標暴露給 HPA 使用
  • ServiceMonitor:定義監控目標的 CRD,實現自動服務發現機制

運作流程

整個監控系統的運作流程如下:

https://ithelp.ithome.com.tw/upload/images/20250919/20119667rZGPniA33z.png

  1. 資料收集:Prometheus 透過 Pull 模式定期 scrape 各個 target 的 /metrics endpoint
  2. 服務發現:透過 ServiceMonitor CRD 自動發現需要監控的服務
  3. 資料存儲:將指標以時序資料格式存儲
  4. 視覺化:Grafana 從 Prometheus 查詢資料並展示在 Dashboard
  5. 告警處理:當指標觸發告警規則時,Alertmanager 負責發送通知

ServiceMonitor:自動化的服務發現

傳統的 Prometheus 需要手動配置 scrape_configs,但在 Kubernetes 環境中,Pod 會動態建立和銷毀。ServiceMonitor 這個 CRD 解決了這個痛點:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: my-app-monitor
spec:
  selector:
    matchLabels:
      app: my-app
  endpoints:
  - port: metrics
    path: /metrics
    interval: 30s

ServiceMonitor 相比傳統方式的優勢:

  • 宣告式管理:透過 YAML 定義監控需求,符合 K8s 原生思維
  • 自動服務發現:動態發現服務,自動更新監控目標
  • 權限隔離:不同團隊可獨立管理自己的監控配置
  • GitOps 友善:監控配置可版本化

雖然 ServiceMonitor 需要手動配置,但大部分 Helm Chart 已經準備好選項:

# Chart 內建支援
helm install keda kedacore/keda --set prometheus.operator.enabled=true

# 手動建立(如果 Chart 沒有內建)
kubectl apply -f my-app-servicemonitor.yaml

重要觀念:你需要明確告訴 Prometheus「要監控什麼」,但 Prometheus Operator 會自動處理後續的配置更新。


Grafana:把數據變成觀察

Grafana 是可視化平台,專門將時序資料轉換成直觀的圖表和儀表板。在監控架構中,Prometheus 負責「存數據」,Grafana 則負責「讓數據好看」

Grafana 透過 PromQL 查詢 Prometheus 的時序資料,提供豐富的視覺化選項:折線圖展示趨勢變化、熱力圖顯示資源分佈、儀表板呈現即時狀態。更重要的是,它支援告警視覺化、多維度資料鑽取,以及團隊協作功能。

對於 DevOps 團隊來說,Grafana 不只是「看圖表」,更是「發現問題」和「分析根因」的利器。一個設計良好的 dashboard 能讓你在幾秒內判斷系統健康狀況,快速定位效能瓶頸。

自訂 Dashboard 的實戰經驗

一開始我們用的都是內建 dashboard。雖然能看基本 CPU、Memory、Node 狀態,但當我想提升 Node Utilization 時,發現這些圖表根本看不出「Pod 的 request/limit 是否合理」。

於是我寫了 PromQL 查詢,自訂了一張 dashboard:

https://ithelp.ithome.com.tw/upload/images/20250919/20119667sVbX65aivC.jpg

關鍵 PromQL 查詢範例:

# Node Usage vs Request
sum(container_memory_usage_bytes{container!="", container!="POD"})
/
sum(cluster:namespace:pod_memory:active:kube_pod_container_resource_requests)

# Node Request vs Capacity
sum(container_memory_usage_bytes{container!="", container!="POD"})
/
sum(node_memory_MemAvailable_bytes)

這張圖讓我能看出:

  • 每個 Pod 的 Memory Usage / Request / Limit 比例
  • Node 層級的 Request vs Usage vs Capacity
  • Pod 的 QoS 類型(Guaranteed / Burstable / BestEffort)分佈(在截圖最下方的 Memory Quota 區塊)

調整之後,Node Utilization 提升到 80% 以上,資源使用效率大幅改善。

客製化 Dashboard 部署方式

我們自己包了一個 chart,允許把 JSON 格式的 dashboard 放進 ConfigMap,再由 Grafana 自動載入。

https://ithelp.ithome.com.tw/upload/images/20250919/20119667bTTG0WnjwS.jpg

在 Cluster values 加入以下設定:

# https://github.com/grafana/helm-charts/issues/764
customDashboards:
  default:
    ingress-nginx-board:
      file: dashboards/ingress-nginx.json
    memory-board:
      file: dashboards/memory-usage.json
    # add more dashboards here*

這樣做的好處是:

  • 彈性新增 dashboard(例如 ingress-nginx、memory-usage)
  • 自訂 dashboard 可重用:版本化、跨叢集部署
  • GitOps 友善:所有配置都在版控中

不只是監控:Alertmanager + Slack 通知

光能「看到」還不夠,還要能「被提醒」。在我們的 Prometheus stack 裡,我們也有設定 Alertmanager,讓告警自動送到 Slack。

重點設定如下:

Step 1: ExternalSecret 提供 Slack webhook

external_secrets:
  - name: slack-webhook
    data:
    - secretKey: slack-webhook-url
      remoteRef:
        key: ops-credentials
        property: slack_webhook_url

Step 2: AlertManager route 與 receiver

kube-prometheus-stack:
  alertmanager:
    enabled: true
    alertmanagerSpec:
      secrets:
        - slack-webhook
    # https://prometheus.io/docs/alerting/configuration/#configuration-file
    config:
      route:
        routes:
          - receiver: 'slack'
            matchers:
              - severity =~ "warning|error|critical"
      receivers:
        - name: 'slack'
          slack_configs:
          - api_url_file: /etc/alertmanager/secrets/slack-webhook/slack-webhook-url
            channel: example-internal-notification
            send_resolved: true
		            ### 設置送到 slack 的 message title
                title: '🚨 [{{ .Status }}] {{ .GroupLabels.alertname }}'
		            ### 設置送到 slack 的 message content
                text: |
                  {{ range .Alerts }}
                  *Alert:* {{ .Annotations.summary }}
                  *Description:* {{ .Annotations.description }}
                  *Severity:* {{ .Labels.severity }}
                  {{ end }}

這樣當 Node Down、Pod CrashLoop、資源用量過高時,我們就能在 Slack channel 裡收到通知。

常用告警規則

系統會自動針對以下情況發送告警:

  • Node Down:節點無法連接
  • Pod CrashLoop:Pod 持續重啟
  • 資源用量過高:CPU/Memory 使用率超過閾值
  • 磁碟空間不足:節點儲存空間低於警戒線
  • API Server 回應緩慢:Kubernetes API 延遲過高

https://ithelp.ithome.com.tw/upload/images/20250919/20119667EAKbFARrvc.jpg


部署方式:ApplicationSet for Prometheus Stack

我們今天一樣會使用 ApplicationSet 管理 Prometheus stack:

  • Shared values:Prometheus 保留時間、資源需求、storage、Grafana 的 OIDC、AlertManager 基本 route。
  • Cluster values:自訂 dashboards、外部 secret(Grafana SSO、Slack webhook)、Grafana ingress host。

這樣所有 cluster 都能有一致的 Prometheus stack,又能根據需求增加自訂 dashboard 或告警規則。又因為我們希望同時設定好 custom dashboard、方便新增 SSO 及 slack webhook 的 ExternalSecret、以及一些我們預設的 Prometheus Rule CRD,所以特地為 Prometheus Stack 包裝成一個新的 helm chart。因此這張 chart 在部署模式上會像前幾天的 Karpenter 一樣,會把需要同時部署的 CRD 詳細資訊也一併放在 Value files 當中:

https://ithelp.ithome.com.tw/upload/images/20250919/20119667GAGACkosGD.jpg

📌 更多參數可參考官方文件:kube-prometheus-stack values.yaml

小結

今天我們透過 Prometheus stack 把監控和告警完整串了起來:

  • Prometheus 收集與存放 metrics。
  • Grafana 把數據可視化,並能掛上自訂 dashboard。
  • PromQL 讓我們能分析 request/limit,優化 Node Utilization。
  • Alertmanager 將告警訊息送到 Slack,讓我們能即時回應。

到這裡,我們不只是「看到叢集在動」,而是能主動「被提醒哪裡出問題」。

Day 20,我們將轉向另一個話題 —— KEDA (Kubernetes Event-Driven Autoscaler),看看如何透過事件或訊號驅動 workload 自動擴縮。


上一篇
[Day 18] DNS 小精靈:ExternalDNS 自動綁定網域
下一篇
[Day 20] 事件驅動的魔法:KEDA 讓 Pod 自己長大縮小
系列文
EKS in Practice:IaC × GitOps 實戰 30 天20
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言