Grafana 監控系統是否重啟
- 2020 年 2 月 24 日
- 筆記
一、概述
Linux 內核(以下簡稱內核)是一個不與特定進程相關的功能集合,內核的代碼很難輕易的在調試器中執行和跟蹤。開發者認為,內核如果發生了錯誤,就不應該繼續運 行。因此內核發生錯誤時,它的行為通常被設定為系統崩潰,機器重啟。基於動態存儲器的電氣特性,機器重啟後,上次錯誤發生時的現場會遭到破壞,這使得查找 內核的錯誤變得異常困難。
線上的k8s集群,有時候回出現重啟的現象,但是什麼原因導致重啟,無法得知。
Kdump
Kdump 是一種基於 kexec 的內存轉儲工具,目前它已經被內核主線接收,成為了內核的一部分,它也由此獲得了絕大多數 Linux 發行版的支持。與傳統的內存轉儲機制不同不同,基於 Kdump 的系統工作的時候需要兩個內核,一個稱為系統內核,即系統正常工作時運行的內核;另外一個稱為捕獲內核,即正常內核崩潰時,用來進行內存轉儲的內核。
關於如何設置 kump,請參考鏈接:
https://blog.csdn.net/bytxl/article/details/45025183
因此,線上已經部署了Kdump,用來捕捉崩潰
二、監控腳本
系統什麼時間發生了重啟?不知道。所以需要有一個腳本來監測一下,一旦發生重啟,就可以使用 crash分析內存轉儲文件
怎麼知道系統重啟
在ubuntu系統中,有一個 last reboot 命令,它會顯示系統重啟的歷史列表
執行命令,效果如下:
root@localhost:~# last reboot reboot system boot 4.4.0-119-generi Mon Jan 7 13:50 still running reboot system boot 4.4.0-119-generi Sat Jan 5 11:48 - 13:49 (2+02:01) reboot system boot 4.4.0-62-generic Sat Jan 5 10:37 - 11:47 (01:10) wtmp begins Sat Jan 5 10:37:40 2019
在第一行,也就是最近一次的重啟記錄。
判斷條件
怎麼知道昨天,系統有沒有重啟呢?
很簡單,先用 last reboot 獲取最近一次的重啟時間。再獲取昨天的時間,將2個時間做對比,如果一致,就說明昨晚重啟了,否則沒有。
獲取最新一次重啟時間
# 最近一次重啟時間 lately=`last reboot | head -1 | awk '{print $5,$6,$7}'`
昨日時間
# 昨天時間 yesterday=`date -d "-1 days" | awk '{print $1,$2,$3}'`
Prometheus數據
我們需要構造Prometheus數據,將數據發送給Pushgateway,最後由Grafana 展示圖表以及做報警
這裡我們使用shell腳本來構造數據,格式如下:
監控名{destinationName="描述信息",instance="實例,默認值為空"} 值
這些數據,我是放在一個臨時文件 /tmp/check_system_restart 裏面
echo "system_restart{destinationName="system_restart",instance="$HOSTNAME"} 1" > /tmp/check_system_restart
注意:使用由於echo外部使用了雙引號,所以內部再次使用雙引號時,需要使用反斜杠進行轉義才行。
我們知道,在shell裏面,單引號是無法引用變量的,必須使用雙引號!
$HOSTNAME 是linux 系統的一個全局變量,表示主機名
發送數據
cat /tmp/check_system_restart|curl --data-binary @- http://$localIP:9091/metrics/job/system_restart_`echo $localIP | awk -F '.' '{print $NF}'`
解釋:
–data-binary 參數表示 HTTP POST請求中的數據為純二進制數據
$localIP 表示 Pushgateway的ip地址
echo $localIP | awk -F '.' '{print $NF}' 表示獲取ip地址的最後一位
注意:這裡的job後面跟了一段字符串,是為了保證每一台服務器發送的url不一致。這樣監控數據就不會被其他主機覆蓋!
關於Pushgateway 的搭建,請參考鏈接:
https://www.cnblogs.com/xiao987334176/p/9933963.html
添加任務計劃
常規情況下,我們一般使用 crontab -e 命令來添加任務計劃
但是在shell腳本,卻不能這麼操作。
其實,直接修改 /etc/crontab 文件,也可以添加任務計劃
下面一段代碼,用來判斷任務計劃是否已經添加,不存在時,就添加!
if [ `cat /etc/crontab|grep 'check_reboot.sh'|wc -l` -eq 0 ];then cp -f /opt/check_reboot.sh /etc/ && chmod 755 /etc/check_reboot.sh echo "0 * * * * root bash /etc/check_reboot.sh" >>/etc/crontabfi
完整代碼
請將代碼務必放到/opt目錄下,因為代碼路徑寫死了!!!
check_reboot.sh
#!/bin/bash # 最近一次重啟時間 lately=`last reboot | head -1 | awk '{print $5,$6,$7}'` # 昨天時間 yesterday=`date -d "-1 days" | awk '{print $1,$2,$3}'` # 判斷時間是否一致 if [ "$string" == "$yesterday" ];then # 寫入日誌 #echo "$HOSTNAME restarted at $lately" >> /opt/restart.log echo "system_restart{destinationName="system_restart",instance="$HOSTNAME"} 1" > /tmp/check_system_restart else echo "system_restart{destinationName="system_restart",instance="$HOSTNAME"} 0" > /tmp/check_system_restart fi # 獲取geteway服務器ip localIP=`ip addr | grep '192.168' | awk '{print $2}' | cut -d '/' -f 1` # 發送數據給Pushgateway if [ `cat /tmp/check_system_restart|wc -l` -ge 1 ];then cat /tmp/check_system_restart|curl --data-binary @- http://$localIP:9091/metrics/job/system_restart_`echo $localIP | awk -F '.' '{print $NF}'` else curl -X DELETE http://$localIP:9091/metrics/job/system_restart_`echo $localIP | awk -F '.' '{print $NF}'` fi # 添加任務計劃 if [ `cat /etc/crontab|grep 'check_reboot.sh'|wc -l` -eq 0 ];then cp -f /opt/check_reboot.sh /etc/ && chmod 755 /etc/check_reboot.sh echo "0 * * * * root bash /etc/check_reboot.sh" >>/etc/crontab fi
執行腳本,就會自動產生 /tmp/check_system_restart 文件。
查看文件內容
root@localhost:~# cat /tmp/check_system_restart system_restart{destinationName="system_restart",instance="xx-node01"} 0
自動將腳本複製到 /etc/check_reboot.sh,這樣是為了路徑統一,方便添加任務計劃!
最後,會自動添加任務計劃!
任務計劃定義的是每個小時執行一次,為了不等那麼長時間,可以先手動執行一次 /etc/check_reboot.sh 腳本
查看 Pushgateway 數據
就會看到一條job

三、Grafana添加監控
添加一個圖形,標題叫做 昨日系統重啟

設置顯示的值

設置報警策略
當最後一個值等於1時,觸發報警

效果如下:
