keepalived詳解 及 keepalived配置LVS高可用集羣

keepalived詳解 及 keepalived配置LVS高可用負載均衡集羣

       在前面《INUX集羣--均衡負載 LVS(一) LVS認知》等系列文章中我們全面認識了LVS,並手動進行了LVS的應用配置,我們知道所有用戶client端的請求都會經過LVS的負載調度器director處理再轉發給後端服務器realserver,這樣director在請求併發量大的時候會產生壓力,甚至有宕機的可能,所以我們必須爲director提供高可用功能。下面將會認識keepalived, 並進行keepalived配置LVS高可用集羣的實現。

1、認識keepalived

       keepalived的誕生最初是爲LVS ipvs(director)提供高可用性的,後來發展一個多功能、通用的輕量級高可用組件,可以爲ipvs、nginx、haproxy等諸多服務提供高可用功能,主要應用在負載均衡調度器上,同時也可以檢查後端各realserver的健康狀態。

1-1、keepalived設計組成

       如上圖,keepalived主要是模塊是VRRP Stack和Cheackers,VRRP主要實現VIP(及MAC)的高可用,下面再詳細認識其實現;Cheackers主要實現各服務如ipvs、nginx等的高可用及realserver健康狀態檢查,其中ipvs和realserver健康狀態檢查通過配置文件配置就可以實現,而其他服務高可用則需要通過自己編寫腳本,然後配置keepalived調用來實現。

       Keepalived運行有3個守護進程。父進程主要負責讀取配置文件初始化、監控2個子進程等;然後兩個子進程,一個負責VRRP,另一個負責Cheackers健康檢查。其中父進程監控模塊爲WacthDog,工作實現:每個子進程打開一個接受unix域套接字,父進程連接到那些unix域套接字並向子進程發送週期性(5s)hello包。

1-2、認識VRRP

       VRRP(Virtual Router Redundancy Protocol,虛擬路由冗餘協議)可以認爲是實現路由器高可用的協議,簡單的說,當一個路由器故障時可以由另一個備份路由器繼續提供相同的服務。

       即將N臺提供相同功能的路由器組成一個路由器組,這個組裏面有一個master和多個backup,master上面有一個對外提供服務的網關ip和虛擬mac;master會發送224.0.0.18地址組播報文,當backup收不到vrrp包時就認爲master宕掉了,這時就需要根據VRRP的優先級來選舉一個backup作爲master對外提供服務。這樣的話就可以保證路由器的高可用,對於該路由器組所在局域網內其他主機來說還是相當於一臺路由器,它們就可設置靜態缺省路由網關爲該路由器組ip了。

       虛擬mac是虛擬路由器根據虛擬路由器ID生成MA地址,格式爲:00-00-5E-00-01-{VRID},當虛擬路由器迴應ARP請求時,使用虛擬MAC地址,而不是接口的真實MAC地址。

1-2-1、爲什麼是VRRP

       對於局域網中的主機,有多種方法可以實現使其知道它的第一跳路由器地址,其中包括:1、運行某種動態路由協議,比如運行RIP或者OSPF; 2、配置靜態缺省路由,即配置網關。

       採用動態路由協議,由於管理開銷、處理開銷、安全原因以及在某些平臺上不支持等原因而不現實;在實際應用中, 使用配置靜態缺省路由, 即在主機配置網關的方法相當普遍, 這種方法具有最小化的配置和運行開銷,並且被所有基於IP的應用所支持。但是,這種方法也有缺點, 即增加了單點故障的可能性。 缺省路由器的不可用將帶來災難性的結果: 當缺省路由器失效時, 所有相連的端主機將由於不能檢測到可以替換的其他可用路徑而造成網絡中斷。

       綜合以上兩種方法存在的問題,設計產生了虛擬路由器冗餘協議(VRRP),採用了靜態缺省路由的方法,並且很好的避免了單點故障。協議定義的選舉過程提供了一個當負責轉發的主路由器失效時,備份路由器可以接替負責轉發的動態容錯機制。VRRP協議的這一優點使得每一個端主機不用配置任何動態路由協議或者路由發現協議,就可以獲得更高的可靠性。

1-2-2、VRRP工作機制

      VRRP根據優先級來確定虛擬路由器中每臺路由器的角色(Master路由器或Backup路由器)。VRRP優先級的取值範圍爲0到255(數值越大表明優先級越高),可配置的範圍是1到254,優先級0爲系統保留給路由器放棄Master位置時候使用,255則是系統保留給IP地址擁有者使用。優先級越高,則越有可能成爲Master路由器。當兩臺優先級相同的路由器同時競爭Master時,比較接口IP地址大小。接口地址大者當選爲Master。

1、初始創建的路由器工作在Initialize狀態:

      通過VRRP報文的交互獲知虛擬路由器中其他成員的優先級(keepalived是通過配置文件配置優先級,所以配置定義爲MASTER的主機優化級較高),其中優先級最高的成爲Master路由器,其他成爲Backup路由器;

2、當路由器處於Master狀態時,它將會做下列工作:

定期發送VRRP報文。

以虛擬MAC地址響應對虛擬IP地址的ARP請求。

轉發目的MAC地址爲虛擬MAC地址的IP報文。

如果它是這個虛擬IP地址的擁有者,則接收目的IP地址爲這個虛擬IP地址的IP報文。否則,丟棄這個IP報文。

如果收到比自己優先級大的報文則轉爲Backup狀態。

如果收到優先級和自己相同的報文,並且發送端的主IP地址比自己的主IP地址大,則轉爲Backup狀態。

當接收到接口的Shutdown事件時,轉爲Initialize。

3、當路由器處於Backup狀態時,它將會做下列工作:

接收Master發送的VRRP報文,判斷Master的狀態是否正常。

對虛擬IP地址的ARP請求,不做響應。

丟棄目的MAC地址爲虛擬MAC地址的IP報文。

丟棄目的IP地址爲虛擬IP地址的IP報文。

Backup狀態下如果收到比自己優先級小的報文時,丟棄報文,不重置定時器;如果收到優先級和自己相同的報文,則重置定時器,不進一步比較IP地址。

當Backup接收到MASTER_DOWN_TIMER定時器超時的事件時,纔會轉爲Master。

當接收到接口的Shutdown事件時,轉爲Initialize。

1-3、VRRP與keepalived

       從上面keepalived設計組成可以看到,keepalived實現了VRRP協議,而VRRP實現路由器高可用,keepalived則用VRRP實現在集羣中負載均衡調度器director的 VIP(和MAC)資源高可用,以及各keepalived主機的角色選舉及其狀態問題。

1-4、keepalived腦裂問題

       Keepalived的BACKUP主機在收到不MASTER主機報文後就會切換成爲master,如果是它們之間的通信線路出現問題,無法接收到彼此的組播通知,但是兩個節點實際都處於正常工作狀態,這時兩個節點均爲master強行綁定虛擬IP,導致不可預料的後果,這就是腦裂。

       腦裂問題首先是檢測,網上有以下幾個方案:

1、添加更多的檢測手段,比如冗餘的心跳線(兩塊網卡做健康監測),ping對方等等。儘量減少"裂腦"發生機會。(指標不治本,只是提高了檢測到的概率);

2、設置仲裁機制。兩方都不可靠,那就依賴第三方。比如啓用共享磁盤鎖,ping網關等。(針對不同的手段還需具體分析);

3、算法保證,比如採用投票機制(keepalived沒有實現);

       ping網關比較容易實現,主要藉助keepalived提供的vrrp_script及track_script實現:在vrrp_script定義一個跟蹤腳本,在腳本定義的檢測規則是,無法ping通網關則停止keepalived服務,但這還不能完全解決腦裂問題,因爲它們報文通信出現問題,但都可以ping的情況還是有的。

       總的來說,keepalived是面向網絡的,只是確保共享的IP地址將存在於至少一個節點,不能確保像heartbeart、corosyn/pacemaker那樣有比較完善的機制,可以保證資源的運行在一臺集羣節點上,使資源不會被併發訪問。

1-5、keepalived雙主模型

       Keepalived一般的工作模型是一主一備(多備),而雙主甚至多主也是可以的,這個雙主是指兩個VIP分別對應兩個VRRP實例(也就是兩個主備同時運行),如果兩個VIP對應同一個服務,可以在前面再加DNS輪循,對就兩條DNS的A記錄,這樣可以做到scale out 橫向擴展,並且充分利用資源。

1-6、keepalived配置文件

       keepalived只有一個配置文件keepalived.conf,安裝後可以通過"man keepalived.conf"來查看說明,裏面主要包括以下幾個配置區域,分別是global_defs、vrrp_script、vrrp_rsync_group、vrrp_instance 、virtual_server和 real_server等:

1、global_defs區域爲全局配置,主要配置realserver發生故障時的通知對象和組播地址等;

2、vrrp_script是用來配置本機服務(如nginx)健康狀態檢查腳本的,當檢查的服務發生故障時,可以配置降低優先級,配置調用則在vrrp_instance中的track_script段;

3、vrrp_instance用來定義一個VRRP實例,多主模型可以定義多個VRRP實例;其中virtual_ipaddress區域配置對外提供服務的VIP,而本機故障通知則需要在vrrp_instance區域的notify_fault配置腳本中實現,如果vrrp_script檢查服務引起的MASTER切換爲BACKUP,則在notify_backup腳本定義通知,同時可以在腳本重啓或停止該服務(注意,如果重啓服務正常,優先級會相應增加,在搶佔模式下,會重新變爲MASTER);

4、virtual_server區域則主要配置VIP和ipvs規則的,virtual_server中的real_server區域配置realserver康健狀態檢查的;

5、vrrp_rsync_group用來定義vrrp_intance組,兩個vrrp_instance同屬於一個vrrp_rsync_group,那麼其中一個vrrp_instance發生故障切換時,另一個vrrp_instance也會跟着切換(即使這個instance沒有發生故障);這在LVS NAT中VIP、DIP各一個實例用到。

      後面具體配置再詳細分析,它們在文件中的位置如下:

        global_defs {

        }

        vrrp_script chk_nginx{

        }

        vrrp_instance VI_1 {

            virtual_ipaddress {

                192.168.18.240/24 dev eth0 label eth0:0

            }

            track_script {

                chk_nginx 

            }

            notify_master "/etc/keepalived/notify.sh master"

            notify_backup "/etc/keepalived/notify.sh backup"

            notify_fault "/etc/keepalived/notify.sh fault" 

        }

        virtual_server 192.168.18.240 80 {

            real_server 192.168.18.251 80 {

            }

            real_server 192.168.18.252 80 {

            }

        }

2、配置前準備

2-1、具體使用環境資源

1、各主機系統:CentOS 6.4 x86_64

2、使用LVS DR模型,兩臺Diretocr:

Node1: IP:192.168.18.241 host name:node1.tjiyu,com;

Node2: IP:192.168.18.242 host name:node2.tjiyu.com;

VIP:192.168.18.240

3、兩臺realserver:

realserver1: IP:192.168.18.251 host name:realserver1.tjiyu,com;

realserver2: IP:192.168.18.252 host name:realserver2.tjiyu.com;

service:httpd

2-2、配置前所需要的準備

各主機需要做以下準備:

1、配置IP、關閉防火牆/SELINUX;

2、時間同步;

3、配置節點名稱和SSH互信(這兩點不是必須的,最好配置上,方便操作)

      在前面heartbeat v2 haresource 配置可用集羣說到的高可用集羣已有詳細介紹,這裏就不再給出了。

3、下載安裝

       CentOS6.4及後版本官方都提供了keepalived的rpm包,如果是低版本可以自己編譯,也可以到rpm.pbone.net搜索下載;我們這裏是CentOS6.4配置好yum源,分別在兩臺director節點上都安裝keepalived和ipvsadm,我們知道ipvs模塊整合在內核,ipvsadm只是用戶空間的一個管理工具,keepalived也沒有用到ipvsadm,這裏只是用它來查看測試而已,如下:

[root@node1 ~]# yum install -y keepalived ipvsadm

       在所有主機上都安裝httpd,兩臺realserver提供httpd服務測試,兩臺director用httpd提供failover頁面,如下:

[root@node1 ~]# yum install -y httpd

4、配置realserver

4-1、配置httpd測試

      在兩臺realserver上分別提供一個測試頁面,然後啓動httpd,用瀏覽器訪問下看是否正常,如下:

        [root@realserver1 ~]# echo "realserver1" >> /var/www/html/index.html

        [root@realserver1 ~]# service httpd start

        [root@realserver1 ~]# chkconfig httpd on

4-2、配置LVS DR相關

      我們這裏使用LVS DR模型,從前面《LINUX集羣--均衡負載 LVS(二) NAT和DR的應用配置》文章知道,需要對realserver進行一些配置,這裏把相關配置寫成腳本,分別在兩臺realserver上執行,然後查看是否正確配置了,注意腳本需要修改所使用的VIP,腳本如下:

    #!/bin/bash

    #

    # Script to start LVS DR real server.

    # description: LVS DR real server

    #

    . /etc/rc.d/init.d/functions

    VIP=192.168.18.240 #修改爲VIP

    host=`/bin/hostname`

    case "$1" in

        start)

            # Start LVS-DR real server on this machine.

            /sbin/ifconfig lo down

            /sbin/ifconfig lo up

            echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore

            echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce

            echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore

            echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce

            /sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up

            /sbin/route add -host $VIP dev lo:0

            ;; 

        stop)

            # Stop LVS-DR real server loopback device(s).

            /sbin/ifconfig lo:0 down

            echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore

            echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce

            echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore

            echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce

            ;; 

        status)

            # Status of LVS-DR real server.

            islothere=`/sbin/ifconfig lo:0 | grep $VIP`

            isrothere=`netstat -rn | grep "lo:0" | grep $VIP`

            if [ ! "$islothere" -o ! "isrothere" ];then

                # Either the route or the lo:0 device

                # not found.

                echo "LVS-DR real server Stopped." 

            else

                echo "LVS-DR real server Running." 

            fi

            ;; 

        *) 

        # Invalid entry.

        echo "$0: Usage: $0 {start|status|stop}"

        exit 1

        ;; 

    esac

    exit 0

      Node1執行如下:

    [root@realserver1 ~]# vim realserver.sh

    [root@realserver1 ~]# chmod +x realserver.sh

    [root@realserver1 ~]# ./realserver.sh start

    [root@realserver1 ~]# ifconfig

    [root@realserver1 ~]# cat /proc/sys/net/ipv4/conf/lo/arp_ignore

    [root@realserver1 ~]# cat /proc/sys/net/ipv4/conf/lo/arp_announce

    [root@realserver1 ~]# cat /proc/sys/net/ipv4/conf/all/arp_ignore

    [root@realserver1 ~]# cat /proc/sys/net/ipv4/conf/all/arp_ignore

    [root@realserver1 ~]# route –n

5、director配置功能說明

      通過/etc/keepalived/keepalived.conf配置文件和自定義腳本來實現我們的需求,下面先來說明幾點實現的功能,後面再給出配置過程和配置文件。

5-1、配置初始啓動後node1成爲主節點,node2成功備節點

      這是通過兩個節點上的配置文件配置state和priorty兩個配置項差別來實現,這也是兩個節點配置文件中僅有的兩處差別,所以在node1上配置好後,直接遠程複製到node2,再修改這兩個地方,如下(左邊是node1):

5-2、配置ipvs規則及其高可用,配置後端realserver健康狀態檢查

      這兩個功能是keepalived的基本功能,直接通過配置選項就可以實現,無需自定義其他腳本命令,注意,global_defs 段配置的郵件通知是realserver狀態發生改變時的通知。

5-3、所有realserver都宕機,定義在director提供維護頁面

      這個主要通過配置文件中的sorry_server配置項實現,當然兩個director節點主機自身要配置對外提供WEB頁面服務。

5-4、實現模擬主備切換

      一般來說主備切換髮生在master上keepalived監測的服務(如nginx)或keepalive服務本身發生故障時,監測服務需要先定義服務狀態跟蹤腳本/命令,腳本中可以檢查高可用服務的狀態,返回狀態碼0表示服務正常,配置調用則在vrrp_instance中的track_script段;但我們這裏沒有監測其他服務,所以模擬一個,定義配置如下:

    

      這裏的模擬heartbeat的standy,意思是如果在配置文件的目錄下有standy這個文件,會在vrrp實例定義的優先級減去下面的weight值,就表示期望這個節點爲備用狀態。

5-5、主備切換及故障時的狀態處理和通知

      配置文件中vrrp_instance段有三個配置項:notify_master、notify_backup和notify_fault,分別可以配置轉換爲master、backup和故障狀態時使用的腳本通知,可以自定義腳本命令,來處理這些狀態變化。

       比如說,如果vrrp_script檢查服務引起的MASTER切換爲BACKUP,則在notify_backup腳本定義通知,同時可以在腳本重啓或停止該服務(注意,如果重啓服務正常,優先級會相應增加,在搶佔模式下,會重新變爲MASTER);

       我們這裏用一個通用腳本來處理狀態變化時發送郵件通知,如下:

6、配置director

      上面說明了幾點實現的功能,下面再給出配置過程和配置文件。

6-1、配置對外提供維護頁面

      先分別在node1、node2主機自身配置對外提供WEB頁面服務,並用瀏覽器訪問測試,如下:

        [root@node2 ~]# echo "In maintenance, please come back later" >> /var/www/html/index.html

        [root@node2 ~]# chkconfig httpd on

        [root@node2 ~]# service httpd start

6-2、配置keepalived.conf文件

      接着在node1上配置keepalived.conf文件,然後遠程複製到node1,再到node2修改配置文件中的兩個差別配置,注意,配置的發件人用戶得是系統用戶,不存在發不出郵件,得先在兩節點上添加用戶,過程如下:

        [root@node1 ~]# cd /etc/keepalived/

        [root@node1 keepalived]# cp keepalived.conf keepalived.conf.bak

        [root@node1 keepalived]# vim keepalived.conf

        [root@node1 keepalived]# scp keepalived.conf root@node2:/etc/keepalived/

        [root@node1 keepalived]# useradd root_keepalived

6-3、配置keepalived狀態變化通知腳本

      接着在node1自定義notify_master、notify_backup和notify_fault狀態變化腳本notify.sh,然後遠程複製到node2,如下:

        [root@node1 keepalived]# vim notify.sh

        [root@node1 keepalived]# chmod +x notify.sh

        [root@node1 keepalived]# ll

        [root@node1 keepalived]# scp –p notify.sh root@node2:/etc/keepalived/

      下面是實現上面功能的配置文件,上面說過node2上僅有兩處差別,所以只給node1配置文件,如下:

        ! Configuration File for keepalived

        global_defs {        #全局配置,這裏額外的靜態路由並未添加因爲它是非必要的,除非我們在當前或特定的主機上生成特殊的靜態路由等

            notification_email {        #realserver故障時通知郵件的收件人地址,可以多個

                root@localhost 

            }

            notification_email_from root_keepalived         #發件人信息(可以隨意僞裝,因爲郵件系統不會驗證處理髮件人信息)

            smtp_server 127.0.0.1         #發郵件的服務器(一定不可爲外部地址)

            smtp_connect_timeout 30         #連接超時時間

            router_id LVS_DEVEL         #路由器的標識(可以隨便改動)

        }

         

        vrrp_script chk_teststandy {         # 定義服務狀態跟蹤腳本,腳本中可以檢查高可用服務的狀態,返回狀態碼0表示服務正常;配置調用則在vrrp_instance中的track_script段;這裏chk_teststandy是定義腳本的名稱,可隨意取

            script "[ -e /etc/keepalived/standy ] && exit 1 || exit 0"         #判斷命令/自己定義好的腳本路徑;#這裏的模擬heartbeatstandy,意思是如果在這個文件下有standy這個文件,會在vrrp實例定義的優先級減去下面的weight值,就表示期望這個節點爲備用狀態。

            interval 1         #每隔1秒鐘執行一次

            weight -2         #上面的命令腳本執行失敗,優先級降低2;這個值的絕對值必須大於MASTER減BACKUP定義的優先級

            fall 2         #命令/腳本執行失敗多少次纔算真的失敗

            rise 1         #命令/腳本執行成功多少次纔算真的成功

        }

         

        vrrp_instance VI_1 {         #配置虛擬路由器的實例,VI_1是自定義的實例名稱state MASTER #初始狀態,MASTER|BACKUP,當state指定的instance的初始化狀態,在兩臺服務器都啓動以後,馬上發生競選,優先級高的成爲MASTER,所以這裏的MASTER並不是表示此臺服務器一直是MASTER

            interface eth0         #通告選舉所用端口

            virtual_router_id 51         #虛擬路由的ID號(一般不可大於255)

            priority 101        #優先級信息       #備節點必須更低

            advert_int 1         #VRRP通告間隔,秒

            authentication {

                auth_type PASS         #認證機制

                auth_pass 5344         #密碼(儘量使用隨機)

            }

            virtual_ipaddress {         #虛擬地址(VIP地址)

                192.168.18.240 

            }

            track_script {          #調用上面定義的服務狀態跟蹤腳本

                chk_teststandy

            }

            #nopreempt         #設置不搶佔,這裏只能設置在state爲BACKUP的節點上,而且這個節點的優先級必須別另外的高

            #preempt delay 300         #搶佔延遲,和nopreempt一樣只能用在BACKUP上,但不能和nopreempt同時使用

            notify_master "/etc/keepalived/notify.sh -n master -a 192.168.18.240"        #轉換爲master狀態時使用此腳本通知

            notify_backup "/etc/keepalived/notify.sh -n backup -a 192.168.18.240"         #轉換爲backup狀態時使用此腳本通知

            notify_fault "/etc/keepalived/notify.sh -n fault -a 192.168.18.240"        #轉換爲fault狀態時使用此腳本通知,如果腳本帶有參數也就是有空格必須使用引號

        }


        virtual_server 192.168.18.240 80 {         #設置一個virtual server: VIP:Vport

            delay_loop 6         # service polling的delay時間,即服務輪詢的時間間隔

            lb_algo rr         #LVS調度算法:rr|wrr|lc|wlc|lblc|sh|dh

            lb_kind DR         #LVS集羣模式:NAT|DR|TUN

            #persistence_timeout 120         #會話保持時間(持久連接,秒),即以用戶在120秒內被分配到同一個後端realserver

            nat_mask 255.255.255.0

            protocol TCP         #健康檢查用的是TCP還是UDP

            real_server 192.168.18.251 80 {         #後端真實節點主機的權重等設置,主要,後端有幾臺這裏就要設置幾個

                weight 1         #給每臺的權重,rr無效

                #inhibit_on_failure         #表示在節點失敗後,把他權重設置成0,而不是衝IPVS中刪除

                #notify_up <STRING> | <QUOTED-STRING>         #檢查服務器正常(UP)後,要執行的腳本

                #notify_down <STRING> | <QUOTED-STRING>         #檢查服務器失敗(down)後,要執行的腳本

                HTTP_GET {         #健康檢查方式,一共HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK:HTTP_GET檢查url,SSL_GET檢查https url,TCP_CHECK檢查tcp連接,可用在mysql檢查

                    url {      #要檢查的URL,可以有多個

                        path /         #具體路徑

                        status_code 200         #返回成功狀態碼,也可以用另外一個選項配置返回字符串

                    }

                    connect_timeout 2         #連接超時時間

                    nb_get_retry 3         #重連次數

                    delay_before_retry 1        #重連間隔

                } 

            }

            real_server 192.168.18.252 80 {         #第二臺realserver

                weight 1

                HTTP_GET {

                    url {

                    path /

                    status_code 200

                    }

                    connect_timeout 2

                    nb_get_retry 3

                    delay_before_retry 1 

                } 

            } 

            sorry_server 127.0.0.1 80         #所有realserver都down機,定義在本機提供維護頁面

        }

下面是該notify.sh腳本的實現,如下:

        #!/bin/bash

        # description: An example of notify script

        # Usage: notify.sh -m|--mode {mm|mb} -s|--service SERVICE1,... -a|--address VIP -n|--notify {master|backup|falut} -h|--help

        contact='root@localhost'

        helpflag=0

        serviceflag=0

        modeflag=0

        addressflag=0

        notifyflag=0

        Usage() {

            echo "Usage: notify.sh [-m|--mode {mm|mb}] [-s|--service SERVICE1,...] <-a|--address VIP> <-n|--notify {master|backup|falut}>"

            echo "Usage: notify.sh -h|--help" 

        }

        ParseOptions() {

            local I=1;

            if [ $# -gt 0 ]; then

                while [ $I -le $# ]; do 

                    case $1 in 

                        -s|--service)

                            [ $# -lt 2 ] && return 3

                            serviceflag=1

                            services=(`echo $2|awk -F"," '{for(i=1;i<=NF;i++) print $i}'`)

                            shift 2 ;;

                            -h|--help)

                            helpflag=1

                            return 0

                            shift

                            ;; 

                        -a|--address)

                            [ $# -lt 2 ] && return 3

                            addressflag=1

                            vip=$2

                            shift 2

                            ;; 

                        -m|--mode)

                            [ $# -lt 2 ] && return 3

                            mode=$2

                            shift 2

                            ;; 

                        -n|--notify)

                            [ $# -lt 2 ] && return 3

                            notifyflag=1

                            notify=$2

                            shift 2

                            ;; 

                        *) 

                    echo "Wrong options..."

                    Usage

                    return 7

                    ;;

                    esac 

                done

                return 0 

            fi 

        }

        #workspace=$(dirname $0)

        RestartService() {

            if [ ${#@} -gt 0 ]; then

                for I in $@; do

                    if [ -x /etc/rc.d/init.d/$I ]; then

                        /etc/rc.d/init.d/$I restart 

                    else

                        echo "$I is not a valid service..." 

                    fi 

                done 

            fi 

        }

        StopService() {

            if [ ${#@} -gt 0 ]; then

                for I in $@; do

                    if [ -x /etc/rc.d/init.d/$I ]; then

                        /etc/rc.d/init.d/$I stop 

                    else

                        echo "$I is not a valid service..." 

                    fi 

                done 

            fi 

        }

        Notify() {

            mailsubject="`hostname` to be $1: $vip floating"

            mailbody="`date '+%F %H:%M:%S'`, vrrp transition, `hostname` changed to be $1."

            echo $mailbody | mail -s "$mailsubject" $contact 

        }

        # Main Function

        ParseOptions $@

        [ $? -ne 0 ] && Usage && exit 5

        [ $helpflag -eq 1 ] && Usage && exit 0

        if [ $addressflag -ne 1 -o $notifyflag -ne 1 ]; then

            Usage

            exit 2 

        fi

        mode=${mode:-mb}

        case $notify in

            'master')

                if [ $serviceflag -eq 1 ]; then

                RestartService ${services[*]}

                fi

                Notify master

                ;; 

            'backup')

                if [ $serviceflag -eq 1 ]; then

                if [ "$mode" == 'mb' ]; then

                StopService ${services[*]}

                else

                RestartService ${services[*]}

                fi

                fi

                Notify backup

                ;; 

            'fault')

                Notify fault

                ;; 

            *) 

            Usage

            exit 4

            ;; 

        esac

        exit 0

7、測試

7-1、啓動及測試ipvs

      分別在兩節點啓動keepalived服務,然後查看ipvs規則配置及以node1上的VIP配置(ip addr show查看),接着通過瀏覽器訪問,可以看到ipvs調度到了兩臺realserver上,如下:

        [root@node1 keepalived]# service keepalived start

        [root@node1 keepalived]# ipvsadm -L -n

        [root@node1 keepalived]# ip addr show

7-2、測試realserver健康狀態檢查

      當有realserver的WEB狀態變化時,keepalived會用郵件系統發送通知給global_defs段配置的收件人,但是測試的時候發現在收不到郵件,通過查看/var/log/messages,可以看到keepalived處理正常,而查看/var/log/maillog,發現由於配置qq郵箱,郵件被qq郵箱服務器拒絕了,如下:

        [root@node1 keepalived]# tail /var/log/messages

        [root@node1 keepalived]# tail /var/log/maillog

      我們直接用本機郵件系統接收好了,分別在兩節點修改keepalived.conf和notify.sh中的收件人地址,然後我們再停止realserver1上的httpd服務,可以看到兩節點上都發生了相應的ipvs規則改變,以及收到了realserver1 down的郵件,如下:

      然後我們又進行了realserver1 的httpd上線、下線以及realservier2下線操作,都能正常反應,如下:

7-3、測試director提供的維護頁面

      上一步,我們把兩臺realserver的httpd服務都停止,現在再訪問VIP,可以看到訪問到director提供的維護頁面,如下:

7-4、測試主備切換及其郵件通知

      我們先把兩臺realserver上線,再把前面的郵件刪除,然後在MASTER狀態的node1上的/etc/keepalived目錄創建standy文件,可以看到兩節點都收到了通知郵件,並且VIP轉移到node2上,即node1變爲了備節點,node2變爲了主節點,過程如下,

        [root@node1 keepalived]# ip addr show

        [root@node1 keepalived]# touch standy

        [root@node1 keepalived]# mail

        [root@node1 keepalived]# ip addr show

 

      然後再刪除node1上剛纔創建的standy文件,可以看到VIP迴轉到node1上,即node2變爲了備節點,node1變爲了主節點,如果沒需要回轉,可以設置非搶佔模式,具體就不說了;

7-5、測試keepalived故障轉移及其郵件通知

      和上一步差不多的,這裏直接停止MASTER狀態node1的keepalived服務,可以看到node2成爲了主節點,從瀏覽器也能正常訪問VIP到realserver,如下:

 

 

       到這裏,keepalived + LVS高可用集羣就可以正常運行了,關於前面說的腦裂問題沒有解決,待後面解決,後面將在本文件的基礎上進行keepalived + nginx高可用集羣配置……

 

 

【參考資料】

1、keepalived官網文檔http://www.keepalived.org/documentation.html

2、VRRP協議詳解:http://wenku.baidu.com/view/6007151f10a6f524ccbf85f1.html

3、LINUX集羣--均衡負載 LVS(一) LVS認知:http://blog.csdn.net/tjiyu/article/details/52489343

4、keepalived工作原理和配置說明:http://outofmemory.cn/wiki/keepalived-configuration

5、Linux 高可用(HA)集羣之keepalived詳解:http://freeloda.blog.51cto.com/2033581/1280962

6、使用keepalived來實現MySQL的failover:https://my.oschina.net/tz8101/blog/653229

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