昨天 Prometheus 開始存資料了,但是它自己的畫面很陽春。今天接上 Grafana,一個把資料畫成圖表的網頁介面,它自己不存任何資料,只負責去問別人要。
不過這篇我不想只教「怎麼拉出一張圖」。我想先問一個更前面的問題:
一張圖表存在的理由是什麼?
會這樣問是因為,我上網找 Grafana 的截圖時,看到的大多是那種深色背景、十幾個儀表盤、綠色數字一直跳的畫面,看起來非常專業。但就像我在 Day 1 說過的,看著這麼多漂亮圖表,我卻沒有辦法說出系統壞在哪裡。
所以今天的目標不是做一張好看的圖,是做一張能回答問題的圖。
kube-prometheus-stack 已經把 Grafana 裝好了,連 Prometheus 也接好了,不用自己設定資料來源。
kubectl port-forward -n monitoring svc/kps-grafana 3000:80
打開 localhost:3000,預設帳號是 admin。密碼存在一個叫 Secret 的東西裡面,那是 Kubernetes 用來放密碼、金鑰這類敏感資料的物件:
kubectl get secret -n monitoring kps-grafana \
-o jsonpath="{.data.admin-password}" | base64 -d
後面那個 base64 -d 是必要的,Secret 裡的值都是用 base64 編碼過的。順帶一提,base64 只是編碼不是加密,任何人拿到都能還原,所以 Secret 本身並不等於「安全」,它只是「不會不小心被看到」。

首頁有點空,只有一塊「Recent dashboards」,而且列的是我剛剛點過的兩張。我一開始以為 chart 沒附儀表板,其實是有的,要點左側選單的 Dashboards 才看得到清單,首頁那塊只是最近瀏覽紀錄。
點進去之後我數了一下,29 張,涵蓋 Kubernetes 的各種面向:節點資源、命名空間、API server、etcd、CoreDNS,還有 Prometheus 和 Grafana 自己的。
但是先不要看它們,等一下會說為什麼。
每次要加一張圖之前,我先問自己這三個問題:
一、這張圖回答什麼問題?
答不出來就不要加。「CPU 使用率」不是一個問題,「這個服務是不是因為 CPU 不夠而變慢」才是。
二、看到異常之後,我下一步能做什麼?
如果答案是「不知道,再看看別的圖」,那這張圖的位置應該讓給那張「別的圖」。
三、這是給誰看的?
半夜被叫起來的人,還是每週開會的人?兩者要看的東西完全不同。前者要的是「現在該不該緊張」,後者要的是趨勢。
拿這三個問題去檢查那些現成的儀表板,會發現大部分都不及格。但這不是它們做得爛,是它們不是為我的問題做的,通用模板就代表沒有針對任何一個具體問題。
Day 2 訂了兩個 SLI,可用性和延遲。第一張圖就畫它們,因為那是我唯一承諾過要達到的東西。
新增一個 Dashboard,第一個面板的查詢是這個:
sum(rate(checkout_total{status="success"}[5m]))
/
sum(rate(checkout_total[5m]))
意思是「過去五分鐘,成功的請求佔全部的比例」。語法明天會完整講,今天先知道 rate(...[5m]) 大概是「過去五分鐘的每秒平均速率」就好。
第一步:左側 Dashboards → 右上 New → New dashboard。畫面右邊會滑出一塊「Add」,最上面的 Panel 區有一個寫著「Drag or click to add a panel」的縮圖框,點它。

第二步:面板會出現在畫布上,但還是空的。點中間那顆藍色的 Configure visualization。

第三步:進到面板編輯畫面。上半部是圖表預覽,下半部是查詢區,資料來源已經幫我們選好 Prometheus 了。重點是查詢區右上角那組 Builder / Code 切換,要點 Code。

第四步:切成 Code 之後,才會出現一個「Enter a PromQL query…」的輸入框,這時候才貼得上去。預設的 Builder 是圖形化模式,只能一格一格選,貼不了文字。

貼上查詢,按 Run queries,上面的預覽就會出圖。
貼上去按 Run queries,圖就出來了。但是它長這樣:

線是有了,可是這張圖幾乎沒有用。Y 軸自動從 0% 拉到 200%,我的線就是中間那條貼在 100% 的直線。成功率掉到 97% 我也看不出來,因為 3% 的變化在這個尺度下只有幾個像素。
問題不在資料,在呈現。右側的 Standard options 有三個欄位要設:

Unit 選 Percent (0.0-1.0)。 下拉選單裡有兩個長得很像的選項,Percent (0-100) 和 Percent (0.0-1.0),要選後者。因為 PromQL 算出來的是 0 到 1 之間的小數,選錯的話 0.99 會顯示成 0.99%。
Min 填 0.95、Max 填 1。 注意是 0.95 不是 95,單位只影響顯示,底層的值還是 0 到 1。
這一步是我覺得今天最實用的。SLI 永遠在 95% 到 100% 之間跳動,讓 Y 軸自動縮放,它就會像上面那樣被壓成一條直線。把範圍縮到我在乎的區間,圖才會開始說話。
最後在 Thresholds 加一條 0.99,也就是我的 SLO,然後把下面的 Show thresholds 改成 As lines,不然只會變成背景上色而不是一條線。

同一份資料,這張圖就有意義了。Y 軸從 95% 到 100%,紅色那條是 SLO 門檻,綠色是實際的成功率。
有了那條紅線,這張圖回答的問題就從「可用性是多少」變成「我有沒有違反自己的承諾」。後者才是可以行動的。
現在故障都關著,所以線一直貼在 100%,看起來很無聊——這是正常的,這叫基準線。之後把故障打開,就是拿這張圖來對照。
histogram_quantile(0.95,
sum(rate(http_request_duration_seconds_bucket{job="gateway", path="/checkout"}[5m])) by (le)
)
這行算的是 P95 延遲,也就是 95% 的請求比這個數字快。
為什麼不畫平均值? Day 2 說過了,99 個 50 毫秒加上 1 個 10 秒,平均是 149 毫秒看起來很健康,但那個等了 10 秒的人已經關掉頁面了。
實務上要在同一張圖裡放三條線:P50、P95、P99。做法是用查詢區下面的 + Add query 加成 A、B、C 三個查詢,只有第一個數字不一樣,分別是 0.5、0.95、0.99。
這張圖的設定跟 SLI 那張不太一樣,有三個地方要注意。
Legend 一定要自己命名。 不設的話圖例會把整行 PromQL 印出來,三行疊在一起完全沒法看。每個查詢下面展開 Options → Legend,分別填 P50、P95、P99。
Unit 選 seconds (s),藏在 Time 分類底下:

指標名字結尾是 _seconds,值的單位就是秒。選了之後 Grafana 會自動把 0.073 顯示成 73 ms,Y 軸也會從一串小數點變成看得懂的毫秒。
Min 填 0,Max 留空。 這裡跟 SLI 那張剛好相反。延遲沒有天花板,上限要讓它自動長;但是下限要釘在 0,不然 Grafana 會從最低點開始畫,看起來波動很大,其實只差幾毫秒。
做完長這樣:

三條線都在 100 毫秒以內,P50 大概 73 毫秒,P95 和 P99 疊在一起大概 97 毫秒。這是故障關著時候的基準線。
值得跟昨天對照一下。昨天我把 log 倒出來自己算,P50 是 73 毫秒、P95 是 718 毫秒。P50 一模一樣,但是 P95 差了七倍——因為昨天故障是開著的。今天這張圖是它健康時候的樣子。
三條線一起看,才看得出問題的形狀:三條一起漲,是全面性的問題;只有 P95、P99 漲而 P50 不動,那是少數請求出事,也就是長尾。Day 6 埋的第二個故障製造出來的就是後者,之後打開它,這張圖上的黃線和綠線會飛上去,而藍線不會動。
為了守住「每張圖都要回答一個問題」,我列了目前不加的圖:
| 不加 | 理由 |
|---|---|
| CPU 使用率 | 它是原因不是結果。使用者不會因為 CPU 高而不開心 |
| 記憶體用量 | 同上。之後為了預測 OOM 會用到,那時候有明確的問題要問 |
| Pod 數量 | 我又沒有自動擴縮,這個數字永遠不會變 |
| 網路流量 | 我現在答不出來「看到它異常要做什麼」 |
這不是說這些指標沒用。 CPU 在你已經知道「服務很慢」、正在找原因的時候非常有用。它們的位置是第二層:第一層的 SLI 圖告訴你有事,你才往下鑽。後面講 USE 和 RED 兩套方法論的時候,會給這個分層一個更完整的說法。
三個原則:
還有一個我覺得最有用的習慣:每張圖的標題直接寫成問題。不要叫「Request Rate」,叫「每秒進來幾筆請求?」。這樣半年後打開它,不用回想這張圖當初是為了什麼而做。
我一開始把兩張圖命名為「可用性 SLI」和「延遲」,後來照這個原則改掉了:

「成功率有沒有掉到 SLO 以下」和「結帳慢的是少數人還是所有人」,光看標題就知道這張圖是要回答什麼。左邊 SLI、右邊延遲,兩張放得進同一個螢幕,不用捲。
順帶一提,左邊那張的圖例我也改了。原本是整行 PromQL,比圖還寬,現在是「成功率」——跟右邊的 P50 / P95 / P99 同一種風格。
回到開頭那句「先不要看」。
現在可以看了,但是用不同的方式看:不是拿來用,是拿來學。點開任何一張現成的面板,看它的查詢是怎麼寫的,那是最好的 PromQL 教材,明天要講的東西裡面有一半都在那裡面。
實際維運的時候它們當然也有用,只是位置不同:我自己做的 SLI 儀表板是第一層,用來看有沒有事;現成的 Kubernetes 儀表板是第二層,往下鑽的時候才看。
今天做出了第一個儀表板,兩張圖:可用性 SLI 和 P50/P95/P99 延遲。
比圖更重要的是那三個問題——這張圖回答什麼問題、看到異常我能做什麼、這是給誰看的。
明天補上今天欠的 PromQL:rate 到底在算什麼、為什麼 counter 一定要包一層 rate、histogram_quantile 那行為什麼要那樣寫。