寫在開篇 關於prometheus的高可用方案,經過筆者不斷的研究、對比、和搜索,發現不管是官方、還是各大搜索引擎搜索出來的方案,都不符合筆者的需求。因此,筆者自己設計了一套prometheus主備的方案。該方案是一個很low的方案,但經過不斷的實踐、驗證,最後發現還挺實用。關於本方案,筆者以後還會 ...
寫在開篇
關於prometheus的高可用方案,經過筆者不斷的研究、對比、和搜索,發現不管是官方、還是各大搜索引擎搜索出來的方案,都不符合筆者的需求。因此,筆者自己設計了一套prometheus主備的方案。該方案是一個很low的方案,但經過不斷的實踐、驗證,最後發現還挺實用。關於本方案,筆者以後還會找機會用go或者python開發一個帶UI界面的prometheus主備管理器,讓它的功能更加完善,做到更自動化和智能化。Prometheus是監控領域的新啟之秀,潛力非常大,K8S內置對它直接支持,直接有提供exporter,而K8S又是未來基礎架構的主力軍。而監控方面,prometheus成為未來的主力軍是勝券在握,把它玩透了你絕對不吃虧。好了,前戲有點多了。敬請大家的關註、點贊、轉發。下麵的正式進入主題!!!
- DIY的prometheus主備方案架構圖
方案說明
- 兩台主機(master和slave)分別部署keepalived,讓master主機接管VIP,註意:keepalived建議配置成非搶占模式
- 之所以採用VIP的原因如下:
- 為了方便日常訪問Prometheus頁面和Alertmanager頁面,在主備切換時,可無需更換訪問ip。
- 上層可視化應用(如grafana)通過VIP來對接Prometheus的數據源,當主備切換時,無需在grafana上修改對應的數據源。
- 日常由master主機處於工作狀態,在master中,啟動Promethues和Alertmanager組件,啟動webhook腳本(告警消息推送腳本,用於將告警推送到其他平臺)。
- slave主機備用狀態,在slave中,需要啟動Promethues組件(用於拉取指標數據),啟動Alertmanager組件(用於接收警報消息),這裡註意,webhook腳本需處於停止狀態(不進行告警推送到其他平臺)。這樣做是為了規避推送重覆告警的問題,雖然Alertmanager有自身的去重告警功能,但這樣的設計根本就沒有告警重覆,已經將重覆扼殺在搖籃里了。
- 在接入監控對象時(部署對應的exporter),切記,僅需要在master上做配置即可, slave定期從master拉取配置文件(包括主配置文件、警報規則文件等),定期和master保持配置同步。
- master和slave的配置保持同步,意味著兩邊都會拉取被監控對象的監控指標數據。監控指標的拉取、警報的觸發兩台均一起工作,但告警的推送只有master在負責,slave不負責告警的推送,如果master不可用了,就需要將slave上的webhook腳本手動拉起來,由slave上的webhook腳本接管告警推送的任務。
- 配置文件同步的做法是採用最原始、最簡單、最粗暴的辦法,master和slave的配置文件同步方案如下:
Master主機:
- master提供配置文件下載服務,由python自帶的SimpleHTTPServer模塊實現,且需要在prometheus或alertmanager規範安裝路徑下(如/usr/local/prometheus)進行SimpleHTTPServer模塊的啟動,拉起後,預設的監聽埠是8000。
- master檢測配置文件變化情況,如達到條件則觸發備份和打包新的配置目錄。在master上,設計了一個保存通知動作的文件notice_slave.action,配置發生變化寫入1,配置沒有發生變化寫入0。同時,該檢測腳本作為常駐進程在後臺運行。
Slave主機:
- slave從master下載通知動作的文件notice_slave.action,根據狀態碼(1和0)來決定接下來的動作,如果是1,則:從master下載配置壓縮包、備份原有配置目錄、解壓新下載後的配置壓縮包、熱重啟相關組件(prometheus、alertmanger),如果是0則什麼都不做。
對於配置文件的同步,也是有兩種實現方式的,要麼是推,要麼是拉,筆者的這個方案里是後者,筆者目前之所以折騰零散的shell腳本來去做高可用的管理,是為了能快速解決需求,因此才做了這個簡陋的方案,筆者的原則是:困難的事情簡單做,簡單的事情咱不做(開玩笑哈!!!)。 當然,筆者以後會通過Go或者Python打造一個管理Promtheus主備的工具,且是帶UI的管理工具,敬請期待推出!我不造車,我只造零件。
一、規劃和規範
1. 設備規劃(本示例為測試環境)
角色 | 物理IP | VIP | 安裝組件 | 告警推送方式 |
---|---|---|---|---|
master | 192.168.11.146 | 192.168.11.203(當前接管) | prometheus、alertmanager(均拉起) | webhook方式,腳本拉起 |
slave | 192.168.11.147 | prometheus、alertmanager(均拉起) | webhook方式,腳本不拉起(備用) |
2. 統一安裝路徑規範
master和slave主機的標準安裝路徑均為:/usr/local/,筆者安裝組件後的環境如下:
/usr/local/keepalived (註意:建議keepalived配置成非搶占模式)
/usr/local/prometheus
/usr/local/alertmanager
至於安裝路徑的規範,請自行根據實際情況敲定。
3. prometheus組件配置文件和目錄規範
- 所有配置文件統一標準路徑:/usr/local/prometheus/conf/
- prometheus主配置文件:/usr/local/prometheus/conf/prometheus.yml
- 按業務粒度,一個業務對應一個目錄,業務下不同的監控對象都放在對應的業務目錄下:/usr/local/prometheus/conf/business
特別說明1:請自行在prometheus組件的安裝目錄下創建conf目錄,並將預設的prometheus.yml配置文件移動進去
特別說明2:請自行在prometheus組件的配置文件統一標準路徑(./conf)下創建業務目錄business
特別說明3:業務目錄下,又包含兩個目錄:job和rule,job用於存放監控拉取配置文件,rule用於存放警報規則配置文件
配置文件目錄和業務目錄規劃示範,如下:
/usr/local/prometheus/ # 這是規範的安裝路徑
/usr/local/prometheus/conf/ # 這是規範的配置目錄
/usr/local/prometheus/conf/prometheus.yml # 這是主配置文件
/usr/local/prometheus/conf/business 這是按業務粒度規劃的業務根目錄
# 如下是業務A的規劃案例:
/usr/local/prometheus/conf/business/a_business/ 這是業務a的目錄
/usr/local/prometheus/conf/business/a_business/job/oracle.yml 這是業務a下拉取oracle監控配置數據的yml配置文件
/usr/local/prometheus/conf/business/a_business/rule/oracle.rules 這是業務a下oracle的警報規則rules配置文件
特別說明:上述對業務A的配置文件規劃案例非常重要,請務必參照此規範。
4. alertmanager組件配置文件和目錄規範
關於Alertmanager組件的配置文件,相對來說沒prometheus那麼複雜,主要的規劃還是在prometeus中
- alertmanager的主配置文件統一標準路徑放在prometeheus的conf中:/usr/local/prometheus/conf/alertmanager.yml
5. 備份路徑規範
在master主機上,會自動備份原有的conf配置文件目錄
- Prometheus組件
統一備份路徑為:/usr/local/prometheus/backup/
- Alertmanager組件
不涉及到備份
6. 日誌目錄規範
在master主機和slave主機上運行的腳本日誌均統一存放在指定目錄
- Prometheus組件
統一日誌目錄:/usr/local/prometheus/logs/
- AlertManager組件
統一日誌目錄:/usr/local/alertmanager/logs/
二、組件安裝部署
註意:master和slave均需要安裝如下組件
- keepalived高可用組件
- prometheus監控組件
- alertmanager警報組件
因組件的安裝部署不是本文的主題,所以筆者在這裡就不再撰寫安裝步驟,在此省略了哈,請自行安裝好即可。
三、prometheus配置文件目錄同步部署
說明1:均需要在master和slave上部署文件同步相關腳本
說明2:以下的每一步操作,請均進入到“/usr/local/prometheus/”目錄下進行操作(此目錄是之前已經定為安裝規範的目錄),如您的規範目錄和筆者的不同,請進入到您自己的規範目錄下。
說明3:以下涉及的腳本,涉及的目錄:conf、backup、logs、cfmd5,請自行在規範的目錄下進行創建即可。
1. master部署配置文件下載服務
- 通過python拉起簡單的Http服務,預設監聽埠為8000,創建腳本startPromconfSyncApi.sh
startPromconfSyncApi.sh腳本內容如下:
#!/bin/sh
nohup /usr/bin/python -m SimpleHTTPServer > /dev/null &
運行配置文件下載服務的腳本
sh startPromconfSyncApi.sh
拉起http服務腳本後查看埠
[root@prosvr-master prometheus]# netstat -tulnp | grep 8000
tcp 0 0 0.0.0.0:8000 0.0.0.0:* LISTEN 1293/python
[root@prosvr-master prometheus]#
- 創建配置文件變化檢查腳本startTarPackConf.sh
註意,請在規範的安裝路徑/usr/local/prometheus/下麵創建startTarPackConf.sh腳本,以及創建目錄cfmd5
startTarPackConf.sh腳本內容:
#!/bin/sh
time_log=`date "+%Y-%m-%d %H:%M:%S"`
echo "${time_log} 配置檢查器啟動"
task_wait_sec=4
find ./conf -type f -print0 | xargs -0 md5sum > ./cfmd5/cfmd5.list
while true
do
time_bak=`date "+%Y%m%d%H%M%S"`
time_log=`date "+%Y-%m-%d %H:%M:%S"`
md5sum -c ./cfmd5/cfmd5.list > ./cfmd5/check_cfmd5.log
md5ret=`cat ./cfmd5/check_cfmd5.log | grep "FAILED" | wc -l`
while true
do
if [ ${md5ret} -gt 0 ]
then
echo "${time_log} 配置文件發生變化,觸發備份和打包壓縮"
mv ./conf.tar.gz ./backup/conf.tar.gz_bak_${time_bak}
tar -zcf conf.tar.gz conf/
echo 1 > ./notice_slave.action
curl -X POST http://127.0.0.1:9090/-/reload
break
else
echo 0 > ./notice_slave.action
break
fi
done
find ./conf -type f -print0 | xargs -0 md5sum > ./cfmd5/cfmd5.list
sleep ${task_wait_sec}
done
腳本實現說明:很簡單,就是遞歸搜索conf目錄下的所有配置文件且生成md5值保存在./cfmd5/cfmd5.list,並使用md5sum -c實時檢查./cfmd5/cfmd5.list中的文件md5值是否有變化,且將結果輸出到./cfmd5/check_cfmd5.log,再通過cat ./cfmd5/check_cfmd5.log進行過濾"FAILED"並統計,只要出現有"FAILED",就認為配置文件有發生過變化,要麼是增加了,要麼是現有的配置文件做了修改。統計的結果保存在md5ret變數,判斷條件就是md5ret結果大於0就觸發北方和打包壓縮配置目錄,同時master中的配置文件發生變化後,也會自動觸發熱重啟。接著將狀態碼1寫入到./notice_slave.action文件中,如果沒有變化,將狀態碼就是0。notice_slave.action文件是存儲狀態變化的(在這裡就乾脆叫通知文件吧!)。
關於通知文件(notice_slave.action)設計的詳細說明:對slave端來講,由slave主動拉取這個通知文件並讀取結果,如果是1就觸發拉取master打包好的壓縮目錄並解壓,且繼續熱重啟相應的組件,如果是0就啥也不幹。
關於參數task_wait_sec=4,任務等待時間,master目前配置的是4秒,也就是每隔4秒檢測一次。對於slave端,也有一個pull_wait_sec=2參數(目前是2秒),也就是每隔2秒拉取一次通知文件,並做判斷。這裡要註意,slave的pull_wait_sec拉取時間一定要小於master的task_wait_sec時間,別問為什麼,自己思考去。
拉起配置文件變化檢查腳本
# 拉起
nohup sh ./startTarPackConf.sh >> ./logs/tar_pack.log &
查看進程
[root@prosvr-master prometheus]# ps -aux | grep tar
root 2473 0.0 0.3 113284 848 pts/1 S 09:48 0:02 sh start_tar_pack_conf.sh
拉起後會作為後臺進程常駐,需要停止的話,查看pid,然後kill掉即可。
- 創建啟動prometheus組件,腳本startPrometheusSvr.sh
startPrometheusSvr.sh內容:
#!/bin/sh
nohup ./prometheus --storage.tsdb.retention.time=180d --web.enable-lifecycle --config.file=./conf/prometheus.yml --log.level=warn --log.format=json >> ./logs/prometheus_run_status.log &
數據保留周期是180天,請根據實際情況調整,其他參數的意義請自行help
在上面腳本的啟動參數中,也可以通過參數--storage.tsdb.path="data/"修改本地數據存儲的路徑,不指定的話,時序數據預設是在prometheus的data目錄下,如需修改數據的存儲路徑,建議存放在性能好(SSD、高端磁碟陣列)、容量大的目錄中。
接著啟動prometheus
# 拉起
[root@prosvr-master prometheus]# sh startPrometheusSvr.sh
查看進程,檢查是否啟動成功
[root@prosvr-master prometheus]# ps -aux | grep prometheus
root 1201 0.0 30.1 1100628 66840 pts/0 Sl 08:45 0:22 ./prometheus --web.enable-lifecycle --config.file=./conf/prometheus.yml --log.level=warn --log.format=json
- 為了方便熱重啟操作,創建腳本hot_restart_prometheus.sh,當修改了配置文件後,就手動執行這個腳本進行熱重啟
#!/bin/sh
curl -X POST http://127.0.0.1:9090/-/reload
平滑重啟示例
[root@prosvr-master prometheus]# sh hot_restart_prometheus.sh
在日常維護中,當配置文件發生了變更就可以利用該腳本進行平滑重啟
- 創建彙總啟動腳本start_all.sh
#!/bin/sh
sh ./startPromconfSyncApi.sh
nohup sh ./startTarPackConf.sh >> ./logs/tar_pack.log &
sh ./startPrometheusSvr.sh
以後就不用一個一個腳本拉起了,直接拉起該腳本即可一併啟動
- 為了增加安全性,僅允許slave主機訪問配置文件拉取服務的埠(筆者這裡是8000埠)
在tcp協議中禁止所有的ip訪問本機的8000埠,僅允許slave主機(192.168.11.147)訪問本機的8000埠(註意按順序執行)
iptables -I INPUT -p tcp --dport 8000 -j DROP
iptables -I INPUT -s 192.168.11.147 -p tcp --dport 8000 -j ACCEPT
查看規則
[root@prosvr-master prometheus]# iptables -nvL
Chain INPUT (policy ACCEPT 9 packets, 744 bytes)
pkts bytes target prot opt in out source destination
8 552 ACCEPT tcp -- * * 192.168.11.147 0.0.0.0/0 tcp dpt:8000
0 0 DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8000
保存規則
註意:使用此命令的規則位置可以是任意的,此方式保存的規則在重啟機器後無法自動生效,需要使用命令iptables-restart恢復),筆者這裡是保存在了/etc/sysconfig/my-iptable-rule-script
# 保存
[root@prosvr-master prometheus]# iptables-save > /etc/sysconfig/my-iptable-rule-script
# 查看
[root@prosvr-master prometheus]# cat /etc/sysconfig/my-iptable-rule-script
# Generated by iptables-save v1.4.21 on Mon May 30 10:37:12 2022
*filter
:INPUT ACCEPT [49:4408]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [27:4840]
-A INPUT -s 192.168.11.147/32 -p tcp -m tcp --dport 8000 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 8000 -j DROP
COMMIT
# Completed on Mon May 30 10:37:12 2022
手動清空規則,模擬規則丟失後,從文件中載入
# 查看
[root@prosvr-master prometheus]# iptables -nvL
Chain INPUT (policy ACCEPT 122 packets, 12944 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT tcp -- * * 192.168.11.147 0.0.0.0/0 tcp dpt:8000
0 0 DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8000
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 86 packets, 14400 bytes)
pkts bytes target prot opt in out source destination
[root@prosvr-master prometheus]#
# 手動清空
[root@prosvr-master prometheus]# iptables -F
# 清空後查看
[root@prosvr-master prometheus]# iptables -nvL
Chain INPUT (policy ACCEPT 12 packets, 1056 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 7 packets, 1080 bytes)
pkts bytes target prot opt in out source destination
[root@prosvr-master prometheus]#
# 使用iptables-restore命令還原iptables-save命令所備份的iptables配置
[root@prosvr-master prometheus]# iptables-restore < /etc/sysconfig/my-iptable-rule-script
# 還原後查看
[root@prosvr-master prometheus]# iptables -nvL
Chain INPUT (policy ACCEPT 34 packets, 2992 bytes)
pkts bytes target prot opt in out source destination
0 0 ACCEPT tcp -- * * 192.168.11.147 0.0.0.0/0 tcp dpt:8000
0 0 DROP tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8000
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 18 packets, 2480 bytes)
pkts bytes target prot opt in out source destination
[root@prosvr-master prometheus]#
特別說明:預防規則重啟後丟失的辦法還有一種,就是將配置規則寫入到啟動文件中,如/etc/rc.local,筆者之前將規則保存在/etc/sysconfig/my-iptable-rule-script文件中,那麼就可以將恢復的命令 iptables-restore < /etc/sysconfig/my-iptable-rule-script 寫入到/etc/rc.local中
特別註意:如果您的環境和筆者不一樣,請自行更改為您自己的IP和埠即可。
- 創建彙總停止腳本stop_all.sh
#!/bin/sh
ps -aux | grep SimpleHTTPServer | grep -v grep | awk '{print $2}' | xargs kill
ps aux | grep startTarPackConf.sh | grep -v grep | awk '{print $2}' | xargs kill
ps -aux | grep -v grep | grep prometheus | awk '{print $2}' | xargs kill
日常維護中,如有需要停止全部服務的需求,運行該腳本即可。
2. slave部署配置文件拉取服務
特別說明:在slave主機上,請在規範的目錄下創建conf、logs、backup目錄
- 將首次安裝完成的prometheus.yml文件移動到當前的conf目錄下
mv ./prometheus.yml ./conf/
之所以要移動slave本身的prometheus.yml,是因為要從master同步過來已經規劃好的conf配置目錄,拉取後會覆蓋slave上的conf目錄,以後都以master的配置為主
- 準備啟動prometheus組件的腳本
腳本/usr/local/prometheus/startPrometheusSvr.sh,代碼:
#!/bin/sh
nohup ./prometheus --storage.tsdb.retention.time=180d --web.enable-lifecycle --config.file=./conf/prometheus.yml --log.level=warn --log.format=json >> ./logs/prometheus_run_status.log &
數據保留周期是180天,請根據實際情況調整,其他參數的意義請自行help
在上面腳本的啟動參數中,也可以通過參數--storage.tsdb.path="data/"修改本地數據存儲的路徑,不指定的話,時序數據預設是在prometheus的data目錄下,如需修改數據的存儲路徑,建議存放在性能好(SSD、高端磁碟陣列)、容量大的目錄中。
- 接著啟動prometheus,並檢查是否啟動成功
[root@prosvr-slave prometheus]# sh startPrometheusSvr.sh
[root@prosvr-slave prometheus]# ps -aux | grep prometheus
root 5107 3.7 16.0 768960 35456 pts/0 Sl 17:18 0:00 ./prometheus --web.enable-lifecycle --config.file=./conf/prometheus.yml --log.level=warn --log.format=json
root 5114 0.0 0.4 112812 976 pts/0 R+ 17:18 0:00 grep --color=auto prometheus
You have new mail in /var/spool/mail/root
[root@prosvr-slave prometheus]# netstat -tulnp | grep prometheus
tcp6 0 0 :::9090 :::* LISTEN 5107/./prometheus
[root@prosvr-slave prometheus]#
- 準備從master拉取配置文件目錄的腳本startUpdateSyncConf.sh,代碼:
#!/bin/sh
time_log=`date "+%Y-%m-%d %H:%M:%S"`
echo "${time_log} 配置更新器啟動"
pull_wait_sec=2
while true
do
wget http://192.168.11.146:8000/notice_slave.action -O notice_slave.action > /dev/null 2>&1
status=`cat ./notice_slave.action`
if [ ${status} -eq 1 ]
then
time_bak=`date "+%Y%m%d%H%M%S"`
time_log=`date "+%Y-%m-%d %H:%M:%S"`
echo "${time_log} 從master下載配置壓縮包文件"
wget http://192.168.11.146:8000/conf.tar.gz -O conf.tar.gz
echo "${time_log} 備份原有的配置目錄"
mv ./conf ./backup/conf_bak_${time_bak}
echo "${time_log} 解壓下載後的配置壓縮包"
tar -zxf conf.tar.gz
echo "${time_log} 熱重啟prometheus服務"
curl -X POST http://127.0.0.1:9090/-/reload
fi
sleep ${pull_wait_sec}
done
pull_wait_sec參數控制每隔時間工作一次,首先會從master中拉取通知文件notice_slave.action,並讀取裡面的結果,如果是1,則說明master上的配置文件有變化,接著會執行一系列操作。如果是0,則什麼也不做。
- 創建熱重啟的腳本hot_restart_prometheus.sh
#!/bin/sh
curl -X POST http://127.0.0.1:9090/-/reload
日常維護中,在slave主機上,如有必要時方便手動執行熱重啟
- 創建彙總啟動腳本start_all.sh
#!/bin/sh
nohup sh startUpdateSyncConf.sh > ./logs/update_sync.log &
sleep 3
sh ./startPrometheusSvr.sh
日常維護中,如需一次性拉起服務,執行該腳本即可
- 創建彙總停止腳本stop_all.sh
#!/bin/sh
ps -aux | grep startUpdateSyncConf.sh | grep -v grep | awk '{print $2}' | xargs kill
ps -aux | grep -v grep | grep prometheus | awk '{print $2}' | xargs kill
日常維護中,如需一次性停止服務,執行該腳本即可
四、監控mysql案例
prometheus如何監控mysql?很簡單,只需要在運行mysql的主機上安裝mysqld_exporter,mysqld_exporter的用途是啥?說白了它就是用來收集mysql資料庫相關指標的程式(官方就有,而且是go語言寫的),mysqld_exporter啟動後預設監聽9104埠(當然啟動時可以通過相應參數進行更改),且它連接上資料庫採集相應指標,並等著prometheus伺服器來拉取。所以,需要在mysql中創建一個專門用於採集監控指標的資料庫賬號,讓mysqld_exporter通過這個賬號去登錄資料庫採集指標,且這個賬號要有相關許可權(合適的許可權即可)。所以的合適,請自行根據實際情況決定要給什麼許可權,如果是生產環境,一般的原則是:最小原則、夠用就好。
- mysql測試環境信息
- 以下是筆者的mysql測試環境
資料庫 | 操作系統 | IP |
---|---|---|
mysql8.0 | centos7 | 192.168.11.150 |
說明:本篇只講解如何使用Prometheus監控MySQL,MySQL本身的安裝過程不在本篇範圍內,請自行將MySQL安裝好。
- 下載mysqld_exporter
wget https://github.com/prometheus/mysqld_exporter/releases/download/v0.14.0/mysqld_exporter-0.14.0.linux-amd64.tar.gz
- 登錄mysql創建用於採集指標數據的專有賬戶
# 創建賬號
mysql> create user 'exporter_user'@'localhost' identified by 'Root.123456' with max_user_connections 3;
Query OK, 0 rows affected (0.06 sec)
# 授權
mysql> grant process, replication client, select on *.* to 'exporter_user'@'localhost';
Query OK, 0 rows affected (0.00 sec)
# 刷新許可權
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
# 查看許可權
mysql> show grants for exporter_user@localhost\G;
*************************** 1. row ***************************
Grants for exporter_user@localhost: GRANT SELECT, PROCESS, REPLICATION CLIENT ON *.* TO `exporter_user`@`localhost`
1 row in set (0.00 sec)
ERROR:
No query specified
# 查看賬號
mysql> select user,host from mysql.user;
+------------------+-----------+
| user | host |
+------------------+-----------+
| exporter | localhost | # 這個,筆者曾經創建過的,不管它了
| exporter_user | localhost | # 這個是剛剛創建好的,就用這個啦!
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
| ttr1 | localhost |
+------------------+-----------+
7 rows in set (0.00 sec)
mysql>
關於mysql的資料庫賬號許可權的授權和回收的知識,筆者以後會出一個專題,專門深入淺出的剖析,敬請大家的關註!
- 部署mysqld_exporter
# 下載完成後,解壓,並移動到規定的目錄下(目錄可自定義哈)
tar -zxf mysqld_exporter-0.14.0.linux-amd64.tar.gz
[root@mysql8db ~]# mkdir /usr/local/exporter/
[root@mysql8db ~]# mv mysqld_exporter-0.14.0.linux-amd64 /usr/local/exporter/mysqld_exporter
[root@mysql8db ~]# cd /usr/local/exporter/mysqld_exporter/
[root@mysql8db mysqld_exporter]# ll
total 14824
-rw-r--r-- 1 3434 3434 11357 Mar 5 00:30 LICENSE
-rwxr-xr-x 1 3434 3434 15163162 Mar 5 00:25 mysqld_exporter # 這個就是可執行程式
-rw-r--r-- 1 3434 3434 65 Mar 5 00:30 NOTICE
- 創建連接mysql的配置文件並啟動mysqld_exporter
# 創建連接mysql的配置文件
[root@mysql8db mysqld_exporter]# cat > exporter_conn_mysql.conf <<EOF
> [client]
> user=exporter_user
> password=Root.123456
> EOF
# 查看創建好的配置文件
[root@mysql8db mysqld_exporter]# cat exporter_conn_mysql.conf
[client]
user=exporter_user
password=Root.123456
[root@mysql8db mysqld_exporter]#
- 啟動mysqld_exporter
# 為了方便啟動,創建一個啟動腳本
[root@mysql8db mysqld_exporter]# cat > start_mysqld_exporter.sh <<EOF
> nohup ./mysqld_exporter --config.my-cnf=./exporter_conn_mysql.conf &
> EOF
[root@mysql8db mysqld_exporter]#
# 查看創建好的啟動腳本
[root@mysql8db mysqld_exporter]# cat start_mysqld_exporter.sh
nohup ./mysqld_exporter --config.my-cnf=./exporter_conn_mysql.conf &
[root@mysql8db mysqld_exporter]#
# 開始啟動
[root@mysql8db mysqld_exporter]# sh start_mysqld_exporter.sh
# 啟動後查看相關埠(預設的埠為9104)
[root@mysql8db mysqld_exporter]# netstat -tulnp | grep mysql
tcp6 0 0 :::33060 :::* LISTEN 1916/mysqld
tcp6 0 0 :::3306 :::* LISTEN 1916/mysqld
tcp6 0 0 :::9104 :::* LISTEN 2073/./mysqld_expor # 這個就是啦!
[root@mysql8db mysqld_exporter]#
[root@mysql8db mysqld_exporter]#
說明:咦!--config.my-cnf這個參數我咋知道的?當然是可以使用help啦!這樣 ./mysqld_exporter --help 就可以知道有哪些選項啦!
還有一個奇怪的問題,怎麼只有ipv6在監聽?沒有IPV4?其實不是啦!centos7以上,都是ipv6優先的原則,對ipv6的支持預設是開啟的,ipv4其實也是有在監聽的啦!
- 啟動後,通過瀏覽器訪問指標頁面
- 暴露的HTTP服務地址(http://192.168.11.150:9104/metrics)
看到這些指標了嗎?Prometheus服務端會周期性的從Exporter暴露的HTTP服務地址(通常是/metrics)拉取監控樣本數據。
指標內容簡單說明:
- HELP:用於解釋當前指標的含義
- TYPE:說明當前指標的數據類型
比如下麵的一個指標
# HELP mysql_up Whether the MySQL server is up. # MySQL伺服器是否啟動
# TYPE mysql_up gauge # 指標的數據類型是gauge,測量、檢測的意思,也有儀錶盤的意思?
mysql_up 1 # mysql_up反應當前的狀態,當前的值為1,說明是啟動的,也可能為0(停止狀態)
筆者去把Mysql給停止了,再次刷新指標頁面,查看這個指標,發現確實變成了0
- 查看採集過程輸出的相關信息
剛剛是通過nohup將mysqld_exporter程式丟入到後臺啟動的,所以相關的輸出信息預設是會寫入nohup.out文件中
[root@mysql8db mysqld_exporter]# tailf nohup.out
ts=2022-05-21T13:40:01.735Z caller=mysqld_exporter.go:277 level=info msg="Starting mysqld_exporter" version="(version=0.14.0, branch=HEAD, revision=ca1b9af82a471c849c529eb8aadb1aac73e7b68c)"
ts=2022-05-21T13:40:01.735Z caller=mysqld_exporter.go:278 level=info msg="Build context" (gogo1.17.8,userroot@401d370ca42e
...
...
到此為止,在Mysql伺服器主機上部署mysqld_exporter的任務算是大功告成。
接下來回到Prometheus Master中繼續以下的操作
- 在Prometheus Master中配置從mysqld_exporter收集監控數據
在Master中的prometheus主配置文件中的scrape_configs配置項添加基於文件的自動發現job
一定要註意:只需在master上做相關配置,slave主機會定時拉取master的配置目錄和master保持同步,且slave的配置發生變更還會自動熱重啟使其生效,也就是說slave不用你操心,你只需管理好你的master就好。
再羅嗦一次:以下操作僅在master上操作。
在主配置文件/usr/local/prometheus/conf/prometheus.yml中添加測試業務A的job
說明:下麵的job_name為prometheus_server是拉取prometheus本身的指標數據(也就是監控其本身),IP地址是指向VIP:192.168.11.203,指向VIP這是建議的做法。
scrape_configs:
- job_name: 'prometheus_server'
static_configs:
- targets: ['192.168.11.203:9090']
- job_name: '測試業務A'
file_sd_configs:
- files:
- './business/test_bus_a/job/*.yml'
refresh_interval: 1s
參數說明:
- '測試業務A'的job_name:定義自發現的採集任務名稱,按業務的維度進行定義名稱,筆者這裡叫“測試業務A”
- file_sd_configs:這是基於文件的自動發現,即<file_sd_configs>,下麵這塊配置都是和file_sd_configs有關的,詳細說明如下:
file_sd_configs: # 指定這是基於文件的自動發現
- files:
- './business/test_bus_a/job/*.yml' # 指定自動發現配置文件的路徑,這裡表示在該路徑下發現所有.yml格式的配置文件
refresh_interval: 1s # 自動發現間隔,時間預設是5秒,筆者這裡設置了1秒。
- 在規劃好的業務目錄(business)下創建對應的業務文件夾:test_bus_a,以及在業務目錄test_bus_a下麵創建job目錄,併進入job目錄創建mysql.yml(該名稱可自定義,也可叫mon_mysql.yml或者其他,主要你喜歡就好!)在mysql.yml中定義拉取mysql的監控指標數據
- ./conf/business/test_bus_a/job/mysql.yml的內容如下:
- targets:
- '192.168.11.150:9104'
labels:
ip: '192.168.11.150'
monitype: 'mysql'
project: '測試業務A'
business: '測試業務A'
參數說明:
- targets:拉取目標,這裡指向mysql伺服器的IP地址,mysqld_exporter的埠是9104
- labels:這是標簽,標簽的主要作用是可以通過指定的標簽查詢指定的數據。
標簽的作用:Prometheus中存儲的數據為時間序列,是由Metric的名字和一系列的標簽(鍵值對)唯一標識的, 不同的標簽代表不同的時間序列,即通過指定標簽查詢指定數據。不同的標簽代表不同的時間序列,即通過指定標簽查詢指定數據。指標+標簽實現了查詢條件的作用,可以指定不同的標簽過濾不同的數據。
在Prometheus UI中對應的Labels信息如下圖可見:
假設有個需求,需要知道被監控的mysql伺服器所在的機房位置,那麼就可以增加一個自定義標簽,如下:
- ./conf/business/test_bus_a/job/mysql.yml
- targets:
- '192.168.11.150:9104'
labels:
ip: '192.168.11.150'
monitype: 'mysql'
project: '測試業務A'
business: '測試業務A'
region: '廣州機房'
在Prometheus UI中可以看到:
- 不管你是用VIP、還是master、slave的物理IP去訪問UI,結果都一樣的,不信你試試。
自定義標簽的主要應用場景:有了這些標簽可以針對特定的標簽去查詢,比如筆者在上面的假設需求中,需要定義一個根據自定義標簽region作為標識機房位置。總而言之,添加的標簽越多,查詢的維度就會越細。
在UI界面中的Graph面板中使用PromQL表達式查詢特定監控指標的監控數據,如下查詢“mysql_up”指標,如下圖:
PromQL是Prometheus自定義的一套強大的數據查詢語言,除了使用監控指標作為查詢關鍵字以為,還內置了大量的函數,幫助用戶進一步對時序數據進行處理。例如使用rate()函數,可以計算在單位時間內樣本數據的變化情況即增長率,通過PromQL我們可以非常方便的對數據進行查詢,過濾,以及聚合,計算等操作。通過這些豐富的表達式語句,監控指標不再是一個單獨存在的個體,而是一個個能夠表達出正式業務含義的語言。當然,關於更多的PromQL知識,以後筆者會慢慢分享,本篇的重點是主備架構,可別跑題了呢!
五、監控主機案例
為了能夠採集到主機的運行指標如CPU, 記憶體,磁碟等信息。可以使用Node Exporter。Node Exporter同樣採用Golang編寫,並且不存在任何的第三方依賴,只需要下載,解壓即可運行。
- 下載node_exporter並解壓以及部署到指定目錄
wget https://github.com/prometheus/node_exporter/releases/download/v1.3.1/node_exporter-1.3.1.linux-amd64.tar.gz
tar -zxf node_exporter-1.3.1.linux-amd64.tar.gz
mv node_exporter-1.3.1.linux-amd64 /usr/local/exporter/node_exporter
cd /usr/local/exporter/node_exporter/
- 可通過help查看一堆啟動參數
[root@mysql8db node_exporter]# ./node_exporter --help
usage: node_exporter [<flags>]
Flags:
-h, --help Show context-sensitive help (also try --help-long and --help-man).
--collector.bcache.priorityStats
Expose expensive priority stats.
--collector.cpu.guest Enables metric node_cpu_guest_seconds_total
--collector.cpu.info Enables metric cpu_info
...
...
- 啟動node_exporter
# 丟入後臺運行
[root@mysql8db node_exporter]# nohup ./node_exporter &
# 查看監聽的埠
[root@mysql8db node_exporter]# netstat -tulnp | grep node_exporte
tcp6 0 0 :::9100 :::* LISTEN 1935/./node_exporte
[root@mysql8db node_exporter]#
# 通過nohup丟入後臺運行,相關的輸出會追加到nohup.out文件中,必要時可查看該文件診斷相關問題
[root@mysql8db node_exporter]# tailf nohup.out
ts=2022-06-04T00:45:58.822Z caller=node_exporter.go:115 level=info collector=thermal_zone
ts=2022-06-04T00:45:58.822Z caller=node_exporter.go:115 level=info collector=time
ts=2022-06-04T00:45:58.822Z caller=node_exporter.go:115 level=info collector=timex
ts=2022-06-04T00:45:58.822Z caller=node_exporter.go:115 level=info collector=udp_queues
...
...
筆者沒啥特殊的需求,所以無需額外在給定啟動參數,直接丟入後臺運行即可,預設的監聽埠是9100
- 通過瀏覽器查看node_exporter暴露的指標
- 在prometheus的master伺服器中配置從node_exporter收集監控數據
假設筆者的這台主機是測試業務b(test_bus_b)的一臺主機,請按照之前的業務目錄規範,在規範的業務目錄(conf/business)下創建業務文件夾test_bus_b。
再次羅嗦一次:僅需在master上做配置即可,slave會定時拉取masetr的配置目錄,不要去管slave,OK?一個大男人那麼羅嗦,真的很惹人討厭啊!
在主配置文件中添加業務B的job
- 主配置文件:/usr/local/prometheus/conf/prometheus.yml
scrape_configs:
- job_name: 'prometheus_server'
static_configs:
- targets: ['192.168.11.203:9090']
- job_name: '測試業務A'
file_sd_configs:
- files:
- './business/test_bus_a/job/*.yml'
refresh_interval: 1s
- job_name: '測試業務B' # 這是新增加的測試業務B
file_sd_configs:
- files:
- './business/test_bus_b/job/*.yml'
refresh_interval: 1s
在規範的業務目錄(conf/business)下創建業務文件夾test_bus_b,然後創建host.yml,增加targets(拉取目標)的配置
[root@prosvr-master business]# cd /usr/local/prometheus/conf/business/
[root@prosvr-master business]# mkdir test_bus_b
[root@prosvr-master business]# cd test_bus_b/
[root@prosvr-master business]# mkdir job
[root@prosvr-master business]# cd job/
[root@prosvr-master job]# cat host.yml
- targets:
- '192.168.11.150:9100'
labels:
ip: '192.168.11.150'
monitype: 'linux-centos7'
project: '測試業務B'
business: '測試業務B'
region: '深圳機房'
在Prometheus UI中查看新增的測試業務B
- 不管你是用VIP、還是master、slave的物理IP去訪問UI,結果都一樣的,不信你試試。
非常不錯,只要檢測到配置文件發生變化,master會自動熱重啟,slave也會自動拉取配置目錄然後熱重啟,非常的省心、省力。自我感覺這個DIY的主備方案幾乎接近完美,雖然沒有用很高大上的語言、工具去實現,但筆者的這個思路自我感覺是非常的不錯,這難道就是傳說中的自我感覺良好?當然,筆者以後會通過Go或者Python打造一個管理Promtheus主備的工具,且是帶UI的管理工具,敬請期待推出!我不造車,我只造零件。
六、AlertManager警報組件配置
說明:基於二進位包的alertmanager組件請自行在master和slave中安裝部署到規範的目錄,之後繼續下麵的步驟。
- 移動master和slave上的警報組件的主配置文件alertmanager.yml
- 在master和slave伺服器上,alertmanager組件的二進位包解壓到規範的目錄後,將警報的主配置文件“alertmanager.yml”移動到prometheus組件的conf目錄下
# 移動後(也就是用mv命令移動),查看如下:
[root@prosvr-master conf]# pwd
/usr/local/prometheus/conf
[root@prosvr-master conf]# ll
total 12
-rw-r--r-- 1 3434 3434 348 Jun 4 13:26 alertmanager.yml # 警報組件的主配置文件已經也在prometheus組件下的conf目錄
drwxr-xr-x 4 root root 42 Jun 4 09:18 business
-rw-r--r-- 1 3434 3434 1033 Jun 4 12:27 prometheus.yml
[root@prosvr-master conf]#
特別註意:上述操作,在master和slave上都要操作,且在slave伺服器移動alertmanager.yml配置文件後,往後就可以不用去管slave上的alertmanager.yml配置文件了,主要的配置變更都在master上進行就好,如果有變更,slave會自動拉取配置目錄。通常警報組件的alertmanager.yml配置文件一旦配置好後,改動的頻率比較少。
特別說明:之所以這麼設計,有兩個好處:1)配置的變更都在同一個目錄下進行;2)利用了現有master和slave的配置目錄同步能力
- 在master上配置警報的主配置文件/usr/local/prometheus/conf/alertmanager.yml
- 在警報組件中配置告警消息發往的介面地址, 讓其可以調用介面,配置方式很簡單,只需要指定一下介面地址即可
global:
resolve_timeout: 5m
route:
group_by: [...]
group_wait: 1s
group_interval: 1s
repeat_interval: 1000d
receiver: 'web.hook'
receivers:
- name: 'web.hook'
webhook_configs:
- url: 'http://127.0.0.1:5001/webhook'
send_resolved: true
上述配置中,主要包含兩大部分,路由(route)和接收器(receivers),所有的告警信息都會從配置中的頂級路由(route)進入路由樹,根據路由規則將告警信息發送給相應的接收器。本篇主要是配置接收器,使用webhook的方式,假設是將告警消息推送到第三方平臺。當然,在本篇僅為示例,列印出來而已。
- 在master和slave上創建Alertmanager組件啟動腳本
- 註意:該步驟一定要進入到/usr/local/alertmanager/目錄下進行操作
- 創建腳本,名稱:startAlertManagerSvr.sh
#!/bin/sh
nohup ./alertmanager --config.file=/usr/local/prometheus/conf/alertmanager.yml >> ./logs/alert.log &
[root@prosvr-master alertmanager]#
註意:startAlertManagerSvr.sh腳本在masetr和slave中都要創建,且--config.file使用絕對路徑指向alertmanager.yml
通過該腳本拉起alertmanager組件
sh startAlertManagerSvr.sh
註意:master和slave都要拉起
啟動後,通過VIP或master和slave的物理IP都可以訪問到警報的頁面,筆者這裡是使用VIP進行訪問,如下圖:
- 關聯Prometheus與Alertmanager
註意:僅在master上配置即可,因為slave會從master上拉取
- /usr/local/prometheus/conf/prometheus.yml
alerting:
alertmanagers:
- static_configs:
- targets:
- 192.168.11.203:9093
筆者這裡通過VIP跟Alertmanager組件通信,當prometheus中的警報規則觸發了告警後,告警消息就會發送到警報組件監聽的9093埠,由alertmanager組件進行處理
- 配置警報規則文件的自動發現
註意:僅在master上配置即可
- /usr/local/prometheus/conf/prometheus.yml
rule_files:
- "./business/test_bus_a/rule/*.rules"
- "./business/test_bus_b/rule/*.rules"
- 配置mysql的警報規則,當mysql掛掉後,使其觸發警報
註意:僅在master上配置即可
- /usr/local/prometheus/conf/business/test_bus_a/rule/mysql.rules
groups:
- name: mysql-alert
rules:
- alert: "MysqlDown"
expr: mysql_up{job="測試業務A"}==0
for: 1m
labels:
annotations:
summary: "MySQL資料庫服務:{{ $labels.ip }}發生停止告警"
description: "測試業務A的環境MySQL資料庫服務:{{ $labels.ip }}已停止,當前UP狀態值為:{{ $value }},已觸發告警條件:mysql_up = 0,持續時間:1m。"
alertLevel: 5
上面的案例很簡單,expr是表達式,該表達式是說:如果mysql_up指標的值等於0那麼就觸發該警報
可以通過promtool工具檢查警報規則配置文件是否有誤
[root@prosvr-master prometheus]# ./promtool check rules ./conf/business/test_bus_a/rule/mysql.rules
Checking ./conf/business/test_bus_a/rule/mysql.rules
SUCCESS: 1 rules found
配置文件發生了變更後,master會自動熱重啟,slave會自動拉取配置並熱重啟,直接在UI界面上可以查看到該規則
- 筆者在這裡假設用python編寫了一個最簡單的webhook介面,讓其可以接收來自alertmanager的警報消息,然後列印出來
特別說明:只需在master上編寫的webhook介面腳本,並且也放在規範的conf目錄下:/usr/local/prometheus/conf/webhook.py,該API腳本會被slave拉取到
- webhook.py簡單的API代碼如下:
import json
from flask import Flask, request
app = Flask(__name__)
@app.route('/webhook', methods=['POST'])
def webhook():
data = json.loads(request.data)
print(data)
if __name__ == '__main__':
app.run('0.0.0.0', 5001)
特別說明1:此示例API只是演示使用,請根據實際情況編寫相關代碼,本實例僅僅只是列印出來,並沒有將告警推送到其他平臺,如釘釘、郵件、或其他告警收斂平臺。
特別說明2:如果您也想在您的測試環境將筆者的這個webhook.py跑起來,請自行安裝python的flask庫,筆者不在本篇講解python的相關知識。python編程筆者後續會專門抽時間作為專題給大家分享,敬請您的關註。
- 創建webhook API的啟動腳本
說明:在master和slave都要創建startWebHook.sh腳本
#!/bin/sh
nohup python ./conf/webhook.py >> ./logs/webhook.log &
```配置文件發生了變更後,master會自動熱重啟,slave會自動拉取配置並熱重啟,直接在UI界面上可以查看到該規則
9. **僅在master上啟動webhook API**
```shell
[root@prosvr-master prometheus]# sh startWebHook.sh
特別註意:千萬不要在slave上啟動webhook API,具體原因在本篇的最前面已經有過解釋(避免告警重覆推送),只有當master不可用了,slave才拉起webhook API腳本進行承擔告警推送的任務。
- 模擬mysql故障,驗證告警是否可以正常觸發,驗證由webhook是否可以正常接收
- 在master上用tailf命令實時監測./logs/webhook.log
[root@prosvr-master prometheus]# tailf ./logs/webhook.log
* Serving Flask app "webhook" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://0.0.0.0:5001/ (Press CTRL+C to quit)
登錄Mysql主機,停掉mysql
[root@mysql8db ~]# cat stop_mysql.sh
#!/bin/bash
/usr/local/mysql8/bin/mysqladmin -S /usr/local/mysql8/mysql.sock -uroot -pRoot.123456 shutdown
[root@mysql8db ~]#
[root@mysql8db ~]# sh stop_mysql.sh
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
[root@mysql8db ~]#
沒過多久,webhook api就接收到了告警消息
同樣,在Alertmanager告警頁面中,也能看到告警消息
寫在最後
到目前為止,該DIY的prometheus主備方案的全程搭建過程就已經完結了,期間涉及到很多知識點都還沒有去深入的剖析,比如:PromQL,Metric類型,告警的分組、抑制、靜默等等知識點。本篇的核心主題是把這個DIY的方案給搞起來,後續筆者會逐一分享更多關於prometheus的技能點,敬請大家的關註。謝謝!感謝您的關註,望多多轉發、點贊。謝謝!