在實際生產環境中,我們可以從以下幾個方面來防止裂腦問題的發生:
同時使用串行電纜和以太網電纜連接,同時用兩條心跳線路,這樣一條線路壞了,另一個還是好的,依然能傳送心跳消息。
當檢測到裂腦時強行關閉一個心跳節點(這個功能需特殊設備支持,如Stonith、feyce)。相當于備節點接收不到心跳消患,通過單獨的線路發送關機命令關閉主節點的電源。
做好對裂腦的監控報警(如郵件及手機短信等或值班).在問題發生時人為第一時間介入仲裁,降低損失。例如,百度的監控報警短倍就有上行和下行的區別。報警消息發送到管理員手機上,管理員可以通過手機回復對應數字或簡單的字符串操作返回給服務器.讓服務器根據指令自動處理相應故障,這樣解決故障的時間更短.
當然,在實施高可用方案時,要根據業務實際需求確定是否能容忍這樣的損失。對于一般的網站常規業務.這個損失是可容忍的。
多節點集群中,可以通過增加仲裁的機制,確定誰該獲得資源,這里面有幾個參考的思路:
1.增加一個仲裁機制。例如設置參考的IP,當心跳完全斷開的時候,2個節點各自都ping一下參考的IP,不同則表明斷點就出現在本段,這樣就主動放棄競爭,讓能夠ping通參考IP的一端去接管服務。
2.通過第三方軟件仲裁誰該獲得資源,這個在阿里有類似的軟件應用
啟用磁盤鎖。正在服務一方鎖住共享磁盤,腦裂發生的時候,讓對方完全搶不走共享的磁盤資源。但使用鎖磁盤也會有一個不小的問題,如果占用共享盤的乙方不主動解鎖,另一方就永遠得不到共享磁盤。現實中介入服務節點突然死機或者崩潰,另一方就永遠不可能執行解鎖命令。后備節點也就截關不了共享的資源和應用服務。于是有人在HA中涉及了“智能”鎖,正在服務的一方只在發現心跳線全部斷開時才啟用磁盤鎖,平時就不上鎖了
報警報在服務器接管之前,給人員處理留足夠的時間就是1分鐘內報警了,但是服務器不接管,而是5分鐘之后接管,接管的時間較長。數據不會丟失,但就是會導致用戶無法寫數據。報警后,不直接自動服務器接管,而是由人員接管。
檢查處理腳本(供參考)
注:
1.腳本無法解決服務器主備之間因為防火墻,配置等產生的腦裂問題(安裝配置時注意檢查,keepalived服務正常運行后再加入檢查處理腳本),腳本只能處理自身網絡問題產生的腦裂,必須保證網關服務器穩定
2.備機獲取vip有2種情況:A主機keepalived服務發生故障vip漂移(非腦裂);B主機通信異常vip漂移(腦裂)。
腳本使用機制(引入第三方仲裁),步驟:
1.查看是否可獲取vip,未獲取:判斷keepalived服務運行狀態,運行中不操作,未運行重新啟動,結束腳本。
2.服務器周期性地ping一下網關(第三方仲裁ip地址),如果ping通:判斷keepalived服務運行狀態,運行中不操作,未運行重新啟動,結束腳本;如果ping不通則認為自身有問題,累計次數達到閾值,關閉keepalived。
腳本執行方式:
1.借助keepalived提供的vrrp_script及track_script實現(腳本內keepalived服務如果被關閉,腳本將不在執行,重新啟動不生效),配置:
... vrrp_scriptcheck_local{ script "/usr/local/src/check_gateway.sh 192.168.1.198" #192.168.1.198 需要檢查的vip interval10#10秒一次 ... track_script{ check_local }
2.linux定時任務(查看 tailf /var/spool/mail/root)
crontab -e
#1分1次延遲10秒實現(時間自定義)keepalived服務腦裂腳本 *****sleep10;bash/usr/local/src/check_gateway.sh192.168.1.198
腳本內容(根據實際環境修改網關ip,是否重新啟動keepalived服務):
vim /usr/local/src/check_gateway.sh
#!/bin/bash export PATH=$PATH:/usr/sbin #腦裂檢查及控制:第三方仲裁機制,使用ping網關ip方式 #循環次數 CHECK_TIME=3 #虛擬ip VIP=$1 #網關ip(根據實際環境修改) GATEWAY=192.168.1.8 #本機網卡 eth=enp2s0 #服務器和網關通信狀態 0=失敗,1=成功 keepalived_communication_status=1 #是否獲取vip狀態 0=失敗,1=成功 get_vip_status=1 #keepalived服務狀態 0=未運行,1=運行中 keepalived_service_status=1 #服務狀態運行中字符串 active_status_str='active (running)' echo "開始執行腳本 check_gateway.sh $VIP;時間:" date #查看是否獲取vip狀態 function check_get_vip_status() { #通過ip add命令查看ip信息,搜索$VIP,統計行數,是否等于1 if [ $(ip add | grep "$VIP" | wc -l) -eq 1 ]; then get_vip_status=1 else get_vip_status=0 fi return $get_vip_status } #檢查通信狀態 function check_keepalived_status() { #檢測$VIP 能否ping通$GATEWAY:使用$eth網絡設備(-I $eth),發送數據包5(-c 5),源地址$VIP詢問目的地[vip] $GATEWAY [網關地址 公用參考ip](-s $VIP $GATEWAY) 日志不保存 >/dev/null 2>&1 /sbin/arping -I $eth -c 5 -s $VIP $GATEWAY >/dev/null 2>&1 #判斷上一步執行結果 等于0成功 if [ $? = 0 ]; then keepalived_communication_status=1 else keepalived_communication_status=0 fi return $keepalived_communication_status } #檢查keepalived服務狀態 function check_keepalived_service_status() { #通過systemctl status keepalived.service命令查看keepalived服務狀態,搜索$active_status_str,統計行數,是否等于1 if [ $(systemctl status keepalived.service | grep "$active_status_str" | wc -l) -eq 1 ]; then keepalived_service_status=1 else keepalived_service_status=0 fi return $keepalived_service_status } #循環執行 #判斷$CHECK_TIME 不等于 0 while [ $CHECK_TIME -ne 0 ]; do #執行check_get_vip_status獲取get_vip_status check_get_vip_status #未獲取vip if [ $get_vip_status = 0 ]; then #修改CHECK_TIME值 結束循環 CHECK_TIME=0 #檢查服務狀態 執行check_keepalived_service_status獲取keepalived_service_status if [ $keepalived_service_status = 0 ]; then echo "執行腳本 check_gateway.sh $VIP;啟動keepalived服務" systemctl start keepalived.service fi echo "執行腳本 check_gateway.sh $VIP;執行結果:未獲取vip,無需處理,腳本執行結束,時間:" date #正常運行程序并退出程序 exit 0 fi #$CHECK_TIME = $CHECK_TIME-1 let "CHECK_TIME -= 1" #執行check_keepalived_status獲取keepalived_communication_status check_keepalived_status #判斷 $keepalived_communication_status = 1 通信成功 if [ $keepalived_communication_status = 1 ]; then #修改CHECK_TIME值 結束循環 CHECK_TIME=0 #檢查服務狀態 執行check_keepalived_service_status獲取keepalived_service_status check_keepalived_service_status if [ $keepalived_service_status = 0 ]; then echo "執行腳本 check_gateway.sh $VIP;啟動keepalived服務" systemctl start keepalived.service fi echo "執行腳本 check_gateway.sh $VIP;GATEWAY=$GATEWAY,執行結果:通信正常,無需處理,腳本執行結束,時間:" date #正常運行程序并退出程序 exit 0 fi #通信失敗&&連續3次 if [ $keepalived_communication_status -eq 0 ] && [ $CHECK_TIME -eq 0 ]; then #關閉keepalived echo "執行腳本 check_gateway.sh $VIP;關閉keepalived服務" systemctl stop keepalived.service echo "執行腳本 check_gateway.sh $VIP;GATEWAY=$GATEWAY,執行結果:通信失敗&&連續3次 關閉keepalived,腳本執行結束,時間:" date #非正常運行程序并退出程序 exit 1 fi sleep 3 done
-
電源
+關注
關注
184文章
17769瀏覽量
250735 -
電纜
+關注
關注
18文章
2729瀏覽量
54883 -
磁盤
+關注
關注
1文章
379瀏覽量
25224
原文標題:Keepalived腦裂的解決和預防(附腳本)
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論