現代監控系統的演進與挑戰
在當代微服務與容器化架構盛行的時代,企業面臨著前所未有的監控挑戰。傳統的監控方案往往難以應對動態擴展的容器環境、短暫生命週期的服務實例,以及複雜的分散式系統架構。當一個應用程式被拆解成數十個甚至數百個微服務,每個服務又可能運行在多個容器實例中時,如何有效地收集、儲存和分析這些海量的監控資料,成為運維團隊必須面對的核心課題。
Prometheus 作為雲端原生運算基金會(Cloud Native Computing Foundation)的畢業專案,已經成為現代監控系統的事實標準。其採用的拉取式(Pull-based)監控模型、強大的時間序列資料庫,以及靈活的 PromQL 查詢語言,讓開發者能夠建構出適應動態環境的監控解決方案。然而,要充分發揮 Prometheus 的威力,需要深入理解其設計哲學和進階特性,特別是在處理大規模監控資料時,如何透過 metadata 指標、記錄規則和視覺化工具來優化監控架構的效能與可維護性。
本文將深入探討 Prometheus 監控系統的進階應用技巧,從 metadata 指標的靈活運用開始,解析如何透過向量比對來實現複雜的查詢邏輯。我們會詳細說明記錄規則(Recording Rules)的設計原則與最佳實務,展示如何透過預先計算來優化查詢效能。此外,也會完整介紹 Grafana 在 Linux、Windows 和 macOS 等不同平台上的部署方法,以及如何與 Prometheus 整合來建構強大的視覺化監控儀表板。透過本文的實務指南,讀者將能夠建立起完整的企業級監控解決方案。
Metadata 指標的設計哲學與實務應用
在 Prometheus 的監控架構中,指標(Metrics)的標籤(Labels)扮演著關鍵的角色。標籤為時間序列提供了維度資訊,讓我們能夠從不同的角度來查詢和分析監控資料。然而,標籤的使用需要謹慎評估,因為標籤與指標名稱共同構成了時間序列的唯一識別。當我們新增或修改標籤時,實際上是在建立全新的時間序列,這會直接影響到 Prometheus 的儲存效能和記憶體使用。
這就是 metadata 指標概念誕生的背景。與其將所有的上下文資訊都作為標籤附加到每個指標上,我們可以建立一個專門的 metadata 指標來承載這些相對靜態的資訊。這種設計模式在實務中帶來了顯著的好處,特別是當我們需要管理大量主機或容器時,可以避免因為標籤變更而造成的時間序列爆炸問題。
透過 Node Exporter 的 Textfile Collector 機制,我們可以輕鬆地建立 metadata 指標。這個收集器允許我們將自訂的指標資料寫入文字檔案,Node Exporter 會定期讀取這些檔案並將其轉換為 Prometheus 可以抓取的指標。這種方式特別適合用來記錄那些不頻繁變更的環境資訊,例如主機的角色定義、所屬資料中心、部署區域等。
# Metadata 指標範例
# 這個指標記錄了主機的角色和所在資料中心
metadata{role="docker_server",datacenter="TW-TPE"} 1
metadata{role="web_server",datacenter="TW-TXG"} 1
metadata{role="database_server",datacenter="US-NYC"} 1
在上述範例中,我們建立了三個 metadata 指標實例,每個實例透過標籤記錄了不同主機的角色和資料中心位置。這些資訊的值固定為 1,因為我們關注的是標籤所攜帶的資訊,而非指標的數值本身。當我們需要查詢特定類型的主機時,可以直接針對 metadata 指標進行過濾,而不需要在每個監控指標上都附加這些標籤。
這種設計帶來的最大優勢在於標籤的穩定性。假設我們有數千個時間序列來自同一台主機,如果將資料中心資訊作為標籤附加到每個時間序列上,當主機遷移到不同資料中心時,所有的時間序列都需要重新建立。但如果使用 metadata 指標,我們只需要更新一個指標實例的標籤,大大降低了維護成本和系統負擔。
# 查詢所有位於台灣資料中心的主機
# 使用標籤選擇器來過濾符合條件的 metadata 指標
metadata{datacenter=~"TW-.*"}
# 查詢非台灣資料中心的主機
# 使用不等於運算子來排除特定資料中心
metadata{datacenter!~"TW-.*"}
# 查詢特定角色的主機
# 組合多個標籤條件來精確定位目標主機
metadata{role="docker_server",datacenter="TW-TPE"}
這些查詢展示了 metadata 指標的靈活性。透過 PromQL 的標籤選擇器,我們可以使用正規表示式、等於或不等於運算子來篩選符合條件的主機。這種方式不僅查詢效率高,而且維護起來也相當簡單。
@startuml
!define PLANTUML_FORMAT svg
!theme _none_
skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100
title Metadata 指標在監控架構中的應用模式
package "監控目標主機群組" {
component [台北 Docker 伺服器\n10.0.1.10] as host1
component [台中 Web 伺服器\n10.0.2.20] as host2
component [紐約資料庫伺服器\n10.0.3.30] as host3
}
package "Node Exporter 層" {
component [Node Exporter\n+ Textfile Collector] as ne1
component [Node Exporter\n+ Textfile Collector] as ne2
component [Node Exporter\n+ Textfile Collector] as ne3
}
package "Metadata 指標定義" {
card "metadata{\nrole=docker_server\ndatacenter=TW-TPE\n} 1" as meta1
card "metadata{\nrole=web_server\ndatacenter=TW-TXG\n} 1" as meta2
card "metadata{\nrole=database_server\ndatacenter=US-NYC\n} 1" as meta3
}
component [Prometheus Server\n時間序列資料庫] as prom
host1 --> ne1
host2 --> ne2
host3 --> ne3
ne1 --> meta1 : 讀取 Textfile
ne2 --> meta2 : 讀取 Textfile
ne3 --> meta3 : 讀取 Textfile
meta1 --> prom : 抓取
meta2 --> prom : 抓取
meta3 --> prom : 抓取
note right of meta1
Metadata 指標優勢
標籤穩定性高
避免時間序列爆炸
維護成本低
查詢效率佳
適用場景
主機角色定義
資料中心位置
環境類型標記
部署區域資訊
end note
@enduml向量比對的進階查詢技術
向量比對(Vector Matching)是 PromQL 中一個強大但常被誤解的特性。在處理複雜的監控場景時,我們經常需要將來自不同指標的資料進行關聯分析。例如,我們可能想要找出所有運行 Docker 服務且位於特定資料中心的主機,或是計算特定區域內所有主機的平均資源使用率。這些需求都需要透過向量比對來實現。
向量比對的核心概念是在兩個向量之間建立對應關係。Prometheus 支援多種比對模式,包括一對一(One-to-One)、多對一(Many-to-One)和一對多(One-to-Many)。理解這些比對模式的差異,以及如何正確使用 on、ignoring、group_left 和 group_right 等修飾符,是掌握進階 PromQL 查詢的關鍵。
一對一比對是最基本的比對模式。當我們使用二元運算子連接兩個向量時,Prometheus 會嘗試為左側的每個元素在右側找到一個完全匹配的元素。所謂完全匹配,是指兩個元素具有相同的標籤集和標籤值。然而在實務應用中,我們往往不需要所有標籤都匹配,這時就可以使用 on 或 ignoring 修飾符來控制比對的標籤範圍。
# 查詢所有 Docker 服務狀態為 active 且位於台灣資料中心的主機
# 這是一個典型的一對一向量比對範例
node_systemd_unit_state{name="docker.service",state="active"} == 1
and on (instance, job)
metadata{datacenter=~"TW-.*"}
在這個查詢中,我們首先選擇所有 Docker 服務狀態為 active 的主機。然後使用 and 運算子配合 on 修飾符,將比對範圍限制在 instance 和 job 這兩個標籤上。這意味著只要兩側的指標在這兩個標籤上的值相同,就視為匹配成功。透過這種方式,我們可以過濾出同時滿足兩個條件的主機。
on 修飾符指定了要考慮的標籤集合,而 ignoring 修飾符則相反,它指定了要忽略的標籤集合。選擇使用哪一個取決於具體的查詢需求。當我們想要精確控制比對邏輯時,on 通常更加清晰明確。但當標籤很多而我們只想忽略其中幾個時,ignoring 會更簡潔。
# 使用 ignoring 修飾符的等效查詢
# 忽略 name 和 state 標籤,僅根據 instance 和 job 進行比對
node_systemd_unit_state{name="docker.service",state="active"} == 1
and ignoring (name, state)
metadata{datacenter=~"TW-.*"}
多對一和一對多比對處理的是更複雜的場景,其中一側的向量元素可以與另一側的多個元素匹配。這種比對模式必須使用 group_left 或 group_right 修飾符來明確指定哪一側具有較高的基數(Cardinality)。基數是指向量中唯一時間序列的數量,較高基數的一側可以包含多個具有相同標籤值的元素。
# 多對一比對範例
# 計算每個主機的 CPU 使用率,並保留其 metadata 標籤資訊
(
100 - (
avg by (instance) (
rate(node_cpu_seconds_total{mode="idle"}[5m])
) * 100
)
)
* on (instance) group_left(datacenter, role)
metadata
在這個範例中,左側的 CPU 使用率計算結果對每個 instance 只有一個值,而右側的 metadata 指標對同一個 instance 可能有多個不同的標籤組合。使用 group_left 告訴 Prometheus 左側具有較高基數,並且我們希望將右側的 datacenter 和 role 標籤附加到結果中。這樣我們就可以在查看 CPU 使用率的同時,了解該主機的角色和所在位置。
@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_
skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100
title 向量比對的執行流程與比對模式
start
:接收 PromQL 查詢\n包含二元運算子;
:識別左側向量表達式;
:識別右側向量表達式;
:確認比對修飾符;
note right
可能的修飾符:
on(labels)
ignoring(labels)
group_left(labels)
group_right(labels)
end note
:執行左側向量查詢;
:執行右側向量查詢;
if (是否使用 on 修飾符?) then (是)
:僅考慮指定的標籤進行比對;
elseif (是否使用 ignoring 修飾符?) then (是)
:忽略指定的標籤進行比對;
else (否)
:使用所有標籤進行比對;
endif
if (比對模式為一對一?) then (是)
:左側每個元素\n找到右側唯一匹配元素;
else (否)
if (比對模式為多對一?) then (是)
:左側多個元素\n匹配右側一個元素\n使用 group_right;
else (否)
:左側一個元素\n匹配右側多個元素\n使用 group_left;
endif
endif
:執行二元運算\n產生結果向量;
:附加額外標籤\n(如果指定);
:返回最終結果;
stop
note right
比對成功條件:
- 指定標籤的值必須完全相同
- 未指定的標籤不參與比對
- 比對失敗的元素會被過濾掉
效能考量:
- 減少比對標籤數量可提升效能
- 高基數向量比對需要更多資源
- 適當使用 group_left/right 避免錯誤
end note
@enduml企業級 Exporter 的 Metadata 模式實踐
在 Prometheus 生態系統中,許多成熟的 Exporter 都採用了 metadata 模式來提供額外的上下文資訊。這種模式已經成為一種最佳實務,特別是在需要追蹤 Exporter 版本、配置資訊或其他靜態屬性時。理解這些 Exporter 如何設計和使用 metadata 指標,可以幫助我們在開發自訂 Exporter 時做出更好的設計決策。
cAdvisor(Container Advisor)是 Google 開發的容器監控工具,它為 Prometheus 提供了豐富的容器級別指標。在 cAdvisor 的指標集中,有一個特別的指標名為 cadvisor_version_info,它遵循了典型的 metadata 模式。這個指標不是用來記錄隨時間變化的測量值,而是用來記錄 cAdvisor 本身的版本資訊和相關的 Docker 配置。
# cAdvisor 版本資訊指標範例
# 這個指標透過標籤提供了豐富的環境資訊
cadvisor_version_info{
cadvisorRevision="1a2b3c4",
cadvisorVersion="v0.47.0",
dockerVersion="24.0.7",
kernelVersion="5.15.0-91-generic",
osVersion="Ubuntu 22.04.3 LTS"
} 1
這個指標的設計展示了幾個重要的概念。首先,指標的值固定為 1,因為我們關注的是標籤攜帶的資訊而非數值本身。其次,標籤包含了多個維度的資訊,從 cAdvisor 的版本和修訂號,到 Docker 引擎版本、作業系統核心版本和發行版資訊。這些資訊在故障排查和版本管理時非常有價值。
當我們需要查詢特定版本的 cAdvisor 實例,或是找出運行在特定 Docker 版本上的容器時,就可以透過這個 metadata 指標來實現。更重要的是,我們可以將這個指標與其他容器監控指標進行向量比對,從而在分析效能問題時獲得完整的環境上下文。
# 查詢運行在 Docker 24.x 版本上的容器 CPU 使用率
# 並保留版本資訊標籤
rate(container_cpu_usage_seconds_total[5m])
* on (instance) group_left(dockerVersion, osVersion)
cadvisor_version_info{dockerVersion=~"24\\..*"}
這個查詢展示了如何結合實際的監控指標和 metadata 資訊。我們計算容器的 CPU 使用率,然後透過向量比對將 Docker 版本和作業系統版本資訊附加到結果中。這樣在檢視監控資料時,我們不僅能看到 CPU 使用率,還能了解該容器運行的環境版本,這對於追蹤特定版本相關的效能問題非常有幫助。
Node Exporter 同樣提供了類似的 metadata 指標,例如 node_exporter_build_info,它記錄了 Node Exporter 的版本、Go 語言版本等建構資訊。在大規模部署環境中,這些資訊對於版本追蹤和升級管理至關重要。我們可以快速識別出哪些主機還在運行舊版本的 Exporter,並制定相應的升級計劃。
# 統計不同 Node Exporter 版本的主機數量
count by (version) (node_exporter_build_info)
# 查詢仍在使用舊版 Node Exporter 的主機
node_exporter_build_info{version!~"v1\\.7\\..*"}
這種 metadata 模式的應用不僅限於官方的 Exporter。在開發自訂的 Exporter 時,我們也應該考慮加入類似的 metadata 指標。例如,如果我們為特定的應用程式開發了 Exporter,可以加入應用程式版本、配置雜湊值、部署時間戳等資訊。這些資訊在進行變更追蹤和關聯分析時會非常有用。
記錄規則的系統化設計與最佳實務
當 Prometheus 監控系統逐漸成熟,我們會發現某些 PromQL 查詢被頻繁使用,或是某些複雜的計算需要在多個地方重複執行。這時候,記錄規則(Recording Rules)就成為優化監控架構的關鍵工具。記錄規則允許我們預先計算並儲存查詢結果,將其轉換為新的時間序列,從而大幅提升查詢效能和系統響應速度。
記錄規則的概念類似於資料庫中的物化視圖(Materialized View)。與其每次都執行複雜的查詢運算,我們可以定期執行這些運算並將結果儲存起來。當需要查詢時,直接讀取預先計算好的結果,避免了重複計算的開銷。這在處理大量時間序列資料或需要執行複雜聚合運算時特別有效。
記錄規則的設計需要考慮多個面向。首先是計算頻率的選擇,這由 Prometheus 配置檔案中的 evaluation_interval 參數控制。太頻繁的計算會增加系統負載,但太稀疏的計算可能導致資料時效性不足。在實務中,通常會根據監控指標的變化速率和查詢需求來決定適當的計算頻率。
# Prometheus 全域配置範例
# 定義了抓取間隔和規則評估間隔
global:
# 指標抓取間隔設定為 15 秒
# 這個間隔決定了 Prometheus 多久向目標發起一次抓取請求
scrape_interval: 15s
# 規則評估間隔同樣設定為 15 秒
# 這個間隔決定了記錄規則和告警規則的執行頻率
# 建議與 scrape_interval 保持一致或略長
evaluation_interval: 15s
# 外部標籤配置
# 這些標籤會附加到所有時間序列和告警上
external_labels:
cluster: 'taiwan-prod'
environment: 'production'
記錄規則的配置需要建立專門的規則檔案,這些檔案通常採用 YAML 格式並遵循特定的結構。良好的檔案組織方式是將不同類型的規則分類存放,例如將節點相關的規則放在 node_rules.yml,容器相關的規則放在 container_rules.yml。這種組織方式不僅便於維護,也讓規則的用途更加清晰。
# 在 prometheus.yml 中引用規則檔案
# 這個配置告訴 Prometheus 載入哪些規則檔案
rule_files:
# 節點監控相關的記錄規則
- "rules/node_rules.yml"
# 容器監控相關的記錄規則
- "rules/container_rules.yml"
# 應用程式監控相關的記錄規則
- "rules/application_rules.yml"
# 告警規則(與記錄規則分開管理)
- "rules/alerts.yml"
記錄規則的定義包含幾個關鍵元素。規則組(Rule Groups)是規則的容器,每個規則組可以包含多個規則,並且可以設定自己的評估間隔。規則本身包含記錄名稱、PromQL 表達式,以及可選的額外標籤。遵循良好的命名慣例對於規則的可維護性至關重要。
Prometheus 官方建議採用 level:metric:operations 的命名格式。其中 level 表示聚合層級,metric 是基礎指標名稱,operations 描述了應用的運算。例如,instance:node_cpu:avg_rate5m 表示這是一個 instance 層級的 node_cpu 指標,應用了 5 分鐘平均速率計算。
# 節點監控記錄規則的完整範例
# 這個檔案定義了一組用於監控節點效能的記錄規則
groups:
# 規則組名稱,用於組織相關的規則
- name: node_recording_rules
# 規則組的評估間隔
# 如果不指定,則使用全域的 evaluation_interval
interval: 15s
# 規則陣列,包含多個記錄規則
rules:
# 第一個規則:計算 CPU 使用率
- record: instance:node_cpu_utilization:rate5m
# PromQL 表達式定義了如何計算這個指標
# 1. rate() 計算 5 分鐘內的每秒變化率
# 2. mode="idle" 選擇 CPU 閒置時間
# 3. avg by (instance) 對每個實例計算平均值
# 4. 1 - idle_rate 得到使用率
# 5. * 100 轉換為百分比
expr: |
(
1 - avg by (instance) (
rate(node_cpu_seconds_total{mode="idle"}[5m])
)
) * 100
# 為新時間序列添加額外標籤
labels:
metric_type: "utilization"
resource: "cpu"
# 第二個規則:計算記憶體使用率
- record: instance:node_memory_utilization:ratio
# 記憶體使用率計算邏輯:
# 1. 取得總記憶體容量
# 2. 減去可用記憶體(包括空閒、快取和緩衝區)
# 3. 除以總容量得到使用率
# 4. 乘以 100 轉換為百分比
expr: |
(
(
node_memory_MemTotal_bytes
- node_memory_MemFree_bytes
- node_memory_Cached_bytes
- node_memory_Buffers_bytes
)
/ node_memory_MemTotal_bytes
) * 100
labels:
metric_type: "utilization"
resource: "memory"
# 第三個規則:計算根檔案系統使用率
- record: instance:node_filesystem_utilization:ratio
# 檔案系統使用率計算:
# 1. 選擇掛載在根目錄的檔案系統
# 2. 計算已使用空間(總容量減去可用空間)
# 3. 除以總容量得到使用率
# 4. 乘以 100 轉換為百分比
expr: |
(
(
node_filesystem_size_bytes{mountpoint="/"}
- node_filesystem_avail_bytes{mountpoint="/"}
)
/ node_filesystem_size_bytes{mountpoint="/"}
) * 100
labels:
metric_type: "utilization"
resource: "filesystem"
mountpoint: "root"
# 第四個規則:計算網路流量速率
- record: instance:node_network_receive:rate5m
# 網路接收流量速率計算:
# 1. rate() 計算 5 分鐘內的每秒變化率
# 2. sum by (instance) 對每個實例的所有網卡求和
# 3. 結果單位為 bytes/second
expr: |
sum by (instance) (
rate(node_network_receive_bytes_total[5m])
)
labels:
metric_type: "rate"
resource: "network"
direction: "receive"
# 第五個規則:計算網路傳送流量速率
- record: instance:node_network_transmit:rate5m
expr: |
sum by (instance) (
rate(node_network_transmit_bytes_total[5m])
)
labels:
metric_type: "rate"
resource: "network"
direction: "transmit"
這個規則檔案展示了記錄規則的多個重要特性。每個規則都預先計算了一個常用的監控指標,從 CPU 使用率到網路流量速率。這些預先計算的指標可以直接在 Grafana 儀表板中使用,或是用於告警規則的條件判斷,大幅提升了查詢效能。
記錄規則還可以用於建立跨資料中心或跨叢集的聚合指標。透過結合 metadata 指標和向量比對,我們可以建立按照地理位置或業務單元聚合的高階指標。這些聚合指標對於管理層的監控視圖特別有用,讓他們能夠快速了解整體系統的健康狀況。
# 跨資料中心聚合的記錄規則範例
groups:
- name: datacenter_aggregation_rules
interval: 30s
rules:
# 按資料中心聚合 CPU 使用率
- record: datacenter:node_cpu_utilization:avg
# 這個規則結合了記錄規則和 metadata 指標
# 1. 使用之前建立的 CPU 使用率記錄規則
# 2. 透過向量比對附加 datacenter 標籤
# 3. 按照 datacenter 進行聚合計算平均值
expr: |
avg by (datacenter) (
instance:node_cpu_utilization:rate5m
* on (instance) group_left(datacenter)
metadata
)
labels:
aggregation_level: "datacenter"
metric_type: "utilization"
resource: "cpu"
# 按資料中心聚合記憶體使用率
- record: datacenter:node_memory_utilization:avg
expr: |
avg by (datacenter) (
instance:node_memory_utilization:ratio
* on (instance) group_left(datacenter)
metadata
)
labels:
aggregation_level: "datacenter"
metric_type: "utilization"
resource: "memory"
# 計算資料中心總體健康分數
# 綜合考慮 CPU、記憶體和磁碟使用率
- record: datacenter:health_score:composite
expr: |
(
(100 - datacenter:node_cpu_utilization:avg) * 0.4 +
(100 - datacenter:node_memory_utilization:avg) * 0.3 +
(100 - avg by (datacenter) (
instance:node_filesystem_utilization:ratio
* on (instance) group_left(datacenter)
metadata
)) * 0.3
)
labels:
aggregation_level: "datacenter"
metric_type: "composite"
resource: "health"
@startuml
!define PLANTUML_FORMAT svg
!theme _none_
skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100
title 記錄規則的評估與時間序列產生流程
participant "Prometheus Server" as prom
participant "規則評估引擎" as engine
database "時間序列資料庫\n(TSDB)" as tsdb
participant "記錄規則檔案\n(node_rules.yml)" as rules
== 初始化階段 ==
prom -> rules : 載入規則配置
rules --> prom : 返回規則定義
prom -> engine : 註冊規則組
note right
規則組資訊:
name: node_recording_rules
interval: 15s
rules: 5 條記錄規則
end note
== 定期評估循環 ==
loop 每 15 秒執行一次
prom -> engine : 觸發規則評估
activate engine
engine -> engine : 解析 PromQL 表達式
note right
instance:node_cpu_utilization:rate5m
計算邏輯解析
end note
engine -> tsdb : 查詢基礎指標
note right
node_cpu_seconds_total{mode="idle"}
過去 5 分鐘的資料點
end note
tsdb --> engine : 返回原始資料
engine -> engine : 執行計算
note right
1. rate() 計算變化率
2. avg by (instance) 聚合
3. 1 - idle_rate 得到使用率
4. * 100 轉換百分比
end note
engine -> engine : 附加額外標籤
note right
labels:
metric_type: "utilization"
resource: "cpu"
end note
engine -> tsdb : 寫入新時間序列
note right
新指標:
instance:node_cpu_utilization:rate5m
值: 計算結果
時間戳: 當前時間
end note
deactivate engine
end
== 查詢使用階段 ==
prom -> tsdb : 查詢記錄規則結果
note right
直接讀取預先計算的結果
無需重複執行複雜運算
end note
tsdb --> prom : 返回快取結果
note bottom
記錄規則的優勢
效能優化
預先計算避免重複運算
查詢響應時間大幅降低
減少 TSDB 的即時計算負載
資料管理
建立可重用的聚合指標
統一計算邏輯避免不一致
支援多層級的指標聚合
最佳實務
遵循命名慣例便於維護
適當的評估間隔平衡效能
透過標籤增強指標描述性
end note
@endumlGrafana 跨平台部署的完整實踐指南
Grafana 作為開源的資料視覺化平台,已經成為 Prometheus 監控系統的標準配套工具。其強大的圖表繪製能力、豐富的儀表板模板,以及靈活的資料來源整合機制,讓監控資料的呈現變得直觀且富有洞察力。然而,要在企業環境中成功部署 Grafana,需要深入理解其在不同作業系統上的安裝方法、配置選項,以及與 Prometheus 的整合技巧。
Grafana 支援多種平台的部署,包括各種 Linux 發行版、Microsoft Windows 和 macOS。每個平台都有其特定的安裝流程和配置考量。在 Linux 環境中,Grafana 通常作為系統服務運行,由 systemd 或其他初始化系統管理。在 Windows 環境中,可以選擇將其註冊為 Windows 服務或直接作為前景程序運行。在 macOS 上,Homebrew 提供了最便捷的安裝和管理方式。
在 Ubuntu 或 Debian 系統上部署 Grafana,我們需要先設定官方的套件倉庫。Grafana 團隊在 PackageCloud 上維護了穩定版本的套件倉庫,透過將其加入系統的套件來源,我們可以使用標準的套件管理工具來安裝和更新 Grafana。這種方式的優勢在於後續的版本升級非常簡單,只需要執行系統更新指令即可。
# Ubuntu/Debian 系統安裝 Grafana 的完整步驟
# 步驟 1: 安裝必要的依賴套件
# 這些工具用於後續的倉庫設定和套件驗證
sudo apt-get install -y apt-transport-https software-properties-common wget
# 步驟 2: 新增 Grafana GPG 金鑰
# 這個金鑰用於驗證套件的真實性和完整性
# 確保下載的套件未被篡改
wget -q -O - https://packages.grafana.com/gpg.key | sudo apt-key add -
# 步驟 3: 新增 Grafana 穩定版本倉庫
# 將 Grafana 官方倉庫加入系統的套件來源清單
# 使用穩定版本倉庫確保系統的穩定性
echo "deb https://packages.grafana.com/oss/deb stable main" | \
sudo tee -a /etc/apt/sources.list.d/grafana.list
# 步驟 4: 更新套件索引
# 從新加入的倉庫獲取最新的套件資訊
sudo apt-get update
# 步驟 5: 安裝 Grafana
# 使用 apt-get 安裝 Grafana 套件
# 這會自動處理所有依賴關係
sudo apt-get install -y grafana
# 步驟 6: 啟用 Grafana 服務
# 設定 Grafana 在系統啟動時自動啟動
sudo systemctl enable grafana-server
# 步驟 7: 啟動 Grafana 服務
# 立即啟動 Grafana 服務
sudo systemctl start grafana-server
# 步驟 8: 檢查服務狀態
# 驗證 Grafana 服務是否正常運行
sudo systemctl status grafana-server
# 步驟 9: 檢視 Grafana 日誌
# 如果遇到問題,可以透過日誌排查
sudo journalctl -u grafana-server -f
在 Red Hat Enterprise Linux、CentOS 或 Fedora 等基於 RPM 的系統上,安裝流程類似但使用不同的套件管理工具。這些系統使用 Yum 或 DNF 作為套件管理器,配置檔案的位置和格式也有所不同。需要特別注意的是 SELinux 的配置,在某些情況下可能需要調整 SELinux 政策才能讓 Grafana 正常運行。
# Red Hat/CentOS/Fedora 系統安裝 Grafana 的完整步驟
# 步驟 1: 匯入 Grafana GPG 金鑰
# 用於驗證 RPM 套件的簽名
sudo rpm --import https://packages.grafana.com/gpg.key
# 步驟 2: 建立 Grafana Yum 倉庫配置檔案
# 在 /etc/yum.repos.d/ 目錄下建立倉庫定義檔案
sudo tee /etc/yum.repos.d/grafana.repo << 'EOF'
# Grafana 官方穩定版本倉庫配置
[grafana]
# 倉庫名稱,顯示在套件管理工具中
name=grafana
# 倉庫的基礎 URL
# $basearch 會自動替換為系統架構(如 x86_64)
baseurl=https://packages.grafana.com/oss/rpm
# 啟用倉庫 GPG 金鑰檢查
# 這是重要的安全機制
repo_gpgcheck=1
# 啟用此倉庫
enabled=1
# 啟用個別套件的 GPG 檢查
gpgcheck=1
# GPG 金鑰的位置
# 第一個是 PackageCloud 的金鑰
# 第二個是 Grafana 的官方金鑰
gpgkey=https://packages.grafana.com/gpg.key
# SSL 驗證設定
# 確保倉庫連線的安全性
sslverify=1
# SSL CA 憑證的位置
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
EOF
# 步驟 3: 清除 Yum 快取
# 確保使用最新的倉庫資訊
sudo yum clean all
# 步驟 4: 安裝 Grafana
# 使用 yum 或 dnf 安裝 Grafana 套件
sudo yum install -y grafana
# 或者在較新的系統上使用 dnf
# sudo dnf install -y grafana
# 步驟 5: 重新載入 systemd 配置
# 確保 systemd 識別新安裝的服務
sudo systemctl daemon-reload
# 步驟 6: 啟用 Grafana 服務
sudo systemctl enable grafana-server
# 步驟 7: 啟動 Grafana 服務
sudo systemctl start grafana-server
# 步驟 8: 配置防火牆規則
# 開放 Grafana 的預設埠 3000
sudo firewall-cmd --permanent --add-port=3000/tcp
sudo firewall-cmd --reload
# 步驟 9: 檢視服務狀態
sudo systemctl status grafana-server
在 Windows 環境中部署 Grafana 需要不同的方法。Windows 版本的 Grafana 以 ZIP 壓縮檔形式提供,需要手動解壓縮並配置。由於 Windows 對於低編號埠(小於 1024)的存取有特殊的權限要求,預設的 3000 埠雖然可以使用,但在某些企業環境中可能會遇到防火牆或安全政策的限制。因此,常見的做法是將埠改為 8080 或其他高編號埠。
# Windows 系統安裝 Grafana 的完整步驟
# 步驟 1: 建立 Grafana 安裝目錄
# 選擇一個適當的位置存放 Grafana 檔案
New-Item -ItemType Directory -Path "C:\Program Files\Grafana" -Force
Set-Location "C:\Program Files\Grafana"
# 步驟 2: 下載 Grafana Windows 版本
# 從官方網站下載最新的穩定版本
# 建議使用 PowerShell 的 Invoke-WebRequest 或直接從瀏覽器下載
# URL 格式: https://dl.grafana.com/oss/release/grafana-{version}.windows-amd64.zip
$grafanaVersion = "10.2.2"
$downloadUrl = "https://dl.grafana.com/oss/release/grafana-$grafanaVersion.windows-amd64.zip"
$zipFile = "grafana-$grafanaVersion.windows-amd64.zip"
# 下載檔案
Invoke-WebRequest -Uri $downloadUrl -OutFile $zipFile
# 步驟 3: 解壓縮 Grafana
# 使用 PowerShell 內建的解壓縮功能
Expand-Archive -Path $zipFile -DestinationPath "." -Force
# 移動檔案到當前目錄
Move-Item -Path "grafana-$grafanaVersion\*" -Destination "." -Force
Remove-Item -Path "grafana-$grafanaVersion" -Recurse -Force
Remove-Item -Path $zipFile -Force
# 步驟 4: 建立自訂配置檔案
# Grafana 的配置透過 custom.ini 檔案進行客製化
$customIniPath = "conf\custom.ini"
# 建立配置檔案並設定基本參數
@"
# Grafana 自訂配置檔案
# 此檔案覆寫 defaults.ini 中的預設設定
[server]
# HTTP 協定設定
protocol = http
# 監聽位址
# 0.0.0.0 表示監聽所有網路介面
http_addr = 0.0.0.0
# HTTP 埠設定
# 更改為 8080 避免 Windows 上的權限問題
http_port = 8080
# 根 URL 路徑
# 如果 Grafana 不在根路徑,需要設定此選項
# root_url = %(protocol)s://%(domain)s:%(http_port)s/grafana/
[database]
# 資料庫類型
# 預設使用 SQLite,適合小型部署
type = sqlite3
# SQLite 資料庫檔案路徑
path = data\grafana.db
[security]
# 管理員使用者的預設密碼
# 首次登入後應立即更改
admin_password = admin
# 密碼雜湊演算法
password_hashing_algo = argon2
[users]
# 允許使用者註冊
# 生產環境建議設為 false
allow_sign_up = false
[auth.anonymous]
# 啟用匿名存取
# 生產環境建議設為 false
enabled = false
[log]
# 日誌模式
# 可選: console, file, syslog
mode = console file
# 日誌等級
# 可選: debug, info, warn, error, critical
level = info
[paths]
# 資料目錄
data = data
# 日誌目錄
logs = data\log
# 外掛目錄
plugins = data\plugins
[alerting]
# 啟用告警功能
enabled = true
"@ | Out-File -FilePath $customIniPath -Encoding UTF8
# 步驟 5: 將 Grafana 加入系統 PATH
# 這樣可以在任何目錄執行 Grafana 命令
$grafanaPath = "C:\Program Files\Grafana\bin"
$currentPath = [Environment]::GetEnvironmentVariable("Path", "Machine")
if ($currentPath -notlike "*$grafanaPath*") {
[Environment]::SetEnvironmentVariable(
"Path",
"$currentPath;$grafanaPath",
"Machine"
)
}
# 更新當前 PowerShell 會話的 PATH
$env:Path += ";$grafanaPath"
# 步驟 6: 建立 Windows 服務
# 使用 NSSM (Non-Sucking Service Manager) 將 Grafana 註冊為服務
# 首先需要下載並安裝 NSSM: https://nssm.cc/download
# 如果已安裝 NSSM,可以使用以下命令建立服務
# nssm install Grafana "C:\Program Files\Grafana\bin\grafana-server.exe"
# nssm set Grafana AppDirectory "C:\Program Files\Grafana"
# nssm set Grafana AppParameters "--config=C:\Program Files\Grafana\conf\custom.ini"
# nssm set Grafana DisplayName "Grafana Server"
# nssm set Grafana Description "Grafana 監控資料視覺化平台"
# nssm set Grafana Start SERVICE_AUTO_START
# 步驟 7: 啟動 Grafana
# 如果設定為服務,使用以下命令
# Start-Service Grafana
# 或者直接執行 Grafana 程序
Start-Process -FilePath "bin\grafana-server.exe" -WorkingDirectory "C:\Program Files\Grafana"
# 步驟 8: 配置 Windows 防火牆規則
# 開放 Grafana 的埠供外部存取
New-NetFirewallRule -DisplayName "Grafana HTTP" `
-Direction Inbound `
-LocalPort 8080 `
-Protocol TCP `
-Action Allow `
-Description "允許存取 Grafana Web 介面"
Write-Host "Grafana 安裝完成!"
Write-Host "請透過瀏覽器存取: http://localhost:8080"
Write-Host "預設帳號: admin"
Write-Host "預設密碼: admin"
在 macOS 環境中,Homebrew 套件管理器提供了最簡潔的安裝方式。Homebrew 是 macOS 上廣泛使用的第三方套件管理器,它簡化了開源軟體的安裝和更新流程。透過 Homebrew 安裝的 Grafana 會自動處理依賴關係,並將配置檔案和資料目錄設定在標準的位置。
# macOS 系統使用 Homebrew 安裝 Grafana 的完整步驟
# 步驟 1: 確認已安裝 Homebrew
# 如果尚未安裝 Homebrew,請先執行以下命令
# /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# 步驟 2: 更新 Homebrew
# 確保 Homebrew 和套件資訊是最新的
brew update
# 步驟 3: 安裝 Grafana
# Homebrew 會自動下載並安裝 Grafana 及其依賴
brew install grafana
# 步驟 4: 檢視 Grafana 的安裝資訊
# 這會顯示配置檔案位置、日誌位置等資訊
brew info grafana
# 步驟 5: 編輯配置檔案(可選)
# Grafana 的配置檔案位於 /usr/local/etc/grafana/grafana.ini
# 可以根據需求進行客製化設定
# nano /usr/local/etc/grafana/grafana.ini
# 步驟 6: 使用 Homebrew Services 啟動 Grafana
# 這種方式會將 Grafana 設定為開機自動啟動
brew services start grafana
# 或者手動啟動 Grafana 伺服器
# 這種方式不會設定為開機啟動
# grafana-server \
# --config=/usr/local/etc/grafana/grafana.ini \
# --homepath=/usr/local/share/grafana
# 步驟 7: 檢查 Grafana 服務狀態
brew services list | grep grafana
# 步驟 8: 檢視 Grafana 日誌
# 日誌檔案位於 /usr/local/var/log/grafana/
tail -f /usr/local/var/log/grafana/grafana.log
# 步驟 9: 停止 Grafana 服務(需要時)
# brew services stop grafana
# 步驟 10: 重新啟動 Grafana 服務(需要時)
# brew services restart grafana
# 步驟 11: 解除安裝 Grafana(需要時)
# brew services stop grafana
# brew uninstall grafana
@startuml
!define PLANTUML_FORMAT svg
!theme _none_
skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100
title Grafana 跨平台部署架構與配置流程
package "Linux 環境" {
component [Ubuntu/Debian\n套件管理] as ubuntu
component [Red Hat/CentOS\n套件管理] as redhat
component [Systemd\n服務管理] as systemd
ubuntu -> systemd : 安裝後註冊服務
redhat -> systemd : 安裝後註冊服務
}
package "Windows 環境" {
component [ZIP 壓縮檔\n手動部署] as winzip
component [NSSM\n服務管理器] as nssm
winzip -> nssm : 註冊為 Windows 服務
}
package "macOS 環境" {
component [Homebrew\n套件管理] as brew
component [Homebrew Services\n服務管理] as brewsvc
brew -> brewsvc : 服務註冊與管理
}
package "Grafana 核心元件" {
database "SQLite/MySQL/PostgreSQL\n配置與資料儲存" as db
component "Web Server\nHTTP 服務" as webserver
component "資料來源管理\nPrometheus/InfluxDB/..." as datasource
component "儀表板引擎\n圖表渲染" as dashboard
component "告警引擎\n通知管理" as alerting
webserver --> db : 讀寫配置
datasource --> db : 儲存連線資訊
dashboard --> datasource : 查詢資料
alerting --> datasource : 評估告警規則
}
systemd --> webserver : 啟動與監控
nssm --> webserver : 啟動與監控
brewsvc --> webserver : 啟動與監控
cloud "使用者存取" {
actor "系統管理員" as admin
actor "開發人員" as dev
actor "運維人員" as ops
}
admin --> webserver : http://hostname:3000\n初始配置
dev --> webserver : 建立儀表板\n設定查詢
ops --> webserver : 監控告警\n問題排查
note right of systemd
Linux 部署特點
系統整合完善
服務管理標準化
日誌整合至 journald
支援自動重啟
效能監控便利
end note
note right of nssm
Windows 部署考量
需要手動配置
埠號避免衝突
防火牆規則設定
服務權限管理
路徑使用反斜線
end note
note right of brewsvc
macOS 部署優勢
Homebrew 簡化安裝
自動處理依賴
配置位置標準化
升級維護方便
與系統整合良好
end note
@endumlPrometheus 與 Grafana 的深度整合實踐
成功部署 Grafana 後,下一步是將其與 Prometheus 整合,建立完整的監控視覺化解決方案。這個整合過程涉及多個層面,從資料來源的配置、儀表板的設計,到告警的設定和使用者權限的管理。透過系統化的整合實踐,我們可以建構出既強大又易用的監控平台。
Grafana 透過資料來源(Data Source)的概念來連接不同的時間序列資料庫。Prometheus 作為資料來源之一,提供了豐富的查詢能力和高效的資料存取。在 Grafana 中配置 Prometheus 資料來源時,需要指定 Prometheus 伺服器的 URL、存取方式(直接存取或透過代理),以及認證資訊(如果啟用了安全認證)。
初次登入 Grafana 時,系統會要求更改預設密碼。這是重要的安全步驟,特別是在生產環境中。更改密碼後,我們就可以開始配置 Prometheus 資料來源。在 Grafana 的主選單中,選擇 Configuration 然後點選 Data Sources,就會進入資料來源管理介面。
# Grafana 資料來源配置範例(以 YAML 格式表示概念)
# 實際配置透過 Grafana Web UI 進行
datasources:
# Prometheus 資料來源配置
- name: Prometheus-Production
# 資料來源類型
type: prometheus
# 存取模式
# proxy: Grafana 伺服器代理存取(推薦)
# direct: 瀏覽器直接存取
access: proxy
# Prometheus 伺服器 URL
# 如果 Grafana 和 Prometheus 在同一主機上,可以使用 localhost
# 否則使用實際的主機名稱或 IP 位址
url: http://localhost:9090
# 基本認證設定(如果 Prometheus 啟用了認證)
basicAuth: false
# basicAuthUser: admin
# basicAuthPassword: password
# 預設設定為預設資料來源
# 建立新儀表板時會自動選擇此資料來源
isDefault: true
# JSON 資料設定
jsonData:
# HTTP 方法
# GET 或 POST,大型查詢建議使用 POST
httpMethod: POST
# 查詢逾時設定(秒)
timeout: 60
# 自訂查詢參數
# 這些參數會附加到所有查詢請求中
customQueryParameters: ""
# 時間間隔設定
# 用於控制查詢的解析度
timeInterval: "15s"
# 版本號
# 用於追蹤配置變更
version: 1
# 唯讀模式
# 設定為 true 時無法透過 UI 修改
editable: true
配置完成後,可以透過測試按鈕驗證 Grafana 是否能成功連接到 Prometheus。如果配置正確,會看到綠色的成功訊息。常見的連接問題包括網路連線失敗、Prometheus 服務未啟動、防火牆阻擋等。透過檢查 Grafana 的日誌,通常可以快速定位問題所在。
成功連接 Prometheus 後,就可以開始建立儀表板。Grafana 的儀表板由多個面板(Panel)組成,每個面板可以顯示不同類型的視覺化圖表。對於 Prometheus 監控資料,最常用的面板類型包括時間序列圖表(用於顯示指標隨時間的變化)、儀表圖(用於顯示當前值)、表格(用於顯示多個指標的對比),以及狀態圖(用於顯示服務的健康狀態)。
{
"dashboard": {
"title": "Node Exporter 完整監控儀表板",
"description": "展示主機資源使用率、網路流量和系統狀態的綜合儀表板",
"tags": ["prometheus", "node-exporter", "infrastructure"],
"timezone": "Asia/Taipei",
"refresh": "30s",
"time": {
"from": "now-6h",
"to": "now"
},
"panels": [
{
"id": 1,
"title": "CPU 使用率",
"type": "timeseries",
"gridPos": {
"x": 0,
"y": 0,
"w": 12,
"h": 8
},
"targets": [
{
"expr": "instance:node_cpu_utilization:rate5m",
"legendFormat": "{{instance}}",
"refId": "A"
}
],
"fieldConfig": {
"defaults": {
"unit": "percent",
"min": 0,
"max": 100,
"thresholds": {
"mode": "absolute",
"steps": [
{"value": 0, "color": "green"},
{"value": 70, "color": "yellow"},
{"value": 90, "color": "red"}
]
}
}
}
},
{
"id": 2,
"title": "記憶體使用率",
"type": "timeseries",
"gridPos": {
"x": 12,
"y": 0,
"w": 12,
"h": 8
},
"targets": [
{
"expr": "instance:node_memory_utilization:ratio",
"legendFormat": "{{instance}}",
"refId": "A"
}
],
"fieldConfig": {
"defaults": {
"unit": "percent",
"min": 0,
"max": 100,
"thresholds": {
"mode": "absolute",
"steps": [
{"value": 0, "color": "green"},
{"value": 80, "color": "yellow"},
{"value": 95, "color": "red"}
]
}
}
}
},
{
"id": 3,
"title": "磁碟使用率",
"type": "gauge",
"gridPos": {
"x": 0,
"y": 8,
"w": 8,
"h": 6
},
"targets": [
{
"expr": "instance:node_filesystem_utilization:ratio",
"legendFormat": "{{instance}}",
"refId": "A"
}
],
"fieldConfig": {
"defaults": {
"unit": "percent",
"min": 0,
"max": 100,
"thresholds": {
"mode": "absolute",
"steps": [
{"value": 0, "color": "green"},
{"value": 75, "color": "yellow"},
{"value": 90, "color": "red"}
]
}
}
}
},
{
"id": 4,
"title": "網路流量",
"type": "timeseries",
"gridPos": {
"x": 8,
"y": 8,
"w": 16,
"h": 6
},
"targets": [
{
"expr": "instance:node_network_receive:rate5m",
"legendFormat": "{{instance}} - 接收",
"refId": "A"
},
{
"expr": "instance:node_network_transmit:rate5m",
"legendFormat": "{{instance}} - 傳送",
"refId": "B"
}
],
"fieldConfig": {
"defaults": {
"unit": "Bps",
"decimals": 2
}
}
},
{
"id": 5,
"title": "系統負載",
"type": "stat",
"gridPos": {
"x": 0,
"y": 14,
"w": 8,
"h": 4
},
"targets": [
{
"expr": "node_load1",
"legendFormat": "1分鐘",
"refId": "A"
},
{
"expr": "node_load5",
"legendFormat": "5分鐘",
"refId": "B"
},
{
"expr": "node_load15",
"legendFormat": "15分鐘",
"refId": "C"
}
]
},
{
"id": 6,
"title": "主機資訊",
"type": "table",
"gridPos": {
"x": 8,
"y": 14,
"w": 16,
"h": 4
},
"targets": [
{
"expr": "metadata * on (instance) group_left(role, datacenter) node_exporter_build_info",
"format": "table",
"refId": "A"
}
],
"transformations": [
{
"id": "organize",
"options": {
"excludeByName": {
"Time": true,
"Value": true
},
"indexByName": {
"instance": 0,
"datacenter": 1,
"role": 2,
"version": 3
},
"renameByName": {
"instance": "主機",
"datacenter": "資料中心",
"role": "角色",
"version": "Exporter 版本"
}
}
}
]
}
]
}
}
這個儀表板範例展示了如何組織多個面板來呈現完整的主機監控資訊。面板的佈局透過 gridPos 屬性控制,Grafana 使用 24 欄的網格系統,每個面板可以指定其起始位置和大小。透過合理的佈局設計,可以讓使用者在一個畫面中快速掌握系統的整體狀況。
除了基本的儀表板功能,Grafana 還提供了變數(Variables)機制,讓儀表板更加靈活。透過變數,我們可以建立參數化的查詢,讓使用者透過下拉選單來選擇要檢視的主機、資料中心或時間範圍。這種動態的儀表板設計大幅提升了可重用性,一個儀表板模板可以適用於多個不同的環境。
# Grafana 儀表板變數配置範例
variables:
# 資料中心選擇變數
- name: datacenter
type: query
label: "資料中心"
# 從 Prometheus 查詢所有唯一的資料中心值
query: label_values(metadata, datacenter)
# 允許多選
multi: true
# 包含全選選項
includeAll: true
# 全選時的值
allValue: ".*"
# 目前選擇的值
current:
text: "All"
value: ["$__all"]
# 排序方式
sort: 1 # 字母順序
# 主機實例選擇變數
- name: instance
type: query
label: "主機實例"
# 根據選擇的資料中心過濾主機清單
query: label_values(metadata{datacenter=~"$datacenter"}, instance)
multi: true
includeAll: true
allValue: ".*"
current:
text: "All"
value: ["$__all"]
# 依賴於 datacenter 變數
refresh: 2 # 當依賴變數改變時重新整理
# 時間範圍選擇變數
- name: time_range
type: custom
label: "時間範圍"
# 自訂選項清單
options:
- {text: "5分鐘", value: "5m"}
- {text: "15分鐘", value: "15m"}
- {text: "30分鐘", value: "30m"}
- {text: "1小時", value: "1h"}
- {text: "6小時", value: "6h"}
- {text: "24小時", value: "24h"}
current:
text: "5分鐘"
value: "5m"
在儀表板的面板查詢中,就可以使用這些變數來動態過濾資料。變數使用 $variable_name 的語法引用,Grafana 會在執行查詢時自動替換為實際選擇的值。這種機制讓同一個儀表板可以輕鬆地在不同的上下文中重複使用。
# 使用變數的 PromQL 查詢範例
# 查詢選定資料中心和主機的 CPU 使用率
instance:node_cpu_utilization:rate5m{
instance=~"$instance",
datacenter=~"$datacenter"
}
# 使用時間範圍變數的查詢
rate(
node_cpu_seconds_total{
mode="idle",
instance=~"$instance"
}[$time_range]
)
監控系統的維運與最佳化策略
建立完整的監控系統後,持續的維運和最佳化同樣重要。監控系統本身也需要被監控,確保其穩定運行和及時發現問題。這包括監控 Prometheus 的資源使用情況、檢查抓取任務的成功率、評估查詢效能,以及定期審查告警規則的有效性。
Prometheus 提供了內建的指標來監控自身的運行狀態。這些指標包括時間序列數量、抓取目標狀態、規則評估時間等。透過這些指標,我們可以及時發現潛在的效能問題或容量瓶頸。當時間序列數量急劇增加時,可能表示有新的服務上線或標籤使用不當導致序列爆炸。當規則評估時間過長時,可能需要最佳化記錄規則的查詢邏輯。
# Prometheus 自身監控的關鍵指標
# 監控時間序列總數
prometheus_tsdb_symbol_table_size_bytes
# 監控活躍的時間序列數量
prometheus_tsdb_head_series
# 監控抓取目標的健康狀態
up{job="node-exporter"}
# 監控規則評估的持續時間
prometheus_rule_evaluation_duration_seconds
# 監控查詢執行時間
prometheus_engine_query_duration_seconds
# 監控 TSDB 的資料塊數量
prometheus_tsdb_blocks_loaded
資料保留策略也是維運的重要環節。Prometheus 預設保留 15 天的資料,但在實務中,我們可能需要根據實際需求調整保留時間。較長的保留時間提供了更豐富的歷史資料供分析,但也會增加儲存空間的需求。可以透過 Prometheus 的啟動參數來配置資料保留策略。
# Prometheus 資料保留配置範例
# 透過命令列參數設定保留時間和大小限制
prometheus \
--config.file=/etc/prometheus/prometheus.yml \
--storage.tsdb.path=/var/lib/prometheus \
--storage.tsdb.retention.time=30d \
--storage.tsdb.retention.size=100GB \
--web.listen-address=0.0.0.0:9090 \
--web.enable-lifecycle \
--web.enable-admin-api
定期備份 Prometheus 的配置檔案和 Grafana 的儀表板定義也是重要的維運實務。配置檔案可以透過版本控制系統管理,這不僅提供了變更歷史的追蹤,也便於在多個環境間同步配置。Grafana 的儀表板可以匯出為 JSON 檔案,同樣可以納入版本控制。
效能最佳化是持續的過程。當監控規模擴大時,我們可能需要考慮採用遠端儲存方案來解決單機 Prometheus 的容量限制。Prometheus 支援多種遠端儲存整合,包括 Thanos、Cortex 等專門為大規模 Prometheus 部署設計的解決方案。這些方案提供了長期儲存、全域查詢視圖和高可用性等企業級功能。
結語
Prometheus 與 Grafana 的組合已經成為現代雲端原生監控的標準方案。透過本文的深入探討,我們完整地涵蓋了從 metadata 指標的靈活運用、向量比對的進階查詢技巧,到記錄規則的系統化設計,以及 Grafana 在多平台環境的完整部署實踐。這些技術的掌握,讓我們能夠建構出既強大又易於維護的企業級監控解決方案。
Metadata 指標的設計模式展示了在大規模監控環境中,如何透過巧妙的架構設計來避免時間序列爆炸的問題。向量比對技術則讓我們能夠執行複雜的關聯查詢,從多個維度分析監控資料。記錄規則透過預先計算來優化查詢效能,是建構高效監控系統的關鍵機制。而 Grafana 的視覺化能力,則將冰冷的數據轉化為直觀易懂的圖表,讓監控資料真正發揮其價值。
在實務應用中,監控系統的成功不僅取決於技術的選擇,更在於是否能夠建立起系統化的維運流程。從指標的規劃、規則的設計、儀表板的組織,到告警的配置,每個環節都需要仔細考量。透過持續的最佳化和調整,監控系統才能真正成為保障業務穩定運行的可靠基石。記住,監控不是一次性的專案,而是需要持續投入和演進的基礎設施。只有深入理解其原理並遵循最佳實務,才能充分發揮 Prometheus 和 Grafana 的威力,為企業的數位化轉型提供堅實的監控保障。