昨天我們看了 Jenkins 的 CI/CD Pipeline,理解了 Jenkins 的強大之處。配合前面學習的 Kubernetes、Kustomize、Istio、Harbor,我們已經具備了大部分的構建和運行現代容器化應用完整能力。
但是,當應用運行在生產環境中時,還有一個至關重要的問題:如何知道系統的運行狀況? CPU 使用率多高?記憶體還剩多少?有沒有 Pod 在不斷重啟?請求延遲是否正常?錯誤率有沒有突然增加?如果沒有監控,系統就像一個黑盒子,只能等到用戶抱怨才知道出問題了。
這就是 可觀測性(Observability) 要解決的問題。今天我們要看看 Prometheus 和 Grafana,是 Kubernetes 生態系統中最主流的監控方案。Prometheus 負責收集和存儲指標數據,Grafana 負責將這些數據視覺化成美觀實用的儀表板。
在深入 Prometheus 和 Grafana 之前,我們需要理解可觀測性的核心概念。可觀測性不僅僅是監控,它是一個更廣泛的概念,描述了我們理解和調試複雜系統的能力。
業界通常將可觀測性分為三大支柱,每個支柱提供了系統的不同視角。
指標(Metrics) 是數值化的測量數據,比如 CPU 使用率、記憶體使用量、請求數量、錯誤率等。指標的特點是輕量、可聚合、適合長期存儲。可以很容易地計算平均值、百分位數、趨勢等。指標回答的是「發生了什麼」和「有多嚴重」。
日誌(Logs) 是系統產生的事件記錄,通常是文本格式。每個請求、每個錯誤、每個重要操作都可能產生日誌。日誌的特點是詳細、具體、包含上下文。它回答的是「為什麼會發生」和「具體發生了什麼」。
追蹤(Traces) 記錄了請求在分散式系統中的完整路徑。一個用戶請求可能經過多個微服務,追蹤能夠串聯這些服務調用,展示每個環節花費的時間。追蹤回答的是「請求經過了哪裡」和「哪個環節慢了」。
這三個支柱是互補關係。指標讓我們快速發現問題,日誌幫我們定位原因,追蹤讓我們理解分散式系統中的調用關係。
關鍵監控指標 - 四個黃金訊號 (Four Golden Signals):
Google SRE 團隊提出了「四個黃金信號」,這是監控任何系統都應該關注的核心指標。
延遲(Latency) 是請求處理的時間。需要關注不同百分位的延遲:P50(中位數)、P95、P99。光看平均值是不夠的,因為平均值會被極端值影響。一個系統可能平均延遲 100ms,但 P99 延遲 10 秒,這意味著 1% 的用戶體驗很糟糕。
流量(Traffic) 是系統承載的負載量。對於 Web 服務,通常是每秒請求數(RPS);對於資料庫,可能是每秒查詢數;對於消息佇列,是消息吞吐量。流量的變化可以反映業務的變化,突然的流量增加或減少都值得關注。
錯誤(Errors) 是失敗請求的比例。包括明確的錯誤(HTTP 500、異常)和隱含的錯誤(返回錯誤的內容、超時)。錯誤率是最直接的服務品質指標,任何錯誤率的上升都需要立即調查。
飽和度(Saturation) 是資源的使用程度。包括 CPU、記憶體、磁碟、網路等。當資源接近飽和時,系統的效能會下降。監控飽和度可以幫助我們在問題發生前進行擴容。
這四個信號相互關聯。當流量增加時,延遲可能上升,如果超過容量,錯誤率會增加。當飽和度過高時,延遲和錯誤率都會受影響。監控這四個信號,就能掌握系統的整體健康狀況。
Prometheus 是一個開源的監控和告警系統,最初由 SoundCloud 開發,現在是 CNCF 的畢業項目。它專門為雲原生環境設計,與 Kubernetes 的整合非常深入。
Prometheus 採用拉取(Pull)模式來收集指標,這與傳統的推送(Push)模式形成鮮明對比。在推送模式中,應用主動將指標發送到監控系統;在拉取模式中,Prometheus 定期訪問應用的指標端點,抓取數據。
首先是 簡化配置,應用只需要暴露一個 HTTP 端點,Prometheus 會自動發現並抓取。應用不需要知道監控系統在哪裡,也不需要配置推送地址。其次是更好的控制,Prometheus 決定抓取頻率和超時時間,可以根據系統負載動態調整。最後是健康檢查,如果 Prometheus 無法抓取指標,說明目標可能已經掛了,這本身就是一個有價值的信號。
Prometheus 的架構體現了雲原生的設計哲學:單一職責、可擴展、聲明式配置。
Prometheus Server 是核心組件,負責抓取和存儲時序數據。它內建了一個高效的時序數據庫,使用獨特的壓縮算法,可以在有限的資源下存儲大量數據。這個數據庫針對時序數據的訪問模式優化:寫入是順序的(按時間順序),讀取通常是範圍查詢(查詢某個時間段的數據)。
服務發現機制 是 Prometheus 的一大亮點。在動態的 Kubernetes 環境中,Pod 會頻繁創建和銷毀,IP 地址不斷變化。手動維護監控目標列表是不現實的。Prometheus 整合了 Kubernetes API,可以自動發現集群中的 Pod、Service、Node 等資源。我們只需要定義規則「監控所有帶有特定標籤的 Pod」,Prometheus 會自動跟蹤這些 Pod 的生命週期。
Exporter 擴展了 Prometheus 的監控範圍。Kubernetes 本身暴露了豐富的指標,但對於第三方系統(MySQL、Redis、Nginx 等),需要 Exporter 作為橋樑。Exporter 連接到這些系統,讀取它們的狀態,轉換成 Prometheus 格式的指標。社群提供了數百個 Exporter,幾乎涵蓋了所有常用系統。
Alertmanager 是告警的專家。Prometheus 專注於指標收集和存儲,告警的處理交給 Alertmanager。這種分離讓每個組件都更專注、更簡單。Alertmanager 負責告警的去重(同一個問題不要發送多次)、分組(相關的告警合併成一個通知)、抑制(當某個嚴重告警觸發時,抑制相關的次要告警)、路由(根據標籤將告警發送到不同的接收者)。
Prometheus 的數據模型簡潔而強大。每個指標由指標名稱和一組標籤(Label)組成。比如:
http_requests_total{method="GET", endpoint="/api/users", status="200"} 1234
這個例子中,http_requests_total
是指標名稱,描述測量的是什麼。花括號內的是標籤,提供了多個維度的上下文:HTTP 方法是 GET、端點是 /api/users、狀態碼是 200。最後的 1234 是指標值,表示到目前為止有 1234 個符合這些條件的請求。
標籤讓指標具有多維度特性,這是 Prometheus 強大的根源。可以沿著任何標籤維度來切割數據。想知道所有 GET 請求的總數?按 method 標籤聚合。想知道 /api/users 端點的錯誤率?過濾 endpoint 標籤,然後計算 status=500 的比例。想比較不同版本的性能?如果 Pod 有 version 標籤,可以按版本分組比較。
這種多維度模型讓我們能夠從不同角度分析同一組數據,而不需要預先定義所有可能的聚合方式。這在微服務環境中特別有價值,因為我們經常需要以不同的視角(按服務、按版本、按環境、按地區等)來查看指標。
Prometheus 定義了四種指標類型,每種都適合不同的使用場景。
Counter(計數器) 是只增不減的累積值。它適合測量「發生了多少次」這類問題。比如 HTTP 請求總數、錯誤總數、處理的消息數。Counter 的絕對值通常意義不大,重要的是它的變化率。如果 http_requests_total 從 1000 變成 1100,說明這段時間有 100 個新請求。Prometheus 提供 rate()
函數來計算 Counter 的增長率。
Gauge(儀表盤) 是可增可減的瞬時值。它適合測量「當前是多少」這類問題。比如當前的記憶體使用量、當前的連接數、隊列中的消息數。Gauge 可以上升也可以下降,它的當前值就是有意義的。
Histogram(直方圖) 用於測量數值的分布。它將觀測值分配到不同的桶(Bucket)中,記錄每個桶的計數。Histogram 特別適合測量延遲。比如請求延遲的 Histogram 可能有這些桶:0-10ms、10-50ms、50-100ms、100-500ms、500ms-1s、>1s。通過 Histogram,可以計算百分位數(P50、P95、P99),了解延遲的分布情況。
Summary(摘要) 類似 Histogram,但它在客戶端計算百分位數,而 Histogram 在服務端計算。Summary 的優勢是計算準確,劣勢是無法聚合多個實例的數據。在微服務環境中,通常優先使用 Histogram,因為經常需要聚合多個 Pod 的延遲來計算整體的百分位數。
Prometheus 提供了強大的查詢語言 PromQL,這是使用 Prometheus 的關鍵。PromQL 看起來類似 SQL,但專門為時序數據設計。
最簡單的查詢就是指標名稱:
http_requests_total
這返回所有匹配的時間序列的當前值。
標籤選擇器讓我們能過濾數據:
http_requests_total{status="500", method="POST"}
這只返回 POST 請求中返回 500 錯誤的計數。標籤選擇器支持多種匹配方式:=
(精確匹配)、!=
(不等於)、=~
(正則匹配)、!~
(正則不匹配)。
PromQL 真正強大的地方在於函數和運算符。rate()
函數計算 Counter 的增長率:
rate(http_requests_total[5m])
這計算過去 5 分鐘內每秒的平均請求數。方括號表示時間範圍,這是一個範圍向量(Range Vector)。
可以進行數學運算:
sum(rate(http_requests_total{status=~"5.."}[5m]))
/
sum(rate(http_requests_total[5m])) * 100
這計算錯誤率:5xx 錯誤的請求占總請求的百分比。sum()
是聚合函數,將多個時間序列合併成一個。
聚合可以按標籤分組:
sum(rate(http_requests_total[5m])) by (endpoint)
這計算每個端點的總請求率,結果是每個 endpoint 一個時間序列。
PromQL 還支持複雜的運算,比如預測:
predict_linear(node_filesystem_free_bytes[1h], 4 * 3600)
這基於過去 1 小時的趨勢,預測 4 小時後磁盤還剩多少空間。
掌握 PromQL 需要時間和實踐,但它的表達能力值得投資。一個好的 PromQL 查詢可以揭示系統深層的問題,而這些問題可能需要大量手工分析才能發現。
如果說 Prometheus 是數據的收集者和保管者,那 Grafana 就是數據的詮釋者和藝術家。Grafana 是一個開源的數據視覺化和監控平台,它的使命是讓複雜的數據變得易於理解。
Grafana 的核心理念是數據源無關。它可以連接多種數據源:Prometheus、InfluxDB、Elasticsearch、MySQL、PostgreSQL、CloudWatch 等等。可以在同一個儀表板中混合使用不同數據源的數據,創建統一的視圖。這種靈活性讓 Grafana 成為監控領域的瑞士軍刀。
儀表板即代碼是 Grafana 的另一個重要特性。儀表板可以導出為 JSON 文件,這意味著可以用 Git 管理儀表板,進行版本控制、審查、回滾。可以用程式碼生成儀表板,實現自動化。可以在團隊間分享儀表板,不需要手動重建。這種「配置即代碼」的理念與 Kubernetes 的聲明式管理完美契合。
**Panel(面板)**是 Grafana 儀表板的基本單位。每個面板展示一個或多個查詢的結果。Grafana 提供了豐富的視覺化類型來適應不同的數據。
**Time Series(時間序列圖)**是最經典的監控視圖。橫軸是時間,縱軸是指標值,多條線代表不同的時間序列。這種圖表讓我們能看到指標隨時間的變化趨勢,發現異常模式。可以設定閾值線,當指標超過閾值時一目了然。可以使用不同的顏色和樣式來區分不同系列。
**Gauge(儀表盤)**適合展示當前狀態。它就像汽車的速度表,用指針或填充條來表示當前值占範圍的比例。可以設定多個閾值,用不同顏色表示不同的狀態:綠色表示正常,黃色表示警告,紅色表示嚴重。這種視覺化讓人能夠瞬間判斷系統狀態。
**Stat(統計數字)**用大字體展示單個數值,適合展示關鍵指標。比如當前的總 RPS、錯誤率、可用性等。可以添加趨勢圖作為背景,既展示當前值,也展示變化趨勢。可以設定閾值改變顏色,讓數字本身傳達狀態資訊。
**Table(表格)**可以展示多個指標的詳細數據,適合需要精確數值的場景。比如列出所有 Pod 的資源使用情況,可以按任何列排序,快速找到使用最多資源的 Pod。表格也支持條件格式,用顏色標記異常值。
**Heatmap(熱圖)**是展示分布的利器。它將數值範圍分成多個區間(Y 軸),時間作為 X 軸,顏色深淺表示該區間的計數。熱圖特別適合展示延遲分布:我們能看到延遲如何隨時間變化,是否有長尾,高延遲請求集中在什麼時間段。
**Variables(變數)**是 Grafana 的殺手級功能之一。變數讓同一個儀表板能夠展示不同範圍的數據,大幅提高了儀表板的重用性。
常見的變數類型包括Query Variables,從數據源查詢可能的值。比如查詢所有的命名空間、所有的 Pod 名稱、所有的服務。用戶可以從下拉選單中選擇,儀表板會動態更新。
Interval Variables 定義時間粒度。用戶可以選擇是按 1 分鐘、5 分鐘還是 1 小時聚合數據。短期查看使用細粒度,長期趨勢使用粗粒度,這樣可以平衡細節和性能。
Custom Variables 讓我們定義自己的選項列表。比如定義環境變數(dev、staging、prod),用戶選擇環境後,儀表板展示對應環境的指標。
變數可以級聯。比如先選擇命名空間,然後 Pod 變數只顯示該命名空間下的 Pod。這種層級關係讓導航變得直觀。
變數還可以支持多選和全選。用戶可以同時選擇多個 Pod,比較它們的指標。或者選擇「全部」,查看所有 Pod 的聚合數據。
Grafana 不僅能展示數據,還能主動監控數據並發出告警。雖然 Prometheus 也有告警功能,但 Grafana 的告警配置更加直觀,因為在設計面板時就能同時設定告警。
Grafana 的新版告警系統(Grafana 8.0+)更加強大和靈活。可以定義複雜的告警規則,組合多個數據源的數據。可以設定告警的評估間隔和持續時間,避免瞬間波動導致的誤報。可以使用標籤來組織和路由告警,實現精細化的告警管理。
Contact Points 定義了告警發送到哪裡。Grafana 支持多種通知渠道:Email、Slack、PagerDuty、Webhook、Microsoft Teams、Line 等。可以為不同嚴重程度的告警配置不同的接收者。Critical 告警發到值班手機,Warning 告警發到團隊頻道。
Notification Policies 定義了告警的路由邏輯。基於告警的標籤,決定發送到哪個 Contact Point。可以設定靜默期,避免在維護窗口發送告警。可以設定分組,將相關的告警合併成一個通知。
Silences 讓我們可以臨時禁止某些告警。比如在做系統升級時,某些告警是預期的,可以創建一個 Silence 來暫時禁止這些告警。Silence 有時間期限,到期後自動失效。
**Annotations(註解)**讓我們可以在圖表上標記重要事件。部署新版本、發生故障、進行配置變更,這些事件都可以作為註解顯示在圖表上。
當我們在分析性能問題時,註解能幫助我們快速關聯指標變化和實際事件。比如錯誤率在某個時間點突然上升,圖表上的註解顯示那時剛好部署了新版本,就知道問題可能在新版本中。
註解可以手動添加,也可以自動生成。Grafana 可以從多種來源獲取註解:Prometheus 的告警、Kubernetes 的事件、CI/CD 系統的部署記錄等。這讓系統的所有重要事件都能在監控視圖中呈現。
Prometheus 和 Grafana 的結合不是偶然,而是各自專注於自己擅長的領域,形成完美互補。
Prometheus 專注於數據。它做好一件事:高效地收集、存儲和查詢時序數據。Prometheus 的時序數據庫針對這個場景優化到極致,可以用很少的資源存儲大量數據。它的服務發現機制讓它能在動態環境中自動追蹤監控目標。它的 PromQL 提供了強大的查詢能力。
Grafana 專注於呈現。它做好另一件事:讓數據變得易於理解。Grafana 的視覺化能力遠超 Prometheus 自帶的 UI。豐富的圖表類型、靈活的佈局、美觀的設計,這些讓監控從「能用」變成「好用」。變數、註解、告警等功能讓儀表板不僅是展示工具,更是運維的工作台。
Grafana 對 Prometheus 的支持是原生級別的。添加 Prometheus 數據源只需要幾次點擊,不需要任何複雜配置。Grafana 理解 Prometheus 的數據模型和查詢語言,提供了智能的查詢構建器。可以用圖形界面構建查詢,不需要記住 PromQL 語法。
Grafana 可以展示 Prometheus 的元數據。查看有哪些指標、每個指標有哪些標籤、標籤的可能值是什麼,這些都可以在 Grafana 中探索。這讓新手更容易上手,不需要先學習所有指標的定義。
Grafana 的變數可以查詢 Prometheus 的標籤值。比如定義一個變數「命名空間」,查詢 label_values(kube_pod_info, namespace)
,Grafana 會自動列出所有命名空間。用戶選擇後,儀表板中所有面板的查詢都會自動過濾到選定的命名空間。
Grafana 儀表板庫 是一個寶庫。社群貢獻了數千個預製儀表板,涵蓋各種應用和場景。監控 Kubernetes?有專門的儀表板。監控 MySQL?有詳細的儀表板。監控 Nginx?也有。這些儀表板都是經過實戰檢驗的,設計合理、功能完善。可以直接導入使用,或者作為起點進行自定義。
Prometheus Exporter 生態 同樣豐富。幾乎任何想監控的系統,都有對應的 Exporter。官方維護的、社群開發的、公司內部的,各種 Exporter 讓 Prometheus 的監控範圍幾乎無限。而且 Prometheus 的指標格式已經成為事實標準,越來越多的應用原生支持 Prometheus 格式的指標暴露。
在 Kubernetes 生態系統中,Prometheus + Grafana 已經是監控的標準配置。CNCF 的畢業專案地位、與 Kubernetes 深度整合、社群的廣泛採用,這些因素讓它們成為事實標準。
Kubernetes 本身就內建了對 Prometheus 的支持。API Server、kubelet、kube-controller-manager 等核心組件都暴露了 Prometheus 格式的指標。Kubernetes 的資源(Pod、Service、Node 等)可以通過標籤和註解來控制監控行為。這種原生整合讓監控變得自然而流暢。
很多 Kubernetes 相關的專案和工具也選擇了 Prometheus 作為指標輸出格式。Istio 暴露服務網格的指標,Nginx Ingress Controller 暴露流量指標,cert-manager 暴露證書管理的指標。這種一致性讓我們可以用同一套監控系統覆蓋整個平台。
這就是我 30 天 Kubernetes 學習之旅的鐵人賽終點,但對我來說只是剛開始,雖然現在沒有真的實務使用過 Kubernetes,但我相信只要需要的話我一定可以很快速的上手。從 Pod 到 Deployment,從 Service 到 Ingress,從 ConfigMap 到 Secrets,從 Kustomize 到 Istio,從 Harbor 到 Jenkins,最後到 Prometheus 和 Grafana,每一個工具都是這個龐大生態系統的一塊拼圖。當它們組合在一起,就形成了一個完整強大的 DevOps 連結。
今年終於又撐過 30 天了,回想這 30 天每天下班才開始想今天內容真的是很大的挑戰。鐵人賽真的是很有意義的一個挑戰,總是可以讓我把想要學的東西藉著這個機會去好好熟悉起來。很感動自己在遇到挑戰和挫折的時候不管多累還是撐下去了,回想剛開始的幾天還因為跟 Kubernetes 不熟而常常熬夜。
如同我系列標題的 CKAD 還沒有考,最近幾天也在刷題準備,因此實戰的部分待考完會再來更新。昨天官方剛公告 2025/10/14 才開始支援 MacOS 26,待考完會再來分享我的準備以及考試的心得。
明年再戰!