Prometheus 監控系統:雲原生環境的可觀測性根本

在我多年帶領團隊建置雲原生監控架構的經驗中,Prometheus 一直是最核心的工具之一。這套開放原始碼監控系統不僅是 CNCF 畢業專案,更已經成為 Kubernetes 生態系統中的事實標準。當組織開始雲原生轉型時,理解 Prometheus 的運作方式不再是選項,而是必要的技術能力。

在本文中,我將從 Prometheus 的基礎概念出發,帶領讀者瞭解如何有效實作、擴充套件並整合 Prometheus 到您的監控策略中。無論您是剛開始接觸 Prometheus,還是正在為生產環境尋找更穩健的監控解決方案,這篇都能為您提供實用的見解和技術細節。

Prometheus 的本質與定位

Prometheus 的核心功能是作為一個時間序列資料函式庫ime Series Database),專門用於儲存數值型指標。每個時間序列都由一組文字標籤(labels)識別,這使得透過 PromQL 查詢語言進行篩選和分析變得既靈活又強大。

在我為金融科技公司設計監控架構時,經常需要向團隊強調 Prometheus 的定位。因此,先了解 Prometheus 不適合做什麼同樣重要:

  • Prometheus 不是日誌工具:它無法儲存或解析日誌行,其時間序列僅限於數值資料。
  • Prometheus 不是追蹤工具:雖然可以在程式碼中加入 Prometheus 指標,但這些只是指標,不是完整的分散式追蹤解決方案。
  • Prometheus 不是資料湖:雖然它在收集和索引指標方面具有極大的彈性,但 Prometheus 不適合長期儲存大量時間序列資料。

Prometheus 之所以能在雲原生環境中迅速成為標準,主要歸功於幾個關鍵特性:

  1. 簡單的佈署與啟動:在 Kubernetes 叢集中,幾分鐘內就能讓 Prometheus 執行起來。
  2. 自動發現機制:透過 Pod 註解(一些預設就有),Prometheus 可以自動發現並開始抓取指標。
  3. 靈活的標籤系統:使用標籤定義時間序列,相比點分隔的指標模型更加靈活。

Prometheus 指標結構

Prometheus 指標採用標籤(labels)而非點分隔的方式定義時間序列,這種設計使指標具有完全的水平擴充套件性和彈性,消除了點分隔模型的限制和層級結構。然而,這種標籤模型也帶來了基數爆炸(cardinality explosion)的風險,即標籤組合可能產生大量不同的指標。

Prometheus 從應用程式公開的端點以文字格式收集指標。一個 Prometheus 指標通常包含名稱、一組標籤和該標籤組合的數值。例如:

prometheus_metric{label_01="label_A", label_02="label_B"} 1234

此外,通常還會以人類可讀的方式顯示有關指標及其使用的資料類別的其他資訊。

PromQL:Prometheus 的查詢語言

PromQL 是 Prometheus 的專用查詢語言,它允許使用者以非常直覺的方式進行時間序列資料的查詢與分析。在我帶領團隊設計監控儀錶板時,PromQL 的強大功能一直是我們能夠快速診斷問題的關鍵工具。

PromQL 具有以下幾個核心功能:

  1. 標籤選擇器:可以精確選取特定標籤組合的時間序列
  2. 算術運算:支援基本的數學運算,如加減乘除
  3. 聚合函式:提供 sum、avg、min、max 等聚合功能
  4. 範圍向量選擇器:使用 [5m] 這樣的語法選擇特定時間範圍內的資料

以下是一些 PromQL 查詢的例項:

# 選擇特定標籤的指標
http_requests_total{status="200", method="GET"}

# 過去5分鐘的平均請求率
rate(http_requests_total[5m])

# 依照應用程式名稱聚合的CPU使用率
sum by (app) (rate(process_cpu_seconds_total[5m]))

經驗教訓

在實際使用 Prometheus 的過程中,我總結出一些重要的經驗教訓:

  1. 謹慎設計標籤:過多或高基數的標籤會導致效能問題,應該只使用真正需要進行查詢和篩選的標籤。
  2. 留意抓取間隔:較短的抓取間隔可以提供更高的解析度,但會增加 Prometheus 和目標系統的負載。
  3. 使用服務發現:在動態環境中,依賴靜態設定很快就會變得不可管理,應充分利用 Prometheus 的服務發現功能。
  4. 規劃儲存需求:Prometheus 的本地儲存適用於短期資料,長期儲存應考慮使用遠端寫入功能(remote_write)。

安裝 Prometheus

安裝 Prometheus 有多種方式,根據您的環境和需求選擇適當的方法。以下是最常見的幾種安裝方式:

使用 Helm 安裝 (Kubernetes 環境)

在 Kubernetes 環境中,使用 Helm 是安裝 Prometheus 最簡單的方式。以下是基本步驟:

# 新增 Prometheus 社群 Helm 倉函式庫elm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

# 安裝 Prometheus
helm install prometheus prometheus-community/prometheus

這將安裝一個基本的 Prometheus 佈署,包括一個 Prometheus 伺服器和一些基本的 exporters。

使用 Docker 安裝

如果您想在單機環境或開發環境中快速使用 Prometheus,可以使用 Docker:

docker run -d --name prometheus \
  -p 9090:9090 \
  -v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml \
  prom/prometheus

您需要準備一個 prometheus.yml 設定檔案,下面是一個簡單的範例:

global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

二進位安裝

對於一些特殊環境或需要更多自定義的場景,可以直接下載 Prometheus 二進位檔案:

# 下載最新版本
wget https://github.com/prometheus/prometheus/releases/download/v2.40.0/prometheus-2.40.0.linux-amd64.tar.gz

# 解壓
tar xvfz prometheus-*.tar.gz
cd prometheus-*

# 執行
./prometheus --config.file=prometheus.yml

使用 Prometheus Operator (Kubernetes 進階使用)

對於生產環境的 Kubernetes 叢集,我強烈建議使用 Prometheus Operator。它提供了更強大的管理功能和自定義資源定義 (CRDs),使 Prometheus 的管理變得更加簡單:

# 新增 Operator 倉函式庫elm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

# 安裝 Prometheus Operator
helm install prometheus-operator prometheus-community/kube-prometheus-stack

這將安裝一個完整的監控堆積積疊,包括 Prometheus、Alertmanager、Grafana 以及各種 exporters。

驗證安裝

無論使用哪種方式安裝完成後,您可以透過存取 Prometheus 的 Web UI 來驗證安裝是否成功。預設情況下,Prometheus 的 Web UI 執行在 9090 連線埠上:

http://localhost:9090

如果您在 Kubernetes 中安裝,可能需要使用 port-forward 來存取:

kubectl port-forward svc/prometheus-server 9090:80

然後在瀏覽器中存取 http://localhost:9090

Prometheus Exporters:監控第三方應用程式

Prometheus 的生態系統中有一個重要概念是 “exporters”。Exporters 是專門的程式,用於從那些沒有原生支援 Prometheus 指標格式的系統中收集指標,並將其轉換為 Prometheus 可以抓取的格式。

常見的 Exporters

在我的實踐經驗中,以下是一些最常用的 exporters:

  1. Node Exporter:收集主機級別的指標,如 CPU、記憶體、磁碟和網路使用情況
  2. MySQL Exporter:收集 MySQL 資料函式庫能指標
  3. Redis Exporter:監控 Redis 伺服器的效能和狀態
  4. Blackbox Exporter:進行 HTTP、DNS、TCP 和 ICMP 等探測,用於監控服務可用性
  5. cAdvisor:收集容器相關指標,在 Kubernetes 環境中特別有用

Exporter 安裝範例:Node Exporter

以下是安裝和設定 Node Exporter 的步驟,它是用於收集主機系統指標的最常用 exporter:

使用二進位檔案安裝

# 下載 Node Exporter
wget https://github.com/prometheus/node_exporter/releases/download/v1.5.0/node_exporter-1.5.0.linux-amd64.tar.gz

# 解壓
tar xvfz node_exporter-*.tar.gz
cd node_exporter-*

# 執行
./node_exporter

Node Exporter 預設在 9100 連線埠上提供指標。

使用 Docker 安裝

docker run -d --name node-exporter \
  --net="host" \
  --pid="host" \
  -v "/:/host:ro,rslave" \
  prom/node_exporter:latest \
  --path.rootfs=/host

在 Kubernetes 中安裝

在 Kubernetes 環境中,通常透過 守護程式集合 佈署 Node Exporter,確保每個節點上都有一個例項:

apiVersion: apps/v1
kind: 守護程式集合
metadata:
  name: node-exporter
  namespace: monitoring
spec:
  selector:
    matchLabels:
      app: node-exporter
  template:
    metadata:
      labels:
        app: node-exporter
    spec:
      hostNetwork: true
      containers:
      - name: node-exporter
        image: prom/node_exporter:latest
        ports:
        - containerPort: 9100
        volumeMounts:
        - name: proc
          mountPath: /host/proc
          readOnly: true
        - name: sys
          mountPath: /host/sys
          readOnly: true
        - name: root
          mountPath: /rootfs
          readOnly: true
      volumes:
      - name: proc
        hostPath:
          path: /proc
      - name: sys
        hostPath:
          path: /sys
      - name: root
        hostPath:
          path: /

設定 Prometheus 抓取 Node Exporter 指標

安裝 Node Exporter 後,需要設定 Prometheus 來抓取它的指標。將以下內容新增到您的 prometheus.yml 檔案中:

scrape_configs:
  # 其他設定...

  - job_name: 'node'
    static_configs:
      - targets: ['localhost:9100']

如果在 Kubernetes 中使用服務發現,設定可能如下所示:

scrape_configs:
  # 其他設定...

  - job_name: 'kubernetes-nodes'
    kubernetes_sd_configs:
      - role: node
    relabel_configs:
      - source_labels: [__meta_kubernetes_node_address_InternalIP]
        target_label: instance
      - action: labelmap
        regex: __meta_kubernetes_node_label_(.+)

使用 Exporters 的最佳實踐

根據我在多個生產環境中的經驗,以下是使用 exporters 的一些最佳實踐:

  1. 有選擇地啟用收集器:大多數 exporters 允許您選擇性地啟用或停用特定的收集器。只啟用您真正需要的部分可以減少資源消耗。

  2. 使用標籤豐富指標:利用重新標記(relabeling)功能為指標新增有用的連貫的背景與環境資訊,如環境、區域或應用。

  3. 監控 exporters 本身:exporters 也是應用程式,可能會失敗。確保監控它們的狀態

Prometheus 監控的強大基礎:文字格式指標

在現代雲端架構中,監控系統已成為不可或缺的關鍵元素。Prometheus 作為一個為雲原生環境設計的監控工具,憑藉其簡單而強大的指標呈現方式,已成為業界標準。

# HELP prometheus_metric This is the information about the metric.
# TYPE prometheus_metric gauge

這種文字化的指標呈現方式有著獨特優勢。在我建構大型微服務架構時,曾發現這種格式的實用性遠超過其他監控系統。它不需要專門的程式就能檢視應用程式是否正常產生指標,使用者只需開啟網頁瀏覽器,就像瀏覽普通網頁一樣即可檢視指標。這種根據文字的格式也使得探索指標及其標籤變得極為容易。

PromQL:強大而靈活的查詢語言

Prometheus 查詢語言(PromQL)是 Prometheus 生態系統的核心元件之一,它讓監控從被動觀察轉變為主動分析的工具。根據官方檔案,「Prometheus 提供了一種名為 PromQL 的函式查詢語言,讓使用者能夠即時選擇和聚合時間序列資料。查詢結果可以圖形方式呈現、在 Prometheus 的表示式瀏覽器中檢視錶格資料,或透過 HTTP API 被外部系統使用。」

PromQL 的實際應用

在我的職業生涯中,我發現 PromQL 的學習曲線雖然存在,但掌握後的回報是巨大的。你可以建立聚合查詢來合計具有特定標籤的所有指標值,或開始使用不同指標進行簡單的數學運算,生成自己的指標和比率。

隨著實踐經驗的積累,你將能夠透過折疊和分組指標來建立複雜查詢,以提取所需的資訊。這正是 PromQL 語言的強大之處,也是 Prometheus 廣受歡迎的另一個原因。

從視覺化到警示:PromQL 的多重價值

PromQL 不僅用於資料視覺化,還能用於警示系統的構建。Prometheus 允許建立用於警示的規則,這些警示規則可以充分利用 PromQL 的強大功能。你可以比較不同指標、建立不同值之間的比率閾值、設定多重條件等。

這種靈活性是 SRE 團隊能夠精細調整警示系統的關鍵,使其在真正需要時發出警示,同時最小化誤報,並涵蓋所有潛在的災難性場景。

實戰案例:使用 PromQL 構建人工智慧警示

在我參與的一個金融科技專案中,我們需要監控系統錯誤率並在超過特定閾值時發出警示。這種警示不能僅透過計算錯誤總數來實作,因為在系統處理 500 個請求和處理 100 萬個請求時,100 個錯誤的意義截然不同。

PromQL 允許我們在指標之間進行數學函式運算,以獲得比率。例如,以下查詢將取得 HTTP 伺服器的錯誤率:

sum(rate(apache_http_response_codes_total{code=~'4..|5..'}[5m])) /
sum(rate(apache_http_response_codes_total[5m]))

這個查詢首先使用 rate() 函式運算 5 分鐘內 HTTP 回應碼的變化率,透過正規表示式 {code=~'4..|5..'} 篩選出所有 4xx 和 5xx 錯誤碼,然後除以所有回應碼的總變化率,得出錯誤率百分比。

資料函式庫監控

同樣,我們可以使用 PromQL 的數學運算來監控資料函式庫均處理時間。以下查詢透過將處理時間除以資料函式庫的運算元量來計算回應時間:

sum(rate(redis_commands_duration_seconds_total[5m])) /
sum(rate(redis_commands_processed_total[5m]))

這個查詢計算 Redis 命令的平均執行時間,可以用來設定警示當處理時間超過預設閾值時通知維運團隊。