keepalived出現no root host報錯的問題跟蹤和處理
問題發現
在OpenStack環境中,我們使用Keepalived+Haproxy的模式來提供負債均衡和高可用。後方運維報過來一個VIP被不時remove的問題,從日誌上來看是由於vrrp_script執行指令碼超時,而後主keepalived讓出了VIP。下圖是日誌 起初判斷認為是由於vrrp_script的指令碼執行時間過長,而導致執行失敗,而觸發了指令碼,這個看法本身沒錯,但是我們當時認為解決辦法應該是縮短指令碼執行時間,這個思路看起來是對的,實際是隻看到了表面。
#!/bin/bash count=`netstat -nlp|grep -i haproxy|wc -l` if [ $count -gt 1 ];then exit 0 else systemctl stop keepalived exit 1 fi
在說指令碼之前,需要說一一下vrrp_script的邏輯,當指令碼返回0,則認為正常,當指令碼結果返回非0,則任務指令碼執行失敗。 該指令碼通過netstat命令獲取目前haproxy的監聽狀態數量,該值不大於1的時候,而對keepalived進行stop,最終完成VIP的切換。 當時對優化指令碼而提出的解決方案是用systemctl is-active haproxy的命令返回值而進行判斷haproxy的狀態,我們判斷認為使用該命令受影響干擾少,且迅速。
驗證兩種指令碼的執行時間
但是測試後,發現兩種指令碼的執行時間基本一致,所以該方案是行不通的。
問題出在哪裡?
有一個淺顯的道理擺在我們面前,我們一直視而不見。既然vrrp_script檢測超時,那麼keepalived的檢測機制和邏輯究竟是什麼
引數設定解釋和建議:
Interval 1 #定期執行指令碼間隔,單位是s
timeout 2 #指令碼執行超時值,超過該值則認為本次指令碼執行失敗(並不是失敗就降優先順序,失敗次數達到fall的值才認為會降級) 通過線下測試發現,我們的指令碼的執行時間的平均值在1.3s左右,因此timeout值建議,大於等於2,也不需要過長
weight -2 #當指令碼的失敗次數達到了fall的次數的時候,priority就按照該值進行降級,當成功的次數達到了rise的值的時候,priority就開始按照該值升級。 這個值的絕對值建議大於等於MASTER中設定的priority與BACKUP中priority的值的差
fall 3 #指令碼執行不成功(超時)多少次,才會觸發priority下降,建議為2或者3都可以
rise 1 #指令碼執行成功多少次,才會觸發priority上升,建議為1
通過以上分析,可以知道,在我們寫vrrp_script配置的時候,最好把以上的引數都寫上,才會減少出問題的機率,如下:
vrrp_script chk_haproxy {
# script "/etc/keepalived/haproxy_check.sh"
script "/etc/keepalived/test.sh"
interval 1
timeout 2
weight -2
fall 3
rise 1
}
驗證一下猜想
1、測試超時
配置如下,其中timeout設定為2秒,fall為3次,rise為1次。 結果我們預期一致,那麼當指令碼超時3次,在2:41:04秒,主節點(192.168.0.105)的priority改變為98,並讓出VIP。 當我們把指令碼中的sleep註釋掉,之後,我們發現主節點192.168.0.105的priority再次回到了100,與預期一致,時間為2:42:08 我們再看一下日誌,在2:41:04秒,發生超時,進行VIP切換,2:42:08秒再切換回來,與我們抓包結果一致。
2、 當haproxy被stop後,是否會發生切換。
當haproxy被我們stop後,通過抓包發現在3:01:54秒的時候,發生了VIP切換,當我們把haproxy再次啟動,並將keepalived也再次啟動,VIP在3:02:10被再次切換回來。 通過日誌我們可以發現與抓包一致的結論。