Prometheus 作為雲原生時代主流的監控系統,其強大的功能和靈活性使其成為監控容器化應用程式的首選。本文將探討如何設定和使用 Prometheus,從 Grafana 整合到服務發現,再到警示設定,提供一個全面的實戰。首先,我們會介紹如何設定 Grafana 資料源並連線到 Prometheus,接著說明如何建立儀錶板來視覺化監控資料。然後,我們將重點介紹 Prometheus 的服務發現機制,包括根據檔案、DNS 和原生服務探索等不同方法,讓 Prometheus 能夠自動偵測和監控動態變化的目標。最後,我們將探討如何使用 Alertmanager 設定警示規則,以便在系統出現異常時及時通知相關人員。
第4章:監控節點和容器
設定Grafana控制檯
圖4.20展示了Grafana控制檯的初始畫面,其中包含了一個「Getting Started」工作流程。我們的首要任務是將Grafana連線到Prometheus的資料來源。點選「Getting Started」工作流程中的「Add data source」。
新增資料來源
新增資料來源需要指定幾個關鍵細節。首先,我們需要為資料來源命名,在這裡我們將其命名為「Prometheus」。接下來,我們需要勾選「Default」核取方塊,以告訴Grafana預設從這個資料來源搜尋資料。此外,我們還需要確保資料來源的「Type」設定為「Prometheus」。
設定HTTP設定
我們還需要為資料來源指定HTTP設定,這包括了Prometheus伺服器的URL。假設我們在與Prometheus相同的機器上執行Grafana,那麼我們的本地伺服器URL就是http://localhost:9090
。如果Prometheus執行在其他機器上,我們就需要指定正確的URL,並確保Grafana主機與Prometheus伺服器之間的連線是通暢的。
注意: Prometheus伺服器必須正在執行,Grafana才能檢索到資料。
此外,我們還需要將「Access」選項設定為「proxy」。這個設定並不是為我們的連線組態HTTP代理,而是告訴Grafana使用其自身的Web服務來代理與Prometheus的連線。「proxy」設定比「direct」更加實用,因為它由Grafana服務負責處理連線問題。
驗證資料來源
點選「Add」按鈕來新增我們的資料來源。如果一切設定正確,我們應該能在螢幕上看到資料來源已經被儲存並顯示出來。如果出現了「Data source is working」的橫幅,那麼就表示我們的資料來源正在運作。
建立第一個儀錶板
回到「Getting Started」工作流程後,點選「New dashboard」按鈕來建立新的儀錶板。儀錶板的建立過程相對複雜,超出了本文的範圍,不過有許多資源和範例可以幫助我們學習,包括Grafana的官方檔案和教學。
範例程式碼
{
"dashboard": {
"title": "Node Dashboard",
"panels": [
{
"title": "CPU Usage",
"type": "graph",
"span": 6,
"targets": [
{
"expr": "100 - (avg by(instance) (irate(node_cpu_seconds_total{mode='idle'}[5m])) * 100)",
"legendFormat": "{{ instance }}",
"refId": "A"
}
]
}
]
}
}
內容解密:
title
屬性:定義了儀錶板的標題為「Node Dashboard」。panels
陣列:包含了儀錶板中的各個面板,本例中只有一個用於顯示CPU使用率的圖表。targets
陣列:指定了圖表所使用的Prometheus查詢表示式,用於計算CPU使用率。expr
屬性:使用了PromQL查詢語言來計算CPU使用率,具體計算方式是透過計算非閒置(non-idle)狀態下的CPU時間比例。legendFormat
屬性:用於格式化圖例,本例中使用了{{ instance }}
來顯示例項名稱。
第5章:服務發現
服務發現的重要性
在上一章中,我們手動指定了每個目標主機的IP位址和埠號。然而,這種方法對於大型或動態的主機群來說並不具有擴充套件性。Prometheus透過服務發現機制解決了這個問題,能夠自動檢測、分類別和識別新的目標。
服務發現機制
服務發現可以透過多種機制實作,包括:
- 從組態檔案管理工具填充的檔案中接收目標列表。
- 查詢API(如Amazon AWS API)以取得目標列表。
- 使用DNS記錄傳回目標列表。
範例組態
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']
內容解密:
scrape_configs
屬性:定義了抓取組態,用於指定Prometheus如何抓取指標。job_name
屬性:定義了任務名稱,用於區分不同的抓取任務。static_configs
屬性:指定了靜態組態,用於手動指定目標主機列表。targets
屬性:列出了需要抓取指標的目標主機及其埠號。
第5章:服務探索
檔案基礎的探索
檔案基礎的探索僅比靜態組態稍微進階一些,但它非常適合透過組態管理工具進行組態。使用檔案基礎的探索,Prometheus 會從檔案中讀取目標。這些檔案通常由其他系統生成,例如像 Puppet、Ansible 或 Chef 這樣的組態管理系統,或者從其他來源查詢,例如 CMDB。指令碼或查詢會定期執行或被觸發,以重新填充這些檔案。Prometheus 然後按照指定的排程從這些檔案中重新載入目標。
這些檔案可以是 YAML 或 JSON 格式,並且包含與靜態組態中定義的目標列表類別似的內容。讓我們首先將現有的作業轉移到根據檔案的探索。
清單 5.2:根據檔案的探索
- job_name: node
file_sd_configs:
- files:
- targets/nodes/*.json
refresh_interval: 5m
- job_name: docker
file_sd_configs:
- files:
- targets/docker/*.json
refresh_interval: 5m
...
我們已經將 prometheus.yml
檔案中的 static_configs
區塊替換為 file_sd_configs
區塊。在這些區塊中,我們指定了一個檔案列表,包含在 files
陣列中。我們為每個作業在 targets
父目錄下指定了檔案,並為每個作業建立了一個子目錄。您可以根據需要建立任何結構。
程式碼解說:
file_sd_configs
取代static_configs
:將靜態組態改為根據檔案的服務探索,使目標管理更靈活。files
陣列指定目標檔案:使用*.json
萬用字元載入指定目錄下的所有 JSON 檔案中的目標。refresh_interval
設定重新整理間隔:每隔五分鐘重新載入一次目標檔案,確保目標清單的即時更新。
建立目標目錄結構
讓我們快速建立這個目錄結構。
清單 5.3:建立目標目錄結構
$ cd /etc/prometheus
$ mkdir -p targets/{nodes,docker}
接下來,我們將節點和 Docker 守護程式移動到新的 JSON 檔案中。
清單 5.4:建立 JSON 檔案以儲存目標
$ touch targets/nodes/nodes.json
$ touch targets/docker/daemons.json
將現有目標填入 JSON 檔案
清單 5.5:nodes.json 檔案內容
[{
"targets": [
"138.197.26.39:9100",
"138.197.30.147:9100",
"138.197.30.163:9100"
]
}]
清單 5.6:daemons.json 檔案內容
[{
"targets": [
"138.197.26.39:8080",
"138.197.30.147:8080",
"138.197.30.163:8080"
]
}]
我們也可以用 YAML 格式表達相同的目標列表。
清單 5.7:YAML 格式的 daemons 檔案
- targets:
- "138.197.26.39:8080"
- "138.197.30.147:8080"
- "138.197.30.163:8080"
為目標新增標籤
清單 5.8:新增標籤
[{
"targets": [
"138.197.26.39:8080",
"138.197.30.147:8080",
"138.197.30.163:8080"
],
"labels": {
"datacenter": "nj"
}
}]
在這裡,我們為 Docker 守護程式目標增加了標籤 datacenter
,其值為 nj
。根據檔案的探索會在重新標記階段自動為每個目標新增一個後設資料標籤:__meta_filepath
,其中包含包含目標的檔案的路徑和檔名。
編寫檔案進行檔案探索
由於將目標寫入 JSON 檔案的具體方法取決於目標來源,因此我們不會詳細介紹任何具體實作,但會提供一些高層次的方法概述。
首先,如果您的組態管理工具可以輸出它正在管理的節點列表,那麼這是一個理想的起點。我們在第3章介紹的一些組態管理模組就有這樣的範本。
程式碼解說:
targets
與labels
結構:定義了目標及其對應的標籤,便於 Prometheus 識別和管理。__meta_filepath
後設資料標籤:自動新增,記錄了目標所在的檔案路徑,方便除錯和追蹤。
原生服務探索外掛
一些工具和平台透過原生的服務探索整合來支援 Prometheus。這些外掛使用這些工具和平台現有的資料儲存或 API 傳回目標列表。
目前可用的原生服務探索外掛包括以下平台:
- Amazon EC2
- Azure
- Consul
- Google Compute Cloud
- Kubernetes
Amazon EC2 服務探索外掛
Amazon EC2 服務探索外掛使用 Amazon Web Services EC2 API 取得 EC2 例項列表以用作 Prometheus 的目標。要使用此發現外掛,您需要擁有 Amazon 賬戶和憑據。
服務探索(Service Discovery)深度解析
在現代化的監控系統中,服務探索是至關重要的一環,尤其是在動態變化的雲端環境中。Prometheus 作為領先的監控解決方案,提供了多種服務探索機制,其中 Amazon EC2 服務探索是針對 AWS 環境的重要功能。
設定 EC2 服務探索
要使用 Prometheus 探索 EC2 例項,首先需要在 Prometheus 組態檔案中新增一個新的任務(job)。以下是一個基本的 EC2 服務探索組態範例:
- job_name: amazon_instances
ec2_sd_configs:
- region: us-east-1
access_key: AKIAIOSFODNN7EXAMPLE
secret_key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
內容解密:
job_name
: 定義了一個名為amazon_instances
的任務,用於從 EC2 例項中收集指標。ec2_sd_configs
: 指定使用 EC2 服務探索組態。region
: 設定 AWS 區域為us-east-1
,Prometheus 將在此區域內發現例項。access_key
和secret_key
: 提供 AWS 的存取金鑰,用於身份驗證。
安全處理憑證
直接在組態檔案中硬編碼 access_key
和 secret_key
是不安全的。Prometheus 支援使用 AWS CLI 的本地組態方式,或透過環境變數來提供憑證。如果未指定金鑰,Prometheus 將自動查詢適當的環境變數或在執行 Prometheus 的使用者主目錄中查詢 AWS 憑證。
- job_name: amazon_instances
ec2_sd_configs:
- region: us-east-1
profile: work
內容解密:
profile
: 使用名為work
的 AWS 組態檔來進行身份驗證,這對於多個 AWS 帳戶的情況非常有用。
自定義目標地址
預設情況下,EC2 服務探索會傳回例項的私有 IP 地址,埠為 80,路徑為 /metrics
。可以透過 port
引數自定義埠:
- job_name: amazon_instances
ec2_sd_configs:
- region: us-east-1
port: 9100
內容解密:
port
: 將預設埠從 80 修改為 9100,以適應 Node Exporter 的預設埠。
使用 Relabelling 自定義目標
Relabelling 是 Prometheus 中一個強大的功能,允許在抓取前修改目標的標籤。以下範例展示如何使用 Relabelling 將目標地址從私有 IP 修改為公有 IP,並指定埠:
- job_name: amazon_instances
ec2_sd_configs:
- region: us-east-1
access_key: AKIAIOSFODNN7EXAMPLE
secret_key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
relabel_configs:
- source_labels: [__meta_ec2_public_ip]
regex: '(.*)'
target_label: __address__
replacement: '$1:9100'
內容解密:
relabel_configs
: 定義 Relabelling 組態。source_labels
: 使用__meta_ec2_public_ip
後設資料標籤作為來源。regex
: 使用正規表示式(.*)
捕捉整個來源標籤內容。target_label
: 將結果寫入__address__
標籤。replacement
: 將捕捉的內容字尾:9100
,形成最終的目標地址。
利用 EC2 標籤最佳化例項名稱
除了修改目標地址,還可以利用 EC2 例項的標籤來最佳化例項名稱:
- job_name: amazon_instances
ec2_sd_configs:
- region: us-east-1
relabel_configs:
- source_labels: [__meta_ec2_public_ip]
regex: '(.*)'
target_label: __address__
replacement: '$1:9100'
- source_labels: [__meta_ec2_tag_Name]
target_label: instance
內容解密:
- 第二個 Relabelling 組態使用
__meta_ec2_tag_Name
將例項的Name
標籤值寫入instance
標籤,從而提供更有意義的例項名稱。
第 5 章:服務發現
在 Prometheus 中,服務發現是一個重要的功能,它允許 Prometheus 自動發現並抓取目標服務的指標。在本章中,我們將學習如何使用不同的服務發現機制,包括檔案基服務發現、平台基服務發現和 DNS 服務發現。
修改例項標籤
在 Prometheus 中,每個目標服務都有一個唯一的例項標籤。有時候,我們需要修改這個標籤以便更好地識別目標服務。例如,將 instance="10.2.1.1"
修改為 instance="bastion"
。
node_cpu{cpu="cpu0",instance="10.2.1.1",job="nodes",mode="system"}
to:
node_cpu{cpu="cpu0",instance="bastion",job="nodes",mode="system"}
內容解密:
這段程式碼展示瞭如何修改 Prometheus 中的例項標籤。原本的標籤是 instance="10.2.1.1"
,現在被修改為 instance="bastion"
。這樣做的好處是使指標更容易被解析和理解。
DNS 服務發現
如果檔案基服務發現不適合您的需求,或者您的來源或服務不支援任何現有的服務發現工具,那麼 DNS 發現可能是一個可行的選擇。DNS 發現允許您指定一個 DNS 條目列表,然後查詢這些條目中的記錄以發現目標列表。它依賴於查詢 A、AAAA 或 SRV DNS 記錄。
- job_name: webapp
dns_sd_configs:
- names: [ '_prometheus._tcp.example.com' ]
內容解密:
這段程式碼定義了一個名為 webapp
的任務,並使用 DNS 服務發現來查詢 _prometheus._tcp.example.com
的 SRV 記錄。SRV 記錄是一種用於定義服務在 DNS 組態中的方式,通常由一個或多個目標主機和埠組合構成。
SRV 記錄格式
SRV 記錄的格式如下:
_service._proto.name. TTL IN SRV priority weight port target.
例如:
_prometheus._tcp.example.com. 300 IN SRV 10 1 9100 webapp1.example.com.
_prometheus._tcp.example.com. 300 IN SRV 10 1 9100 webapp2.example.com.
_prometheus._tcp.example.com. 300 IN SRV 10 1 9100 webapp3.example.com.
內容解密:
這段程式碼展示瞭如何定義 SRV 記錄。SRV 記錄包含了服務名稱、協定、名稱、TTL、優先順序、權重、埠和目標主機等資訊。Prometheus 將查詢這些記錄並傳回目標列表。
DNS 目標列表
當 Prometheus 查詢目標時,它將查詢 example.com
域的 DNS 伺服器,並搜尋 _prometheus._tcp.example.com
的 SRV 記錄,然後傳回該條目中的服務記錄。
webapp1.example.com:9100
webapp2.example.com:9100
webapp3.example.com:9100
內容解密:
這段程式碼展示了 DNS 查詢傳回的目標列表。這些目標將被 Prometheus 用於抓取指標。
A 或 AAAA 記錄查詢
除了 SRV 記錄外,Prometheus 也支援查詢 A 或 AAAA 記錄。但是,需要明確指定查詢型別和埠。
- job_name: webapp
dns_sd_configs:
- names: [ 'example.com' ]
type: A
port: 9100
內容解密:
這段程式碼定義了一個名為 webapp
的任務,並使用 DNS 服務發現來查詢 example.com
的 A 記錄。查詢結果將被補充為 :9100
的埠。
第 6 章:警示和 Alertmanager
在本章中,我們將學習如何使用 Prometheus 和 Alertmanager 建立警示系統。首先,我們將討論什麼是好的警示,接著安裝和組態 Alertmanager,然後定義警示規則並觸發警示。
良好的警示
良好的警示應該是及時的、相關的和有用的。它們應該能夠幫助我們快速定位問題並採取相應的措施。
Alertmanager 的安裝和組態
Alertmanager 是 Prometheus 的一個獨立元件,負責處理警示事件。它可以處理重複的警示、抑制警示並將警示通知傳送給相關人員。
警示規則的定義
警示規則是在 Prometheus 中定義的,用於觸發警示事件。這些規則根據 Prometheus 中收集的指標資料。
# 示例警示規則
groups:
- name: example_alerts
rules:
- alert: HighCPUUsage
expr: avg(rate(cpu_usage[5m])) > 0.8
for: 5m
labels:
severity: critical
annotations:
summary: "CPU 使用率過高"
description: "CPU 使用率超過 80% 已持續 5 分鐘。"
內容解密:
這段程式碼定義了一個名為 HighCPUUsage
的警示規則。當 CPU 使用率平均值在過去 5 分鐘內超過 80% 時,將觸發警示。警示的嚴重性被標記為 critical
,並附帶了詳細的描述資訊。