?? 歡迎大家來到景天科技苑??
🎈🎈 養成好習慣,先贊后看哦~🎈🎈
🏆 作者簡介:景天科技苑
🏆《頭銜》:大廠架構師,華為云開發者社區專家博主,阿里云開發者社區專家博主,CSDN全棧領域優質創作者,掘金優秀博主,51CTO博客專家等。
🏆《博客》:Python全棧,前后端開發,小程序開發,人工智能,js逆向,App逆向,網絡系統安全,數據分析,Django,fastapi,flask等框架,云原生k8s,Prometheus監控,linux,shell腳本等實操經驗,網站搭建,數據庫等分享。所屬的專欄:Prometheus監控系統零基礎到進階
景天的主頁:景天科技苑
文章目錄
- PromQL進階用法
- 1、PromQL資源監控案例
- 1.1 監控系統資源方法論
- 1.2 使用USE監控系統資源
- 2、CPU監控案例實踐
- 2.1 CPU重點監控的維度
- 2.2 計算CPU平均使用率
- 2.3 計算CPU飽和度
- 2.4 配置CPU告警規則
- 3、內存監控案例實踐
- 3.1 內存重點監控的維度
- 3.2 計算內存使用率
- 3.3 計算內存飽和度
- 3.4 配置內存告警規則
- 4、磁盤監控案例實踐
- 4.1 磁盤重點監控的維度
- 4.2 計算磁盤空間使用率
- 4.3 計算磁盤IO吞吐量
- 4.4 計算磁盤IOPS
- 4.5 配置磁盤告警規則
- 5、網絡監控案例實踐
- 5.1 網絡重點監控的維度
- 5.2 計算網絡傳輸速率
- 5.3 計算網絡連接數使用率
- 5.4 配置網絡告警規則
PromQL進階用法
1、PromQL資源監控案例
資源監控無外乎CPU,內存,磁盤,網絡等。
怎么監控呢?需要找到具體的指標,尋找指標又要用到方法論,如下:
1.1 監控系統資源方法論
1、Google 的四個黃金指標著眼點在“服務監控”,這四個指標分別是“延遲、
流量、錯誤、飽和度”
2、RED方法主要著眼點在“用戶體驗”,它基于Google的黃金指標,細化了
三個關鍵指標,“請求率、錯誤數、請求處理時間”
3、USE方法主要著眼點在“系統資源”,的使用情況,這三個指標分別是“使
用率、飽和度、錯誤”。因此USE方法是最適合系統資源監控的
1.2 使用USE監控系統資源
在監控CPU、內存、磁盤和?絡等系統資源時,使?USE的?法論是最為合適
的,它要求我們針對每個資源(也就是CPU、內存 、?絡等)分別檢查三個關鍵
方面:使用率、飽和度和錯誤。
使用率:表示資源在占作時占用的平均時間,例如,CPU在過去的60秒內有
30秒被用來執行指令,那么我們可以說這個CPU的使用率是50%。
飽和度:指明資源已經到達或接近其處理能力極限的程度,表明無法再處理
更多的工作量。這通常通過隊列長度等指標來衡量。
錯誤:記錄了資源在運行過程中發生的錯誤事件的次數。網絡監控用的比較多
2、CPU監控案例實踐
2.1 CPU重點監控的維度
對于CPU資源的監控,采用USE方法論通常關注以下幾點:
CPU使用率:衡量CPU在一段時間內處于活躍狀態的百分比。高使用率可能表明系統正在密集執行任務。
CPU飽和度:反映了在某一時間點等待CPU時間的進程數量。高飽和度可能意味著有很多任務在爭奪CPU資源。
錯誤:通常對CPU不太有影響;
案例1:監控CPU1分鐘的平均使用率;
案例2:監控CPU的飽和度;
2.2 計算CPU平均使用率
計算CPU平均使用率的公式: (1 - CPU 空閑率) * 100 = CPU 使用率
第一步:獲取每個CPU模式的變化率,使用irate函數靈敏度更高,反映更接近實際使用率。
rate(node_cpu_seconds_total[1m])
第二步:查詢CPU的空閑時間比率,即CPU處于空閑狀態的時間比例。
irate(node_cpu_seconds_total{mode="idle"}[1m])
第三步:系統可能會有多個CPU核心,因此我們需要通過avg聚合函數來計算CPU平均空閑率,最后按照實例進行分組統計。
avg(irate(node_cpu_seconds_total{mode="idle"}[1m])) by (instance)
第四步:使用1減去每個核心的平均空閑率,得到平均使用率,然后將此值乘以100,轉換為百分比,最終得出CPU的整體平均使用率
(1 - avg(irate(node_cpu_seconds_total{mode="idle"}[1m])) by (instance) ) *100
2.3 計算CPU飽和度
評估主機的CPU飽和度,最常用的方法是跟蹤系統的平均負載。通常情況下,如
果這個負載的值低于CPU核心的數量,可以認為系統運行正常。然而,當平均負
載持續高于CPU核心數量的兩倍時,這通常是CPU已經非常飽和了。
計算CPU飽和度的公式:1分鐘平均負載 / (CPU核?數*2) * 100 = CPU飽和度
的百分比,當大于80%則認為CPU已經接近處理能力的極限。
第一步:獲取1分鐘平均負載值,然后按照實例和job進行分組計算。
sum(node_load1) by (instance,job)
第二步:獲取CPU的核心數,然后乘以2,按實例進行分組計算每個實例的核心數。 這個mode找空閑的還是其他的都可以,因為是要查找CPU核心數
(count(node_cpu_seconds_total{mode="idle"}) by (instance,job) * 2)
第三步:計算CPU飽和度百分比,如果這個百分比大于80%,我們認為CPU已經
非常飽和,并且已經達到了處理能力的極限。
sum(node_load1) by (instance,job) / (count(node_cpu_seconds_total{mode="idle"}) by (instance,job) * 2) * 100 > 80
2.4 配置CPU告警規則
1、定義CPU告警規則組,然后注入兩條規則
cat /etc/prometheus/rules/node_rules.yml
以groups開頭
groups:
- name: CPU告警規則rules:- alert: 節點CPU使用率超過80%expr: ( 1 - avg(irate(node_cpu_seconds_total{mode="idle"}[1m])) by (instance,job) ) * 100 > 80for: 1mlabels:severity: warningannotations:summary: "主機CPU利用率過高,實例:{{ $labels.instance }}, 任務:{{ $labels.job }}"description: "該實例的CPU利用率高于80%,當前利用率:{{ $value }}%。請及時檢查。"- alert: CPU飽和度過高expr: sum(node_load1) by (instance,job) / (count(node_cpu_seconds_total{mode="idle"}) by (instance,job) * 2) * 100 > 80for: 2mlabels:severity: criticalannotations:summary: "CPU飽和度過高,實例:{{ $labels.instance }}, 任務:{{ $labels.job }}"description: "該實例的1分鐘平均CPU負載超過了核心數的兩倍,已經持續2分鐘,當前CPU飽和度:{{ $value }}%。需要立即檢查系統負載情況。"
如果想要prometheus讀取到我們配置的告警規則,需要讓prometheus能夠讀取到該配置文件
我們先看下默認的prometheus.yml配置文件寫法
需要指定告警規則的yml文件路徑
如果告警規則比較多,我們可以指定某個路徑下的所有yml文件
然后執行prometheus熱加載
curl -X POST http://localhost:9090/-/reload
檢查配置文件格式是否正確
./promtool check config prometheus.yml
然后在prometheus的alert界面,就可以看到我們配置的告警規則
3、內存監控案例實踐
3.1 內存重點監控的維度
對于內存資源的監控,采用USE方法論通常關注以下幾點:
1、內存使用率:衡量系統內存被使用的程度。
2、內存飽和度:表明系統內存的負載程度。內存飽和度,通常監控SWAP的使用率來評估。
3、內存錯誤:通常較少發生。
案例1:計算內存使用率;
案例2:計算內存飽和度;
3.2 計算內存使用率
計算內存使用率百分比公式: ( 總內存 - 可用內存)/ 總內存 * 100 = 內存使用率
(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100
3.3 計算內存飽和度
計算內存飽和度百分比公式: (總SWAP - 未使用的SWAP) / 總SWAP * 100> 20
(node_memory_SwapTotal_bytes - node_memory_SwapFree_bytes) / node_memory_SwapTotal_bytes * 100
3.4 配置內存告警規則
1、定義內存告警規則組,然后注入兩條規則
[root@prom-node01 ~]# cat /etc/prometheus/rules/node_rules.yml
groups:
- name: 內存告警規則rules:- alert: 主機內存不足expr: (node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / node_memory_MemTotal_bytes * 100 > 80for: 2mlabels:severity: warningannotations:summary: "主機內存使用率較高, 實例:{{ $labels.instance }}, 任務:{{ $labels.job }}"description: "該實例的內存使用率持續2分鐘高于80%,當前利用率:{{ $value}}%"- alert: 內存飽和度高expr: (node_memory_SwapTotal_bytes - node_memory_SwapFree_bytes) / node_memory_SwapTotal_bytes * 100 > 10for: 2mlabels:severity: warningannotations:summary: "主機內存內存飽和度高, 實例:{{ $labels.instance }}, 任務:{{ $labels.job }}"description: "SWAP內存使用率已連續2分鐘超過10%,表明內存飽和度過高,當前SWAP使用率為:{{ $value }}%。"
我們可以去掉–name 和rules
這樣,告警規則就在一個分組下
如果我們加上,就單獨是一個分組
4、磁盤監控案例實踐
4.1 磁盤重點監控的維度
對于磁盤,我們不光需要度量磁盤使用率,甚至還需要度量 磁盤IO讀寫吞吐量、以及磁盤IOPS
1、磁盤使用率:衡量磁盤空間使用率、Inode使用率;
2、磁盤延遲:有些磁盤明確標注了延遲,我們可以監控磁盤的讀寫延遲,而后進行判定;
3、磁盤飽和度:通過監控I/O吞吐量和IOPS,可以衡量磁盤在繁忙時段的飽和度情況。
案例1:計算磁盤空間使用率、磁盤Inode空間使用率;
案例2:計算磁盤的IO吞吐量的飽和度;
案例3:計算IOPS每秒讀寫次數的飽和度;
常規磁盤的每秒的IOPS能力和IO吞吐量,有標準后,就好基于標準進行觸發器設定,例如當IOPS每秒讀寫次數的飽和度超過80%則需要關注了
4.2 計算磁盤空間使用率
計算磁盤空間使用率:(總的磁盤空間 - 可用的磁盤空間 = 已用的磁盤空間) / 總的磁盤空間 * 100
計算Inode空間使用率:( 總的Inode數 - 可用的inode數) / 總的inode數 * 100
1、計算不同分區的磁盤空間使用率(排除tmpfs的分區)
( node_filesystem_size_bytes{device!="tmpfs"} - node_filesystem_avail_bytes{device!="tmpfs"} ) / node_filesystem_size_bytes{device!="tmpfs"} * 100
2、計算inode使用率(排除tmpfs的分區)
(node_filesystem_files{device!="tmpfs"} - node_filesystem_files_free{device!="tmpfs"} ) / node_filesystem_files{device!="tmpfs"} * 100
4.3 計算磁盤IO吞吐量
I/O吞吐量:衡量在單位時間內磁盤能夠讀寫多少數據量,通常以MB/s(兆字節每秒)為單位。
I/O吞吐量飽和度(%)=(當前IO吞吐量 / 磁盤的最大IO吞吐量能力)× 100
要根據不同的磁盤類型來確定磁盤的最大IO吞吐能力,如果使用云主機,廠商告訴你磁盤的最大吞吐能力為多大
磁盤吞吐量指標
1、模擬IO寫入吞吐量,并限制寫入IO最大20MB/s
yum install pv -ydd if=/dev/zero bs=1M count=10000 | pv -L 20M > /tmp/bigdata
2、獲取當前磁盤最近1分鐘的,寫入吞吐量最大的值,然后按實例進行分組計算,最后將結果轉為MB
max(rate(node_disk_written_bytes_total[1m])) by (instance,job) / 1024 /1024
3、使用當前IO寫入吞吐量 除以 磁盤最大寫入I/O吞吐量30MB/s,而后乘以100,獲取I/O吞吐的飽和度百分比
(max(rate(node_disk_written_bytes_total[1m])) by (instance,job) / 1024 /1024) / 30 * 100
# 告警(當IO寫入吞吐大于80%則觸發告警),round四舍五入取整數
round(max(rate(node_disk_written_bytes_total[1m])) by (instance,job) / 1024/1024 / 30 * 100) > 60
4、模擬IO讀取吞吐量,并限制讀取IO最大20MB/s
# yum install pv -y
pv -L 20M /tmp/bigdata > /dev/null
在這里插入圖片描述
5、獲取當前磁盤最近1分鐘的,讀取吞吐量最大的值,然后按實例進行分組計算,最后將結果轉為MB
max(rate(node_disk_read_bytes_total[1m])) by (instance,job) / 1024 /1024
6、使用當前IO讀取吞吐量 除以 磁盤最大讀取I/O吞吐量30MB/s,而后乘以100,獲取I/O吞吐的飽和度百分比
max(rate(node_disk_read_bytes_total[1m])) by (instance,job) / 1024 /1024 /30 * 100
# 告警(當IO讀取吞吐大于60%則觸發告警)
round(max(irate(node_disk_read_bytes_total[1m])) by (instance,job) / 1024 /1024 /30 * 100 ) > 60
4.4 計算磁盤IOPS
IOPS:衡量在單位時間內磁盤能夠讀寫操作的次數。
IOPS飽和度(%)=(當前IOPS / 磁盤的最大IOPS能力)× 100
iops指標
1、模擬IO寫入,也相當于有大量IOPS
dd if=/dev/zero bs=1M count=10000 | pv -L 100M > /tmp/bigdata
2、獲取當前磁盤最近1分鐘的,IOPS寫入次數的最大的值,然后按實例進行分組計算
max(irate(node_disk_writes_completed_total[1m])) by (instance,job)
3、使用當前IOPS寫入次數 除以 磁盤最大IOPS,這里是120,而后乘以100,獲取IOPS寫入的飽和度百分比
max(irate(node_disk_writes_completed_total[1m])) by (instance,job) / 120 *100
# 告警(當IOPS飽和度大于60%則觸發告警)
round(max(irate(node_disk_writes_completed_total[1m])) by (instance,job) /120 * 100) > 60
4、模擬IO讀取,也相當于有大量IOPS
yum install pv -y
pv -L 50M /tmp/bigdata > /dev/null
5、獲取當前磁盤最近1分鐘的,讀取IOPS最大次數的值,然后按實例進行分組計算
max(irate(node_disk_reads_completed_total[1m])) by (instance,job)
6、使用當前IO讀取吞吐量 除以 磁盤最大讀取I/O吞吐量,而后乘以100,獲取IOPS讀取的飽和度百分比
max(irate(node_disk_reads_completed_total[1m])) by (instance,job) / 120 * 100
# 告警(當IOPS讀取大于60%則觸發告警)
round(max(irate(node_disk_reads_completed_total[1m])) by (instance,job) / 120 * 100) > 60
4.5 配置磁盤告警規則
1、編寫磁盤告警規則文件
groups:
- name: 磁盤告警規則rules:- alert: 磁盤空間告急expr: ( node_filesystem_size_bytes{device!="tmpfs"} - node_filesystem_avail_bytes{device!="tmpfs"} ) / node_filesystem_size_bytes{device!="tmpfs"} * 100 > 70for: 1mlabels:severity: criticalannotations:summary: "實例 {{ $labels.instance }} 磁盤 {{ $labels.mountpoint }}分區空間不足"description: "實例 {{ $labels.instance }} 磁盤 {{ $labels.mountpoint}} 分區空間使用率已超過 70%,當前使用率為 {{ $value }}%,請及時處理。"- alert: 磁盤Inode空間告急expr: (node_filesystem_files{device!="tmpfs"} - node_filesystem_files_free{device!="tmpfs"} ) / node_filesystem_files{device!="tmpfs"} * 100 > 70for: 1mlabels:severity: criticalannotations:summary: "實例 {{ $labels.instance }} 磁盤 {{ $labels.mountpoint }}分區Inode空間不足"description: "實例 {{ $labels.instance }} 磁盤 {{ $labels.mountpoint}} 分區的Inode空間使用率已超過 70%,當前使用率為 {{ $value }}%,請及時處理。"- alert: 磁盤IOPS寫入較高#expr: sum(rate(node_disk_writes_completed_total[1m])) by (instance,job) / 120 * 100 >60#round函數可以對值進行四舍五入expr: round(max(irate(node_disk_writes_completed_total[1m])) by (instance,job) / 120 * 100,0.01) > 60for: 1mlabels:severity: criticalannotations:summary: "實例 {{ $labels.instance }} IOPS每秒寫入次數超過120次/s"description: 目前磁盤IOPS寫入飽和度是 {{ $value }}%,目前磁盤IOPS每秒寫入最大 {{ printf `max(rate(node_disk_writes_completed_total{instance="%s",job="%s"}[1m]))` $labels.instance $labels.job | query | first | value | printf "%.2f" }} 次/s- alert: 磁盤IOPS讀取較高expr: round(max(irate(node_disk_reads_completed_total[1m])) by (instance,job) / 120 * 100) > 60for: 1mlabels:severity: criticalannotations:summary: "實例 {{ $labels.instance }} IOPS每秒讀取次數超過120次/s"description: 目前磁盤IOPS讀取飽和度是 {{ $value }}%,目前磁盤IOPS每秒讀取最大{{ printf `max(rate(node_disk_reads_completed_total{instance="%s",job="%s"}[1m]))` $labels.instance $labels.job | query | first | value | printf "%.2f" }} 次/s- alert: 磁盤IO寫入吞吐較高expr: round(max(rate(node_disk_written_bytes_total[1m])) by (instance,job) / 1024 /1024 / 30 * 100) > 60for: 1mlabels:severity: criticalannotations:summary: "實例 {{ $labels.instance }} 磁盤IO寫入每秒超過最大30MB/s"description: 目前磁盤IO寫?吞吐量的飽和度是 {{ $value }}%。目前磁盤IO寫入吞吐量每秒最大是 {{ printf `max(rate(node_disk_written_bytes_total{instance="%s",job="%s"}[1m])) /1024/1024` $labels.instance $labels.job | query | first | value | printf "%.2f" }}MB/s- alert: 磁盤IO讀取吞吐較高expr: round(max(rate(node_disk_read_bytes_total[1m])) by (instance,job) / 1024 /1024 /30 * 100 ) > 60for: 1mlabels:severity: criticalannotations:summary: "實例 {{ $labels.instance }} 磁盤IO讀取每秒超過最大30MB/s"description: 目前磁盤IO讀取吞吐量的飽和度是 {{ $value }}%。目前磁盤IO讀取吞吐量每秒最大是 {{ printf `max(rate(node_disk_read_bytes_total{instance="%s",job="%s"}[1m])) /1024/1024` $labels.instance $labels.job | query | first | value | printf "%.2f" }}MB/s
5、網絡監控案例實踐
5.1 網絡重點監控的維度
對于網絡,通常使用USE方法監控如下幾個維度:
1、網絡傳輸速率:即當前網絡每秒傳輸的帶寬。
2、網絡飽和度:對于網絡飽和度,通常查看網絡是否丟包嚴重,如果持續有丟包情況則認為目前網絡比較飽和;
3、網絡錯誤率:可以通過監控網絡發送和接收的錯誤來獲得;
案例1:計算網絡每秒傳輸帶寬;
案例2:計算網絡飽和度,例如:當帶寬速率達到100%,并且發送和接收的丟包率持續上升則告警 node_network_transmit_drop_total、node_network_receive_drop_total
案例3:計算網絡TCP連接數使用率;
5.2 計算網絡傳輸速率
網絡傳輸速率 = irate(網絡接口 “發送/接收” 的總數據量) * 8 /1024 /1024 =Mbps
1、模擬帶寬
# 1、在兩個測試的節點上安裝:yum install iperf -y
# 2、服務端運行并指定端口:iperf -s -p 9999
3、客戶端模擬帶寬發送命令,-b指定發送大小,-t指定發送持續時間:iperf -c -p 9999 -b 300M -t 60
2、獲取最大的下載帶寬,也就是每秒能接收多少Mbps
max(irate(node_network_receive_bytes_total[1m]) * 8 / 1024 / 1024) by (instance,job,device)
3、獲取最大的上傳帶寬,也就是每秒能上傳多少Mbps
max(irate(node_network_transmit_bytes_total[1m]) * 8 / 1024 / 1024) by (instance,job,device)
4、假設公司帶寬是500Mbps,我希望達到400Mbps時則觸發告警,計算公式: 網絡每秒傳輸帶寬 / 網絡最大帶寬 * 100 >= 80
下載
max(irate(node_network_receive_bytes_total[1m]) * 8 / 1024 / 1024) by (instance,job,device) / 500 * 100 >= 80
上傳
max(irate(node_network_transmit_bytes_total[1m]) * 8 / 1024 / 1024) by (instance,job,device) / 500 * 100 >= 80
5.3 計算網絡連接數使用率
網絡連接率 = 當前活躍TCP連接數 / 系統內核最大支持的TCP連接數 * 100
(node_nf_conntrack_entries / node_nf_conntrack_entries_limit) * 100
# 告警
(node_nf_conntrack_entries / node_nf_conntrack_entries_limit) * 100 > 80
5.4 配置網絡告警規則
1、配置網絡告警規則
- name: 網絡告警規則rules:- alert: 網絡下載帶寬占用過高,超過80%expr: max(irate(node_network_receive_bytes_total[1m]) * 8 / 1024 / 1024) by (instance,job,device) / 50 * 100 >= 80for: 1mlabels:severity: criticalannotations:summary: "實例 {{ $labels.instance }} 的 {{ $labels.device }} 接口下載流量即將超過公司實際50Mbps"description: 目前下載帶寬已經達到 {{ printf `(irate(node_network_receive_bytes_total{instance="%s",job="%s",device="%s"}[1m]) * 8 / 1024 / 1024)` $labels.instance $labels.job $labels.device | query | first | value | printf "%.2f"}} Mbps/s 目前下載帶寬使用率在 {{ $value }}%- alert: 網絡上傳帶寬占用過高,超過80%expr: max(irate(node_network_transmit_bytes_total[1m]) * 8 / 1024 / 1024) by (instance,job,device) / 50 * 100 >= 80for: 1mlabels:severity: criticalannotations:summary: "實例 {{ $labels.instance }} 的 {{ $labels.device }} 接口上傳流量即將超過公司實際50Mbps"description: 目前上傳帶寬已經達到 {{ printf `(irate(node_network_transmit_bytes_total{instance="%s",job="%s",device="%s"}[1m]) * 8 / 1024 / 1024)` $labels.instance $labels.job $labels.device | query | first | value | printf "%.2f"}} Mbps/s 目前上傳帶寬使用率在 {{ $value }}%- alert: 網絡TCP連接數過高,超過80%expr: node_nf_conntrack_entries / node_nf_conntrack_entries_limit * 100 > 80for: 1mlabels:severity: criticalannotations:summary: "實例 {{ $labels.instance }} 的 tcp連接數超過80%"description: 目前TCP連接數是 {{ printf `node_nf_conntrack_entries{instance="%s",job="%s"}` $labels.instance $labels.job | query | first | value" }} 目前TCP連接使用率是 {{ $value }}%
最后一個TCP的沒法用,我們先去掉