iT邦幫忙

2026 iThome 鐵人賽

DAY 28
0

昨天用 PromQL 查到了 staging 的 CPU、記憶體和重啟次數,但每次都要打開 Prometheus 貼查詢,結果也只是一條一條的序列。今天用 Grafana 把這些查詢做成 Dashboard,打開就能一眼看出 Todo App 的狀況。


Grafana 是什麼

Grafana 是視覺化工具,本身不存資料,而是去資料來源(Prometheus)查詢,再把結果畫成圖表:

Prometheus(存資料、執行 PromQL)
      │
      │  Grafana 送出 PromQL 查詢
      ▼
Grafana Dashboard(畫成圖表)

所以昨天學的 PromQL 可以直接沿用,差別只在於結果從表格變成圖表,並且可以把多個查詢排在同一個畫面上。

昨天裝的 kube-prometheus-stack 已經包含 Grafana,也設定好了 Prometheus 資料來源。


實際操作

今天目標:登入 Grafana,看懂內建 Dashboard,建立一個可以切換 dev / staging 的 Todo App Dashboard,最後把它存進 ConfigMap,Grafana 重啟也不會消失。

Step1: 登入 Grafana

轉發到本機 3001,終端機保持開著:

kubectl port-forward svc/monitoring-grafana -n monitoring 3001:80

不用 3000,是因為前面幾天 Todo App 的前端用的就是 3000,會打開到前端的畫面。

打開 http://localhost:3001,帳號 admin,密碼從 Secret 取得:

kubectl get secret monitoring-grafana -n monitoring -o jsonpath="{.data.admin-password}" | base64 -d

PowerShell:

$pw = kubectl get secret monitoring-grafana -n monitoring -o jsonpath="{.data.admin-password}"
[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($pw))

Step2: 確認資料來源

左側選單 Connections → Data sources,會看到已經有一個 Prometheus,URL 指向昨天 port-forward 的那個 Service。

kube-prometheus-stack 安裝時就自動設定好了,不用手動新增。

Step3: 看懂內建 Dashboard

左側選單 Dashboards,kube-prometheus-stack 預裝了很多 Dashboard,先看這幾個:
https://ithelp.ithome.com.tw/upload/images/20261006/20183863UYMejdoxaz.png

  • Kubernetes / Compute Resources / Cluster:整個叢集的 CPU、記憶體,以及各 Namespace 的使用比例
  • Kubernetes / Compute Resources / Namespace (Pods):某個 Namespace 裡每個 Pod 的資源使用
  • Kubernetes / Compute Resources / Pod:單一 Pod 的 CPU、記憶體,並對照 requests 和 limits

打開 Kubernetes / Compute Resources / Pod,上方的 namespace 選 staging,pod 選 todo-staging-api-xxx。右上角可以調整時間範圍,看過去幾小時的變化。

這些圖表背後都是 PromQL。在任一個圖表右上角的選單選 Edit,就能看到它用的查詢,會發現跟昨天寫的很像,一樣用了 rate、sum by 和 label 篩選。看完按 Discard 離開,不要存檔。

Step4: 建立 Todo App Dashboard

內建 Dashboard 涵蓋整個叢集,這裡建一個只看 Todo App 的。

Dashboards → New → New dashboard → Add visualization,資料來源選 Prometheus。

新版 Grafana(12.x)沒有 Add visualization 時,點 Add panel(或右側邊欄的 + → Panel),再按 Configure visualization。注意不要選到 Variable。

查詢框預設是 Builder 模式(用選單組查詢),切到 Code 模式就能直接貼昨天的 PromQL。

右側如果先出現圖表類型清單,要先點一種類型,才會出現標題、單位等設定。

依序加入四個 Panel,每加完一個按 Back to dashboard,再新增下一個:

Panel 1:API CPU 使用量

  • 圖表類型:Time series
  • 查詢:
sum by (pod) (rate(container_cpu_usage_seconds_total{namespace="staging", container="api"}[5m]))
  • 查詢框下方 Options → Legend 選 Custom,填 {{pod}}
  • 標題:API CPU 使用量(core)

Legend 填 {{pod}},圖例才會只顯示 Pod 名稱。標題在右側 Panel options → Title,設定項目多時可以用右側上方的搜尋框找。

Panel 2:API 記憶體使用率

  • 圖表類型:Time series
  • 查詢:
sum by (pod) (container_memory_working_set_bytes{namespace="staging", container="api"})
/
sum by (pod) (kube_pod_container_resource_limits{namespace="staging", container="api", resource="memory"})
  • Legend:{{pod}}
  • 右側 Standard options:Unit 選 Percent (0.0-1.0),Min 填 0,Max 填 1
  • 右側 Thresholds:把紅色的值改成 0.8,Show thresholds 選 As lines
  • 標題:API 記憶體使用率

圖上會多一條 80% 的紅線,曲線越接近它,越接近被 OOMKilled。

沒看到紅線,通常是漏填 Min、Max。Y 軸會自動縮放到資料附近(例如 46%~48%),80% 就落在畫面外了。

兩個 Pod 的使用率接近時,曲線會疊在一起,滑鼠移上去就能看到各自的數值。

Panel 3:API 可用 Pod 數

  • 圖表類型:Stat
  • 查詢:
sum(kube_deployment_status_replicas_available{namespace="staging", deployment=~".*-api"})
  • 標題:API 可用 Pod 數

staging 的 API 由 HPA 控制,這個數字會隨負載在 2~5 之間變化。

Panel 4:過去 1 小時重啟次數

  • 圖表類型:Stat
  • 查詢:
sum by (pod) (increase(kube_pod_container_status_restarts_total{namespace="staging"}[1h]))
  • Legend:{{pod}}
  • 標題:過去 1 小時重啟次數

這裡沒有篩選 container,所以 frontend 和 mysql 的 Pod 也會列出來。

四個 Panel 都加好後,拖曳標題列調整位置、拖曳右下角調整大小,右上角 Save dashboard,命名為 Todo App Overview。

Step5: 加上 namespace 變數,切換 dev / staging

現在查詢都寫死 namespace="staging",想看 dev 就得再做一份。Grafana 的變數可以解決這個問題。

先確認 dev 有在跑:

kubectl get pods -n dev

出現 No resources found,通常是 Day 26 Step0 重建叢集後漏了部署 dev。在 helm/ 補上,等 Pod Running 一兩分鐘後再繼續:

helm install todo-dev ./todo-app -f values-dev.yaml --set mysql.password=devpass123 --set mysql.rootPassword=devroot123 -n dev --create-namespace
  1. Dashboard 右上角 Edit → Settings → Variables → Add variable:
    • Variable type:Custom
    • Name:namespace
    • Custom options:dev,staging

新版 Grafana:編輯模式下點右側邊欄的 + → Variable,或齒輪 ⚙ → Variables → Add variable。

⚠️ 容易踩到的坑:

  • 要選 Custom,不是 Constant(Constant 不會出現下拉選單)。選錯後用 Change type 改,可能留下隱藏的舊變數,記得確認變數清單的 Hidden 底下是空的。
  • 查詢裡的 $namespace 對應的是 Name,不是 Label。
  • 值用半形逗號、不加空格,Preview 要出現兩個選項。
  • 改完要 Save,沒存檔就重新整理會全部消失。
  1. 按 Back to dashboard,上方會多一個 namespace 下拉選單。
  2. 逐一編輯四個 Panel,把查詢裡的 "staging" 改成 "$namespace"(Panel 2 有兩處),例如:
sum by (pod) (rate(container_cpu_usage_seconds_total{namespace="$namespace", container="api"}[5m]))
  1. 下拉選單切回 staging 後存檔,存檔時選的值就是預設值。

切換下拉選單,同一個 Dashboard 就能看 dev 或 staging。Panel 3 用 deployment=~".*-api" 而不是寫死 todo-staging-api,就是為了讓兩個環境都適用。
https://ithelp.ithome.com.tw/upload/images/20261006/20183863WbyAM9dFBr.pnghttps://ithelp.ithome.com.tw/upload/images/20261006/20183863IObS1pG3aI.png

💡 切到 dev 時,Pod 名稱要變成 todo-dev-...,可用 Pod 數是 1(dev 沒開 HPA)。還是 todo-staging-... 的話,代表有查詢沒改到。在 Panel 編輯畫面點 Query inspector,可以看到變數替換後實際送出的查詢。

這跟 Day 24 的 Helm values 是一樣的概念:模板只有一份,差異用參數帶入。

Step6: 把 Dashboard 存進 ConfigMap

kube-prometheus-stack 預設沒有幫 Grafana 開啟永久儲存,Grafana 的 Pod 重啟後,在 UI 建立的 Dashboard 就會消失。

解法是把 Dashboard 匯出成 JSON,存成 ConfigMap。kube-prometheus-stack 的 Grafana 有一個 sidecar,會自動載入帶有 grafana_dashboard=1 label 的 ConfigMap。

  1. 匯出前確認 Dashboard 已存檔,時間範圍是 Last 6 hours 這類相對時間。時間範圍和變數預設值都會一起寫進 JSON。

時間範圍顯示成 2026-10-06 01:59:01 to ... 這種固定時段,通常是在圖上拖曳放大後存了檔。不改回來,從 ConfigMap 載入後會一直停在那個時段。

  1. Dashboard 右上角 Export → Export as JSON → Download file。

新版 Grafana:右側邊欄的下載圖示 → Export as code → Download file。有格式選項的話選 Classic。

如果有 Export the dashboard to use in another instance 的開關,保持關閉。打開的話資料來源會變成 ${DS_PROMETHEUS} 佔位符,載入後 Panel 會沒資料。

  1. 檔案會下載到「下載」資料夾,檔名是 Todo App Overview-<一串數字>.json。在 repo 根目錄建立 monitoring/,搬過去並改名:
mkdir monitoring
mv ~/Downloads/"Todo App Overview-<一串數字>.json" monitoring/todo-app-dashboard.json

PowerShell:

mkdir monitoring
Move-Item "$HOME\Downloads\Todo App Overview-<一串數字>.json" monitoring\todo-app-dashboard.json
  1. 在 monitoring/ 執行,建立 ConfigMap 並加上 label:
kubectl create configmap todo-app-dashboard -n monitoring --from-file=todo-app-dashboard.json
kubectl label configmap todo-app-dashboard -n monitoring grafana_dashboard=1
kubectl get configmap todo-app-dashboard -n monitoring --show-labels

LABELS 欄位看到 grafana_dashboard=1 就完成了。

  1. 刪掉 Grafana 的 Pod 模擬重啟:
kubectl delete pod -n monitoring -l app.kubernetes.io/name=grafana
kubectl get pods -n monitoring -w

等新的 Grafana Pod 顯示 3/3 Running 後按 Ctrl + C,重新執行 Step1 的 port-forward(Pod 重建後原本的會斷線)。登入後 Todo App Overview 還在,這次是從 ConfigMap 載入的。

找不到 Dashboard 時,看 sidecar 的 log:

kubectl logs -n monitoring deploy/monitoring-grafana -c grafana-sc-dashboard --tail=20

從 ConfigMap 載入的 Dashboard 無法在 UI 直接存檔。要修改的話,改完重新匯出覆蓋 JSON,再更新 ConfigMap(ConfigMap 已存在,不能再用 create):

kubectl create configmap todo-app-dashboard -n monitoring --from-file=todo-app-dashboard.json --dry-run=client -o yaml | kubectl apply -f -
  1. JSON 檔也一起 commit 進 Git,Dashboard 就跟程式碼一樣有版本紀錄:
git pull
git add monitoring/todo-app-dashboard.json
git commit -m "Add Todo App Grafana dashboard"
git push

先 git pull,因為 CI 會更新 values-staging.yaml 的 image tag,本機可能不是最新的。

練習結束後,到 port-forward 的終端機按 Ctrl + C 停掉。


延伸筆記

Dashboard 要放什麼?Google SRE 書裡提出了「四個黃金指標」,是設計 Dashboard 的好起點:

  • Latency(延遲):請求的回應時間。要區分成功和失敗的請求,失敗的請求通常回應很快,混在一起會拉低平均值。
  • Traffic(流量):每秒有多少請求進來,用來了解負載,也是判斷是否擴容的依據。
  • Errors(錯誤率):失敗請求的比例,例如 5xx 錯誤率超過 1% 就該注意。
  • Saturation(飽和度):服務還剩多少餘裕,CPU、記憶體接近上限代表快撐不住了。

今天的 Dashboard 涵蓋的是 Saturation(CPU、記憶體、Pod 數)。這些資料來自 kubelet 和 kube-state-metrics,它們只看得到容器和 K8s 物件的狀態,看不到「進來了幾個請求、回應花了多久、有幾個失敗」。

Latency、Traffic、Errors 屬於應用程式層的指標,要由應用程式自己暴露 /metrics 給 Prometheus 抓取。以 Todo App 的 FastAPI 為例,可以用 prometheus-fastapi-instrumentator 自動產生請求數、回應時間等指標,再搭配 ServiceMonitor 讓 Prometheus 收集,就能把四個黃金指標補齊,有興趣的話很適合當作延伸練習。


小結

  • Grafana 不存資料,用 PromQL 向 Prometheus 查詢再畫成圖表
  • 內建 Dashboard 涵蓋叢集、Namespace、Pod 層級,打開 Edit 就能參考它的 PromQL
  • 自訂 Dashboard:Time series 看趨勢,Stat 看單一數字,Thresholds 標出危險線
  • 變數:用 $namespace 讓同一個 Dashboard 切換 dev / staging
  • ConfigMap + sidecar:Dashboard 存成 JSON,Grafana 重啟也不會消失,還能放進 Git 管理

Dashboard 要有人盯著才有用。明天會學 Alerting,把今天的查詢變成告警規則,出問題時自動通知。


上一篇
Day 27|Prometheus
下一篇
Day 29|Alerting
系列文
從零學 K8s|30 天核心概念 × 實作,新手也能真正掌握 Kubernetes 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言