Keepalived原理及配置應用總結

振宇要低調發表於2015-05-26

Keepalived——保持存活,在網路裡的含義就是保持線上。Keepalived提供高可用和熱備的功能,用來防止單點故障的發生。

1、VRRP協議基本原理介紹

Keepalived實現的基礎是VRRP協議,我們將會在這一節中簡要介紹VRRP協議的基本原理。

1.1 協議

VRRP協議是為消除在靜態預設路由環境下的預設路由器單點故障引起的網路失效而設計的主備模式的協議,使得在發生故障而進行裝置功能切換時可以不影響內外資料通訊,不需要再修改內部網路的網路引數。VRRP協議具有IP地址備份,優先路由選擇,減少不必要的路由器間通訊等功能。

VRRP協議將兩臺或多臺路由器裝置虛擬成一個裝置,對外提供虛擬路由器IP(一個或多個),而在路由器組內部,如果實際擁有這個對外IP的路由器能夠工作正常的話就是MASTER, MASTER實現針對虛擬路由器IP的各種網路功能,如ARP請求,ICMP,以及資料的轉發等;其他裝置不擁有該IP,狀態是BACKUP,除了接收MASTER的VRRP狀態通告資訊外,不執行對外的網路功能。當主機失效時,BACKUP將接管原先MASTER的網路功能。

配置VRRP協議時需要配置每個路由器的虛擬路由器ID(VRID)和優先權值,使用VRID將路由器進行分組,具有相同VRID值的路由器為同一個組,VRID是一個0~255的正整數;同一組中的路由器通過使用優先權值來選舉MASTER,優先權大者為MASTER,優先權也是一個0~255的正整數。

VRRP協議使用多播資料來傳輸VRRP資料,VRRP資料使用特殊的虛擬源MAC地址傳送資料而不是自身網路卡的MAC地址,VRRP執行時只有MASTER路由器定時傳送VRRP通告資訊,表示MASTER工作正常以及虛擬路由器IP(組),BACKUP只接收VRRP資料,不傳送資料,如果一定時間內沒有接收到MASTER的通告資訊,各BACKUP將宣告自己成為MASTER,傳送通告資訊,重新進行MASTER選舉狀態。

1.2 MASTER選舉

如果對外的虛擬路由器IP就是路由器本身配置的IP地址的話,該路由器始終都是MASTER;否則如果不具備虛擬IP的話,將進行MASTER選舉,各路由器都宣告自己是MASTER,傳送VRRP通告資訊;如果收到其他機器的發來的通告資訊的優先順序比自己高,將轉回BACKUP狀態;如果優先順序相等的話,將比較路由器的實際IP,IP值較大的優先權高;不過如果對外的虛擬路由器IP就是路由器本身的IP的話,該路由器始終將是MASTER,這時的優先順序值為255。

2、Keepalived內部原理

2.1 Keepalived元件

keepalived是模組化設計,不同模組負責不同的功能。

corekeepalived的核心,負責主程式的啟動和維護,全域性配置檔案的載入解析等;

check負責healthchecker(健康檢查),包括了各種健康檢查方式,以及對應的配置檔案的解析;

vrrpVRRPD子程式,用來實現VRRP協議;

libipfwciptables(ipchains)庫,配置LVS;

libipvs*配置LVS;

2.2 Keepalived程式

keepalived啟動後會有三個程式:

父程式:記憶體管理,子程式管理等等

子程式:VRRP子程式

子程式:healthchecker子程式

兩個子程式都被系統WatchDog看管,兩個子程式各自負責自己的事,healthchecker子程式負責檢查各自伺服器的健康程度,如果healthchecker子程式檢查到MASTER上服務不可用了,就會通知本機上的兄弟VRRP子程式,讓他刪除通告,並且去掉虛擬IP,轉換為BACKUP狀態。

3、Keepalived安裝

3.1安裝Keepalived

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

tar zxvf keepalived-1.2.6.tar.gz

cd keepalived-1.2.6

./configure

make

make install

3.2 新增Keepalived為系統服務

cp /usr/local/etc/rc.d/init.d/keepalived /etc/rc.d/init.d/

cp /usr/local/etc/sysconfig/keepalived /etc/sysconfig/

cp /usr/local/sbin/keepalived /usr/sbin/

mkdir /etc/keepalived

3.3新增keepalived的配置項

vi /etc/keepalived/keepalived.conf

我們將會在下一節對Keepalived配置檔案——keepalived.conf進行詳細介紹。

3.4 啟動

service keepalived start

4、Keepalived配置詳解

一個功能比較完整的keepalived的配置檔案,其配置檔案keepalived.conf可以包含三個文字塊:全域性定義塊、VRRP例項定義塊及虛擬伺服器定義塊。

4.1 全域性定義塊

4.1.1 email通知

有故障,發郵件報警。

4.1.2 Lvs負載均衡器標識

在一個網路內,它應該是唯一的。

4.1.3 花括號“{}”

用來分隔定義塊,因此必須成對出現。如果寫漏了,keepalived執行時,不會得到預期的結果。由於定義塊記憶體在巢狀關係,因此很容易遺漏結尾處的花括號,這點要特別注意。

4.1.4 notification_email_from

指定發件人。

4.1.5 smtp_server

smtp伺服器地址,可以配置為localhost。

4.1.6 smtp_connect_timeout

指定smtp連線超時時間。

4.1.7 router_id

執行keepalived機器的一個標識。

4.2 VRRP定義塊

4.2.1 同步vrrp組vrrp_sync_group

確定失敗切換(FailOver)包含的路由例項個數。即在有2個負載均衡器的場景,一旦某個負載均衡器失效,需要自動切換到另外一個負載均衡器的例項是哪些。

4.2.2 例項組group

至少包含一個vrrp例項。

4.2.3  Vrrp例項vrrp_instance

例項名出自例項組group所包含的那些名字。

(1)例項狀態state只有MASTER和BACKUP兩種狀態,並且需要大寫這些單詞。其中MASTER為工作狀態,BACKUP為備用狀態。當MASTER所在的伺服器失效時,BACKUP所在的系統會自動把它的狀態有BACKUP變換成MASTER;當失效的MASTER所在的系統恢復時,BACKUP從MASTER恢復到BACKUP狀態。

(2)通訊介面interface。對外提供服務的網路介面,如eth0,eth1。當前主流的伺服器都有2個或2個以上的介面,在選擇服務介面時,一定要核實清楚。

(3)lvs_sync_daemon_inteface。負載均衡器之間的監控介面,類似於HA HeartBeat的心跳線。但它的機制優於Heartbeat,因為它沒有“裂腦”這個問題,它是以優先順序這個機制來規避這個麻煩的。【腦裂:在“雙機熱備”高可用(HA)系統中,當聯絡2個節點的“心跳線”斷開時,本來為一整體、動作協調的HA系統,就分裂成為2個獨立的個體。由於相互失去了聯絡,都以為是對方出了故障,2個節點上的HA軟體像“裂腦人”一樣,“本能”地爭搶“共享資源”、爭起“應用服務”,就會發生嚴重後果:或者共享資源被瓜分、2邊“服務”都起不來了;或者2邊“服務”都起來了,但同時讀寫“共享儲存”,導致資料損壞(常見如資料庫輪詢著的聯機日誌出錯)。】

(4) 虛擬路由標識virtual_router_id。這個標識是一個數字,並且同一個vrrp例項使用唯一的標識。即同一個vrrp_stance,MASTER和BACKUP的virtual_router_id是一致的,同時在整個vrrp內是唯一的。

(5)優先順序priority。這是一個數字,數值愈大,優先順序越高。在同一個vrrp_instance裡,MASTER 的優先順序高於BACKUP。

(6) 同步通知間隔 advert_int。MASTER與BACKUP負載均衡器之間同步檢查的時間間隔,單位為秒。

(7) 驗證authentication。包含驗證型別和驗證密碼。型別主要有PASS、AH兩種,通常使用的型別為PASS。驗證密碼為明文,同一vrrp例項MASTER與BACKUP 使用相同的密碼才能正常通訊。

4.2.4 虛擬ip地址virtual_ipaddress

可以有多個地址,每個地址佔一行,不需要指定子網掩碼。注意:這個ip必須與我們在lvs客戶端設定的vip相一致。(開啟Keepalived服務後,可以通過命令:ip a 來檢視虛擬IP是否繫結到本機)

4.3虛擬伺服器virtual_server定義塊

4.3.1 虛擬伺服器virtual_server

這個ip來自於vrrp定義塊的第“4”步,後面一個空格,然後加上埠號。定義一個vip,可以實現多個tcp埠的負載均衡功能。

(1)delay_loop健康檢查時間間隔,單位是秒。

(2)lb_algo負載均衡排程演算法,網際網路應用常使用wlc或rr。

(3)lb_kind負載均衡轉發規則。一般包括DR,NAT,TUN3種。

(4)persistence_timeout會話保持時間,單位是秒。

(5)protocol轉發協議,一般有tcp和udp兩種。

4.3.2 真實伺服器real_server

Real_server的值包括ip地址和埠號。多個連續的真實ip,轉發的埠相同。

(1)權重weight。權重值是一個數字,數值越大,權重越高。使用不同的權重值的目的在於為不同效能的機器分配不同的負載,效能較好的機器,負載分擔大些;反之,效能差的機器,則分擔較少的負載,這樣就可以合理的利用不同效能的機器資源。

(2)Tcp檢查 tcp_check。

5、Keepalived、Redis高可用配置及指令碼

5.1 Keepalived配置檔案keepalived.conf

global_defs {

   router_id LVS_DEVEL

}

vrrp_script Monitor_Redis {

 script "/home/plat/laizy/redis/redis/script/redis_keepalive.sh"

 interval 1  #重複執行間隔1秒

 weight -2  #當健康檢查指令碼失敗後,主機權重將會-2

}

 

vrrp_instance VI_1 {

    state BACKUP  #主備機狀態均設為BASKUP,這樣才可以做到在主機宕掉之後,其餘#備機爭搶主機身份

    interface em1   #繫結網路卡名稱

    virtual_router_id 52

    priority 100   #優先順序,其餘備機應設定比100小的值

    advert_int 1

    nopreempt

    authentication {

        auth_type PASS

        auth_pass 1111

    }

    notify_master /home/plat/laizy/redis/redis/script/redis_master.sh

    notify_backup /home/plat/laizy/redis/redis/script/redis_backup.sh

    track_script {

        Monitor_Redis  #健康檢查指令碼

    }

    virtual_ipaddress {

        10.0.63.251  #虛擬IP地址,可以設定多個

        }

}

5.2 Redis服務健康檢查指令碼redis_keepalive.sh

#!/bin/bash

time=$(date '+%Y-%m-%d %H:%M:%S' )

redispath=/home/plat/laizy/redis/redis

rediscli=$redispath/redis-cli

logfile=$redispath/logs/redis-state.log

oldfile=$logfile'.'$(date +%Y-%m-%d --date='30 days ago')

yesterdayfile=$logfile'.'$(date +%Y-%m-%d --date='1 days ago')

if [ -f $yesterdayfile ]

then

        echo "OK"

else

        mv $logfile $yesterdayfile >> $logfile 2>&1

        echo "$time [$yesterdayfile] Move yesterdayfile Success!" >> $logfile

fi

if [ -f $oldfile ]

then

        rm -f $oldfile >> $logfile 2>&1

        echo "$time [$oldfile] Delete Old File Success!" >> $logfile

else

        echo "no old file"

fi

status=`$rediscli -h 127.0.0.1 -p 6379 info|grep role|awk -F ":" '{print $2}'`

$rediscli -h 127.0.0.1 -p 6379 info > /dev/null

if [ $? -eq 0 ]

then

        echo "$time redis server is OK" >>$logfile

        echo The status is:$status >>$logfile

else

        echo "$time no redis service found!" >>$logfile

        sleep 1

        # try to found it again

        $rediscli -h 127.0.0.1 -p 6379 info > /dev/null

        if [ $? -eq 0 ]

        then

                echo "$time redis server is OK" >>$logfile

                echo The status is:$status >>$logfile

                #exit 0

        else

                echo "$time redis server error" >>$logfile

                #stop keepalived

                /etc/init.d/keepalived stop

                echo "$time stop keepalived" >>$logfile

        fi

fi

5.3 轉換為Master身份時觸發指令碼redis_master.sh

#!/bin/sh

localip=127.0.0.1

backip=10.0.63.246

port="6379"

 

time=$(date '+%Y-%m-%d %H:%M:%S' )

redispath=/home/plat/laizy/redis/redis

rediscli=$redispath/redis-cli

logfile=$redispath/logs/redis-state.log

for p in $port

do

{

        echo "$time redis $p is the master port" >>$logfile

        #以主機身份配置Redis服務,注意,Redis支援熱配置,即在不重啟Redis的情況

#下完成主備機身份的轉換

        $rediscli -h $localip -p $p slaveof no one >>$logfile 2>&1

}

done

5.4轉換為Backup身份時觸發指令碼redis_backup.sh

#!/bin/sh

localip=127.0.0.1

backip=10.0.63.246

port="6379"

 

time=$(date '+%Y-%m-%d %H:%M:%S' )

redispath=/home/plat/laizy/redis/redis

rediscli=$redispath/redis-cli

logfile=$redispath/logs/redis-state.log

for p in $port

do

{

        echo "$time redis $p change to $backip port" >>$logfile

        $rediscli -h $localip -p $p slaveof $backip $p  >>$logfile 2>&1

}

done

相關文章