Prometheus 提供強大的監控能力,尤其在容器化環境中。本文將會詳細介紹如何利用 Node Exporter 和 cAdvisor 收集主機和容器的關鍵指標,並說明如何在 Prometheus 設定檔中組態抓取任務。同時,也將會探討服務發現機制與標籤管理的重要性,以及如何有效地利用標籤來組織和查詢監控資料。最後,文章會提供一些最佳實務和常見問題的解決方案,幫助讀者更好地理解和應用 Prometheus 監控系統。

第3章:安裝與入門

磁碟使用

Prometheus 的磁碟使用量取決於儲存的時間序列資料量及其保留時間。預設情況下,指標資料會在本地時間序列資料函式庫中儲存 15 天。資料函式庫的位置和保留時間可透過命令列選項進行控制。

  • --storage.tsdb.path 選項控制時間序列資料函式庫的位置,預設目錄為執行 Prometheus 的目錄下的 data
  • --storage.tsdb.retention 控制時間序列的保留時間,預設為 15d,即 15 天。

磁碟使用最佳化

  • 最適合時間序列資料函式庫的磁碟是 SSD,應優先使用 SSD。
  • 根據每秒 100,000 個樣本的例子,每個樣本在磁碟上大約佔用 1 到 2 位元組。假設每個樣本佔用 2 位元組,那麼保留 15 天的時間序列資料大約需要 259 GB 的磁碟空間。

更多資訊

更多關於 Prometheus 磁碟使用的資訊,請參閱儲存檔案。

第4章:監控節點和容器

在上一章中,我們安裝了 Prometheus 並進行了一些基本組態。我們還從 Prometheus 伺服器本身抓取了一些時間序列資料。在本章中,我們將探討如何使用 Prometheus 監控主機和容器的指標。我們將在一個由三台 Ubuntu 主機組成的叢集上進行演示,這些主機上都執行著 Docker 守護程式。

首先,我們將在每台主機上安裝匯出器,組態節點和 Docker 指標的匯出,並組態 Prometheus 來抓取這些指標。

接下來,我們將監控一些基本的主機資源,包括:

  1. CPU
  2. 記憶體
  3. 磁碟
  4. 可用性

為了確定需要監控的內容,我們將重新審視 USE 方法監控方法論,以幫助識別正確的指標。我們還將探討如何使用 Prometheus 檢測服務狀態和主機可用性。

然後,我們將利用收集到的指標建立一些聚合指標,並將其儲存為記錄規則。

最後,我們將簡要介紹 Grafana,用於對我們收集的一些資料進行基本視覺化。

監控節點

Prometheus 使用稱為匯出器的工具來暴露主機和應用程式上的指標。有許多匯出器可用於各種目的。目前,我們將重點關注一個特定的匯出器:Node Exporter。Node Exporter 是用 Go 編寫的,具有用於各種主機指標的收集器函式庫,包括 CPU、記憶體和磁碟。它還具有一個 textfile 收集器,允許匯出靜態指標,這對於傳送有關節點的資訊或批次作業匯出的指標非常有用。

安裝 Node Exporter

Node Exporter 可作為 tarball 和有限數量的平台上的套件提供。Node Exporter 的 tarball 可從 Prometheus 網站下載,同時提供的還有其他一些匯出器。

讓我們下載並解壓縮適用於 Linux 的 Node Exporter,然後將二進位檔案移動到我們的路徑中。

wget https://github.com/prometheus/node_exporter/releases/download/v0.16.0/node_exporter-0.16.0.linux-amd64.tar.gz
tar -xzf node_exporter-*
sudo cp node_exporter-*/node_exporter /usr/local/bin/

#### 內容解密:

  • 使用 wget 從 GitHub 下載 Node Exporter 的 tarball。
  • 使用 tar 解壓縮下載的 tarball。
  • 使用 sudo cpnode_exporter 二進位檔案複製到 /usr/local/bin/ 目錄下,以便於執行。

測試 Node Exporter 二進位檔案

node_exporter --version

#### 內容解密:

  • 執行 node_exporter --version 以測試 Node Exporter 是否正確安裝並顯示其版本資訊。

組態 Node Exporter

node_exporter 二進位檔案透過旗標進行組態。您可以執行帶有 --help 旗標的二進位檔案以檢視所有可用旗標的列表。

node_exporter --help

#### 內容解密:

  • 使用 --help 旗標執行 node_exporter 以顯示所有可用組態旗標的列表。

預設情況下,node_exporter 在埠 9100 上執行,並在 /metrics 路徑上暴露指標。您可以透過 --web.listen-address--web.telemetry-path 旗標控制介面和埠。

node_exporter --web.listen-address=":9600" --web.telemetry-path="/node_metrics"

#### 內容解密:

  • 使用 --web.listen-address 旗標將 node_exporter 繫結到埠 9600。
  • 使用 --web.telemetry-path 旗標指定 /node_metrics 路徑作為指標暴露路徑。

這些旗標還控制哪些收集器被啟用。預設情況下,大多數收集器都被啟用。收集器要麼處於停用狀態,要麼處於啟用狀態,並且…

監控節點與容器

在前面的章節中,我們已經成功地設定了 Prometheus 伺服器。現在,我們將重點放在監控節點和容器上。首先,我們需要了解如何組態 Node Exporter 來收集主機的相關資料。

組態 Node Exporter

Node Exporter 是一個用於收集主機指標的工具,它透過各種收集器(collector)來收集資料。預設情況下,某些收集器是啟用的,但我們可以透過指定相關的 flag 來停用或啟用它們。例如,arp 收集器預設是啟用的,它透過 --collector.arp flag 來控制。要停用它,我們可以執行:

停用 arp 收集器

$ node_exporter --no-collector.arp

組態 Textfile 收集器

Textfile 收集器允許我們公開自定義指標。這些自定義指標可能是批次或 cron 作業的結果,或者來自沒有匯出器的來源。該收集器透過掃描指定目錄中的檔案,提取格式化為 Prometheus 指標的字串,並將它們公開以供抓取。

首先,我們建立一個目錄來存放我們的指標定義檔案。

建立 textfile 目錄

$ mkdir -p /var/lib/node_exporter/textfile_collector

接下來,我們在這個目錄中建立一個新的指標檔案。指標定義使用 Prometheus 文字展示格式。

定義 metadata 指標

metadata{role="docker_server",datacenter="NJ"} 1

這裡,我們定義了一個名為 metadata 的指標,它有兩個標籤:roledatacenter。這個指標的值是靜態的 1,因為它提供了上下文資訊而不是記錄計數器或計量器。

我們將這個指標寫入到 metadata.prom 檔案中。

建立 metadata.prom 檔案

$ echo 'metadata{role="docker_server",datacenter="NJ"} 1' | sudo tee /var/lib/node_exporter/textfile_collector/metadata.prom

要啟用 Textfile 收集器,我們需要指定 --collector.textfile.directory flag,告訴 Node Exporter 去哪裡找到我們的自定義指標。

啟用 systemd 收集器

我們還啟用了 systemd 收集器,它記錄了 systemd 的服務和系統狀態。為了保持資料的乾淨,我們可以透過 --collector.systemd.unit-whitelist flag 指定要收集指標的服務。

執行 Node Exporter

$ node_exporter --collector.textfile.directory /var/lib/node_exporter/textfile_collector --collector.systemd --collector.systemd.unit-whitelist=(docker|ssh|rsyslog).service

從 Node Exporter 抓取資料

現在,我們需要在 Prometheus 伺服器上組態一個新的作業來抓取 Node Exporter 的資料。我們在 prometheus.yml 檔案中新增一個新的 job_namenode 的作業。

新增 node 作業

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']
  - job_name: 'node'
    static_configs:
      - targets: ['138.197.26.39:9100', '138.197.30.147:9100', '138.197.30.163:9100']

新增完成後,我們重新載入 Prometheus 的組態,或者重啟 Prometheus 伺服器,這樣它就會開始抓取 Node Exporter 的資料。

在伺服器端過濾收集器

Node Exporter 可以傳回大量的指標,但我們可能不想要全部收集它們。Prometheus 提供了一種方法,可以在伺服器端限制實際抓取的收集器。這對於我們不能控制主機組態的情況尤其有用。

我們可以透過在作業組態中新增特定的收集器列表來實作這一點。

篩選收集器的原理

Prometheus 透過在 job_name 組態中新增 params 部分來指定要抓取的收集器。例如:

scrape_configs:
  - job_name: 'node'
    static_configs:
      - targets: ['138.197.26.39:9100', '138.197.30.147:9100', '138.197.30.163:9100']
    params:
      collect[]:
        - cpu
        - meminfo

這樣,Prometheus 只會抓取 cpumeminfo 這兩個收集器的資料。

監控節點與容器

篩選收集器

在設定 Prometheus 時,我們可以透過 params 區塊中的 collect[] 列表來限制所收集的指標。以下是一個範例設定:

scrape_configs:
  ...
  - job_name: 'node'
    static_configs:
      - targets: ['138.197.26.39:9100', '138.197.30.147:9100', '138.197.30.163:9100']
    params:
      collect[]:
        - cpu
        - meminfo
        - diskstats
        - netdev
        - netstat
        - filefd
        - filesystem
        - xfs
        - systemd

內容解密:

  • scrape_configs:定義 Prometheus 的抓取設定。
  • job_name: 'node':指定作業名稱為 ’node’,用於識別不同的抓取目標。
  • static_configs:使用靜態設定來定義目標主機。
  • targets:列出需要抓取指標的目標主機及其埠號。
  • params:定義額外的引數,這裡用於指定要收集的指標。
  • collect[]:列出要收集的指標名稱,例如 cpumeminfo 等。

我們可以使用 curl 命令來測試這些引數的效果:

$ curl -g -X GET http://138.197.26.39:9100/metrics?collect[]=cpu

這個命令會傳回 Node Exporter 的基本指標以及 CPU 收集器生成的指標,而忽略其他指標。

監控 Docker

要監控 Docker,我們可以使用 Google 的 cAdvisor 工具。cAdvisor 是一個執行在 Docker 容器內的工具,可以收集 Docker 主機及其上執行的容器的指標。

執行 cAdvisor

我們可以使用以下命令來執行 cAdvisor 容器:

$ docker run \
  --volume=/:/rootfs:ro \
  --volume=/var/run:/var/run:rw \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  --volume=/dev/disk/:/dev/disk:ro \
  --publish=8080:8080 \
  --detach=true \
  --name=cadvisor \
  google/cadvisor:latest

內容解密:

  • --volume:掛載主機的目錄到容器內,以便 cAdvisor 可以收集相關資料。
    • /:/rootfs:ro:掛載主機根目錄為唯讀,供 cAdvisor 使用。
    • /var/run:/var/run:rw:掛載 Docker socket 目錄為讀寫,供 cAdvisor 與 Docker 互動。
    • /sys:/sys:ro/var/lib/docker/:/var/lib/docker:ro/dev/disk/:/dev/disk:ro:掛載其他必要的目錄為唯讀,供 cAdvisor 收集資料。
  • --publish=8080:8080:將容器的 8080 埠對映到主機的 8080 埠,以便存取 cAdvisor 的網頁介面和 Prometheus 指標。
  • --detach=true:以背景模式執行容器。
  • --name=cadvisor:將容器命名為 cadvisor。
  • google/cadvisor:latest:使用最新的 google/cadvisor 映象。

執行後,我們可以使用 docker ps 命令來確認 cAdvisor 容器是否正在執行。

從 cAdvisor 抓取指標

要在 Prometheus 中抓取 cAdvisor 的指標,我們需要在 prometheus.yml 設定檔中新增一個作業:

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']
  - job_name: 'node'
    static_configs:
      - targets: ['138.197.26.39:9100', '138.197.30.147:9100', '138.197.30.163:9100']
  - job_name: 'docker'
    static_configs:
      - targets: ['138.197.26.39:8080', '138.197.30.147:8080', '138.197.30.163:8080']

內容解密:

  • 新增了一個名為 docker 的作業,用於抓取 cAdvisor 的指標。
  • targets 中列出了執行 cAdvisor 的 Docker 主機及其埠號(8080)。

重新載入 Prometheus 設定後,它將開始抓取 cAdvisor 的指標,並將新的時間序列資料儲存起來。

抓取生命週期

Prometheus 每隔一段時間(由 scrape_interval 定義)就會執行一次抓取作業。在這個過程中,Prometheus 會根據服務發現機制生成目標列表。在我們的例子中,我們使用了靜態設定來手動指定目標主機。

圖示說明:

  graph LR;
    A[Prometheus] -->|scrape_interval| B[抓取作業];
    B --> C[服務發現];
    C --> D[生成目標列表];
    D --> E[抓取指標];

此圖示展示了 Prometheus 的抓取流程,包括根據設定的時間間隔觸發抓取作業,並透過服務發現機制生成目標列表,最終抓取指標資料。

監控節點與容器

服務發現與標籤管理

在 Prometheus 中,服務發現(Service Discovery)扮演著至關重要的角色。它能夠傳回一系列目標(Targets)並附上一組標籤(Labels),這些標籤被稱為後設資料(Metadata)。這些後設資料標籤通常以 __meta_ 為字首,不同的服務發現機制會提供不同的後設資料。例如,AWS EC2 的服務發現機制會傳回例項的可用區域,並將其儲存在名為 __meta_ec2_availability_zone 的標籤中。

除了後設資料之外,服務發現還會根據目標的組態設定額外的標籤,這些標籤以 __ 為字首和字尾。它們包括 __scheme____address____metrics_path__ 等,分別代表目標的協定(http 或 https)、地址和指標路徑。這些標籤的預設值通常是預先定義好的,例如 __metrics_path__ 預設為 /metrics,而 __scheme__ 預設為 http。如果路徑中包含任何 URL 引數,那麼這些引數也會被設定為以 __param_* 為字首的標籤。

在抓取(Scrape)的生命週期中,這些組態標籤會被重複使用,以填充其他標籤。例如,指標上的 instance 標籤的預設內容就是來自 __address__ 標籤的內容。

覆寫已發現的標籤

Prometheus 允許在組態中覆寫某些標籤,例如透過 metrics_path 引數來指定指標路徑,或透過 scheme 引數來指定使用的協定。以下是一個範例組態:

scrape_configs:
  - job_name: 'node'
    scheme: https
    metrics_path: /moremetrics
    static_configs:
      - targets: ['138.197.26.39:9100', '138.197.30.147:9100', '138.197.30.163:9100']

在這個範例中,我們將協定改為 https,並將指標路徑改為 /moremetrics

標籤的重新標記與過濾

在抓取生命週期中,Prometheus 提供了機會對目標進行重新標記(Relabeling)和過濾。這使得我們可以根據服務發現所新增的後設資料來調整目標,或者過濾掉某些不需要的目標。同樣,在抓取指標時,我們也有機會對指標進行重新標記和過濾,然後再將它們儲存到伺服器。

簡化的抓取生命週期

下圖展示了簡化的抓取生命週期:

  graph LR
    A[服務發現] -->|傳回目標與標籤|> B[重新標記目標]
    B --> C[抓取指標]
    C -->|傳回指標|> D[重新標記指標]
    D --> E[儲存到伺服器]

內容解密:

此圖示展示了 Prometheus 的抓取生命週期。首先,服務發現傳回一系列目標和相關的後設資料。接著,Prometheus 對這些目標進行重新標記和過濾。然後,Prometheus 對篩選出的目標進行指標抓取。抓取到的指標再次經過重新標記和過濾,最後被儲存到伺服器中。

標籤的重要性與管理

標籤在 Prometheus 中至關重要,它們定義了時間序列的維度,並為時間序列增加了上下文。結合指標名稱,標籤構成了時間序列的身份。如果標籤發生變化,那麼時間序列的身份也會隨之改變。因此,應該謹慎使用標籤,並盡量保持它們的一致性。

標籤分類別

在設計標籤時,建立一個合理的分類別體系(Taxonomy)是非常重要的。可以將標籤分為拓撲(Topological)標籤和示意(Schematic)標籤。拓撲標籤描述了服務元件的物理或邏輯結構,例如資料中心的位置。Prometheus 自動為每個指標提供了兩個拓撲標籤:jobinstancejob 標籤來自於抓取組態中的任務名稱,而 instance 標籤通常是目標的 IP 地址和埠。

示意標籤則用於描述一些特定的屬性,例如 URL、錯誤程式碼或使用者等,這些屬性使得我們可以在相同的拓撲層級上對時間序列進行比較。

合理的標籤層次結構

在新增額外的標籤時,可以考慮建立一個類別似下圖所示的層次結構:

  graph TD
    A[環境] --> B[資料中心]
    B --> C[叢集]
    C --> D[主機]
    D --> E[服務]

內容解密:

此圖示展示了一個可能的標籤層次結構。首先是最頂層的環境分類別,接著是資料中心、叢集、主機和服務。這種層次結構有助於我們更好地組織和管理監控資料。

透過合理地使用和管理標籤,我們可以更好地維護時間序列的一致性和可管理性,從而提高監控系統的效率和準確性。