Keepalived配置及典型應用案例

使用源碼先安裝keepalived 1.2.6

cd /usr/local/src

wget  http://www.keepalived.org/software/keepalived-1.2.6.tar.gz

tar zxf keepalived-1.2.6.tar.gz  

cd keepalived-1.2.6

./configure --prefix=/usr/local/keepalived  

make

make install

所設keepalived安裝到/usr/local/keepalived, 則所有配置文件均位於此目錄之下。 我一直沒搞明白一個問題,Linux默認總是將程序安裝到/usr/local目錄下,所有程序共享了/usr/local/sbin目錄。這對一些人的操作習慣是有影響的。爲何不考慮使用每個軟件一個獨立的目錄呢?

1.  建立服務啓動腳本,以便使用service命令控制之
cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/keepalived

chmod +x /etc/init.d/keepalived

因爲我們使用非默認路徑(/usr/local)安裝keepalived, 故需要修改幾處路徑,以保證keepalived能正常啓動, 需要修改的文件如下:

2. 修改/etc/init.d/keepalived, 尋找大約15行左右的. /etc/sysconfig/keepalived, 修改爲:
.  /usr/local/keepalived/etc/sysconfig/keepalived, 即指向正確的文件位置

同時在上述行下添加以下內容(將keepavlied主程序所在路徑導入到環境變量PATH中):

PATH="$PATH:/usr/local/keepalived/sbin"

export PATH

3. 修改/usr/local/keepalived/etc/sysconfig/keepalived文件,設置正確的服務啓動參數
KEEPALIVED_OPTIONS="-D -f /usr/local/keepalived/etc/keepalived/keepalived.conf"

4. 經過以上修改,keepalived基本安裝即可完成,啓動測試之:
service keepalived restart

5. 切勿忘記將此服務設置爲開機啓動

chkconfig keepalived on

默認的配置文件中,指定了兩個數個虛擬IP : 192.168.200.16  192.168.200.17  192.168.200.18

可使用ip addr命令驗證之。

以上實驗只需要一臺主機,因爲當前節點被指定爲主節點,且沒有收到其它節點的VRRP組播信息,故自動綁定了虛擬IP。

參考案例一:主-備模式
在這種模式下,虛擬IP在某時刻只能屬於某一個節點,另一個節點作爲備用節點存在。當主節點不可用時,備用節點接管虛擬IP,提供正常服務。

節點A 192.168.0.11 (主節點), 節點B 192.168.0.12(備用節點)  虛擬IP(對外提供服務的IP 192.168.0.200  

要求默認情況下由節點A提供服務,當節點A不可用時,由節點B提供服務(即虛擬IP漂移至節點B)。

節點A上的配置文件/usr/local/keepalived/etc/keepalived/keepalived.conf

global_defs {

  notification_email {

    root@localhost

  }

  notification_email_from root@local host

  smtp_server localhost

  smtp_connect_timeout 30

  router_id  NodeA

}

默認的配置文件中,使用第三方smtp服務器,但這在現實中幾乎沒有意義(需要驗證的原因),我們將其指定爲localhost, 將通知信息的發送交給本地sendmail服務處理。查閱說明文檔得知route_id配置是爲了標識當前節點,我將其設置爲NodeA。當然兩個節點的此項設置可相同,也可不相同。

vrrp_instance VI_1 {

   state MASTER   #指定A節點爲主節點 備用節點上設置爲BACKUP即可

   interface eth0   #綁定虛擬IP的網絡接口

   virtual_router_id 51  #VRRP組名,兩個節點的設置必須一樣,以指明各個節點屬於同一VRRP組

   priority 100   #主節點的優先級(1-254之間),備用節點必須比主節點優先級低

   advert_int 1   #組播信息發送間隔,兩個節點設置必須一樣

   authentication {   #設置驗證信息,兩個節點必須一致

       auth_type PASS

       auth_pass 1111

   }

   virtual_ipaddress {   #指定虛擬IP, 兩個節點設置必須一樣

       192.168.200.16/24

       192.168.200.17 /24

       192.168.200.18 /24

   }

}

默認的配置文件中,竟然沒有子網掩碼,從而導致使用了默認子網掩碼255.255.255.255,如果導致無法從其它機器訪問虛擬IP(keepalived虛擬IP無法ping通)。

按同樣的方法配置節點B並修改配置文件,可將A節點的配置文件複製到B節點,並修改以下幾項:
router_id  NodeB

state   BACKUP

priority   99

其它項不必修改。

測試及驗證:拔掉節點A的網線,就發現虛擬IP已經綁定到節點B上,再恢復A節點的網線,虛擬IP又綁定回節點A之上。

但是這種方式存在惱裂的可能,即兩個節點實際都處於正常工作狀態,但是無法接收到彼此的組播通知,這時兩個節點均強行綁定虛擬IP,導致不可預料的後果。
這時就需要設置仲裁,即每個節點必須判斷自身的狀態(應用服務狀態及自身網絡狀態),要實現這兩點可使用自定義shell腳本實現,通過週期性地檢查自身應用服務狀態,並不斷ping網關(或其它可靠的參考IP)均可。當自身服務異常、或無法ping通網關,則認爲自身出現故障,就應該移除掉虛擬IP(停止keepalived服務即可)。主要藉助keepalived提供的vrrp_script及track_script實現:

在keepalived的配置文件最前面加入以下代碼,定義一個跟蹤腳本:
vrrp_script check_local { #定義一個名稱爲check_local的檢查腳本

   script "/usr/local/keepalived/bin/check_local.sh" #shell腳本的路徑

   interval 5  #運行間隔

}

再在vrrp_instance配置中加入以下代碼使用上面定義的檢測腳本:

track_script {

check_local

}

我們在/usr/local/keepalived/bin/check_local.sh定義的檢測規則是:

1.  自身web服務故障(超時,http返回狀態不是200)

2.  無法ping通網關

3.  產生以上任何一個問題,均應該移除本機的虛擬IP(停止keepalived實例即可)

但這裏有個小問題,如果本機或是網關偶爾出現一次故障,那麼我們不能認爲是服務故障。更好的做法是如果連續N次檢測本機服務不正常或連接N次無法ping通網關,才認爲是故障產生,才需要進行故障轉移。另一方面,如果腳本檢測到故障產生,並停止掉了keepalived服務,那麼當故障恢復後,keepalived是無法自動恢復的。我覺得利用獨立的腳本以秒級的間隔檢查自身服務及網關連接性,再根據故障情況控制keepalived的運行或是停止。

這裏提供一個思路,具體腳本內容請大家根據自己的需要編寫即可。

如下圖的案例:

120831094292431.png


假設節點A和B組成主備關係,A爲備用節點,B爲主節點,那麼當在圖標紅叉位置發生網絡故障時,節點A接收不到節點B的組播通知,將搶佔虛擬IP。這時出現的後果就是節點A和節點B均擁有虛擬IP,就可能導致了腦裂。所以我們以網關IP連通性作爲參考,可避免此問題產生。


參考案例二:雙主模式
主備模式的缺點就是始終只有一臺機器位於工作狀態,另外一臺機器永遠是備用狀態,存在資源浪費之問題。

雙主模式允許兩臺機器均處於工作狀態並互相作爲備份。

搭建keepalived雙方模式的要素:

1.  必須有兩個虛擬IP, 分別綁定至兩個節點上

2. 每個節點作爲某個虛擬IP的主節點,並同時作爲另外一個虛擬IP的備用節點。

3. 當某個節點產生故障時,兩個虛擬IP自動綁定至正常節點上

參閱相關文章,這就相當於使用兩臺物理路由器(普通主機視爲路由器即可),構造出兩個虛擬VRRP路由器。

120831094419291.png

也就是說,兩個節點的配置應該是交叉的,對同個虛擬IP,交叉互爲主備。

節點A的關鍵配置:
vrrp_instance vip1 {

    state MASTER

   interface eth0

    virtual_router_id 51   #本機兩個vrrp_instance組的此值不能相同,但對應備用節點的此值必須相同

    priority 99 #對應備用節點值應該比此值小

   advert_int 1

   authentication {

       auth_type PASS

       auth_pass 1111

   }

   virtual_ipaddress {

       192.168.100.1 /24

   }

}


vrrp_instance vip2 {

    state BACKUP

   interface eth0

    virtual_router_id 52  #本機兩個vrrp_instance組的此值不能相同,但對應主節點的此值必須相同

    priority 90   #主節點的值應該比此值大

   advert_int 1

   authentication {

       auth_type PASS

       auth_pass 1111

   }

   virtual_ipaddress {

       192.168.100.2 /24

   }

}

複製節點A的配置至B節點,並將MASTER修改爲BACKUP, 同時將BACKUP修改爲MASTER。優先級和虛擬路由器組id(virtual_route_id)要特別注意其它配置必須保持相同。

B節點的配置:
vrrp_instance vip1 {

    state BACKUP

   interface eth0

    virtual_router_id 51

    priority 90

   advert_int 1

   authentication {

       auth_type PASS

       auth_pass 1111

   }

   virtual_ipaddress {

       192.168.100.1 /24

   }

}


vrrp_instance vip2 {

    state MASTER

   interface eth0

    virtual_router_id 52

    priority 99

   advert_int 1

   authentication {

       auth_type PASS

       auth_pass 1111

   }

   virtual_ipaddress {

       192.168.100.2 /24

   }

}

另外,爲了保證服務可靠性,我們應該在每個節點運行shell腳本檢測本機的服務是否正常,一旦檢測到服務異常時,停止掉本機的keepalived, 如此虛擬IP自動轉移到備用機器之上,如每隔3秒檢測一次本機服務狀態,如果連接3次檢測失敗,則停止掉keepalived實例。同時如果本機服務是正常的,但是keepalived沒有啓動(故障恢復之後),則啓動keepalived,以達到故障恢復之目的。

check_service.sh文件的內容

#!/bin/bash


pidfile=/var/lock/subsys/`basename $0`.pid

if [ -f $pidfile ] && [ -e /proc/`cat $pidfile` ] ; then

   exit 1

fi


trap "rm -fr $pidfile ; exit 0" 1 2 3 15

echo $$ > $pidfile


maxfails=3

fails=0

success=0


while [ 1 ]

do

   /usr/bin/wget --timeout=3 --tries=1 http://127.0.0.1/ -q -O /dev/null

   if [ $? -ne 0 ] ; then

       let fails=$[$fails+1]

       success=0

   else

       fails=0

       let success=$[$success+1]

   fi


   if [ $fails -ge $maxfails ] ; then

       fails=0

       success=0


       #check keepalived is running ? try to stop it

       service keepalived status | grep running

       if [ $? -eq 0 ] ; then

           logger -is "local service fails $maxfails times ... try to stop keepalived."

           service keepalived stop 2>&1 | logger

       fi

   fi


   if [ $success -gt $maxfails ] ; then

       #check keepalived is stopped ? try to start it

       service keepalived status | grep stopped

       if [ $? -eq 0 ] ; then

           logger -is "service changes normal, try to start keepalived ."

           service keepalived start

       fi

       success=0

   fi

   sleep 3

done

兩個節點上均應運行此腳本,請將此腳本加入到cron任務中(此程序已經作了單實例運行機制,加入計劃任務的作用就是防止腳本意外中斷後檢測功能失效),可實現的功能:

如果本地服務連續三次檢測失敗,就嘗試停止keepalived服務(如果keepalived處於運行狀態)

如果本地服務連接三次檢測成功,但keepalived沒有啓動,則啓動之

關鍵的執行點,均已經記錄到系統日誌中(/var/log/messages)

執行crontab -e , 加入以下內容:
*/1  *  *  *  * /root/check_service.sh

此腳本的原始文件

下載在Linux公社的1號FTP服務器裏,下載地址:

FTP地址:ftp://www.linuxidc.com

用戶名:www.linuxidc.com

密碼:www.muu.cc

在 2012年LinuxIDC.com\8月\Keepalived配置及典型應用案例

下載方法見 http://www.linuxidc.net/thread-1187-1-1.html

停止掉本機的keepalived, 稍過一會,就會keepalived服務被自動啓動了(這是因爲本地服務檢測正常)

停止掉本機的nginx, 稍過一會,就會發現keepalived服務也被停止掉了

再啓動nginx, 稍過一會,發現keepalived也被正常啓動,並綁定了正確的虛擬IP

我們可根據具體環境,將服務的檢測功能強化(如檢測到網關的連接性),以達到較好的故障轉移效果。



本文轉自:http://www.linuxidc.com/Linux/2012-08/69383p2.htm


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章