LVS+Keepalived實現前端高可用實現

一、Keepalived簡介及VRRP原理

    Keepalived 是一個基於VRRP協議來實現的LVS服務高可用方案,可以利用其來避免單點故障。一個LVS服務會有2臺服務器運行Keepalived,一臺爲主服務器(MASTER),一臺爲備份服務器(BACKUP),但是對外表現爲一個虛擬IP,主服務器會發送特定的消息給備份服務器,當備份服務器收不到這個消息的時候,即主服務器宕機的時候, 備份服務器就會接管虛擬IP,繼續提供服務,從而保證了高可用性。Keepalived是VRRP的完美實現,因此在介紹keepalived之前,先介紹一下VRRP的原理。

    VRRP原理

    在一個VRRP虛擬路由器中,有多臺物理的VRRP路由器,但是這多臺的物理的機器並不能同時工作,而是由一臺稱爲MASTER的負責路由工作,其它的都是BACKUP,MASTER並非一成不變,VRRP讓每個VRRP路由器參與競選,最終獲勝的就是MASTER。MASTER擁有一些特權,比如,擁有虛擬路由器的IP地址,我們的主機就是用這個IP地址作爲靜態路由的。擁有特權的MASTER要負責轉發發送給網關地址的包和響應ARP請求。

    VRRP通過競選協議來實現虛擬路由器的功能,所有的協議報文都是通過IP多播(multicast)包(多播地址224.0.0.18)形式發送的。虛擬路由器由VRID(範圍0-255)和一組IP地址組成,對外表現爲一個周知的MAC地址。所以,在一個虛擬路由 器中,不管誰是MASTER,對外都是相同的MAC和IP(稱之爲VIP)。客戶端主機並不需要因爲MASTER的改變而修改自己的路由配置,對客戶端來說,這種主從的切換是透明的。

    在一個虛擬路由器中,只有作爲MASTER的VRRP路由器會一直髮送VRRP通告信息(VRRPAdvertisement message),BACKUP不會搶佔MASTER,除非它的優先級(priority)更高。當MASTER不可用時(BACKUP收不到通告信息), 多臺BACKUP中優先級最高的這臺會被搶佔爲MASTER。這種搶佔是非常快速的(<1s),以保證服務的連續性。由於安全性考慮,VRRP包使用了加密協議進行加密。

二、LVS+Keepalived實現前端高可用實現

    1、 實驗環境   

[root@localhost ~]# uname -r
2.6.32-696.el6.x86_64
[root@localhost ~]# rpm -q keepalived
keepalived-1.2.13-5.el6_6.x86_64

    時間同步:

[root@node2 ~]# ntpdate 192.168.1.200

    各主機添加host能相互解析

    關閉iptables及selinux

    wKiom1ngigqzS7FVAAA3TKgHYEE440.jpg-wh_50

    2、配置Keepalived

    1)、在192.168.1.200及192.168.1.201上安裝Keepalived(yum install keepalived -y)

    2)、配置Keepalived

    192.168.1.200配置文檔:

global_defs {               //全局配置段
   notification_email {        //管理員通知郵箱,可不填寫
      
   }
   notification_email_from root
   smtp_server 127.0.0.1       //郵件服務器地址
   smtp_connect_timeout 30
   router_id LVS_10         //主調度路由器名稱,需和備份服務器保持一致
}

vrrp_instance VI_1 {         //VRRPD配置段
    state MASTER         //設置MASTER或BACKUP         
    interface eth0         //設置VIP物理地址的接口
    virtual_router_id 51            //虛擬路由ID號,每組需保持一致
    priority 100                    //優先級,越大越有限
    advert_int 1                    //心跳頻率(秒)
    authentication {        
        auth_type PASS          //組播認證方式
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.1.250/24 dev eth0 label eth0:1 //VIP配置,可以有多個VIP
    }
}

virtual_server 192.168.1.250 80 {        //LVS段配置,注意端口
    delay_loop 3                       //健康檢測時間
    lb_algo wrr                        //算法rr,wrr,lc,wlc等
    lb_kind DR                        //集羣工作模式(nat、dr、tunl、fullnat)
    persistence_timeout 0            //會話保持時間
    protocol TCP                     //協議

    real_server 192.168.1.202 80 {    //realserver配置
        weight 1                    //權重
        TCP_CHECK {                 //健康檢查(多種方式)
            connect_port 80     //檢測端口
            connect_timeout 3   //超時時間
            nb_get_retry 3      //重試次數
            delay_before_retry 3 //重試間隔
        }
    }

    real_server 192.168.1.203 80 {
        weight 1
        TCP_CHECK {
            connect_port 80
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

192.168.1.201配置與上面類似更改state及priority

3、配置realserver

192.168.1.202配置:

DR  realserver腳本:

#!/bin/bash
#
#script to start LVS DR real server.   
# description: LVS DR real server   
#   
.  /etc/rc.d/init.d/functions
VIP=192.168.1.250 #修改你的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

執行腳本:

[root@node2 ~]# chmod +x realserver.sh 
[root@node2 ~]# ./realserver.sh start

檢查相關腳本配置是否正確

ifconfig及cat

在node2上安裝httpd後添加測試網頁

echo "<h1>node2.psemily.com</h1>" > /var/www/html/index.html

node3類似操作

4、驗證

    啓動192.168.1.200及192.168.1.201上keepalived後訪問VIP:192.168.1.250

    下圖:圖一:調度情況,圖二爲正常訪問,圖三爲192.168.1.202停止httpd後的訪問,圖四爲停止192.168.1.200後,192.168.1.201的日誌

wKioL1ngbdzylMykAAAit43LvV0851.png-wh_50

wKiom1ngbhehHkCHAAAfCCAYrTY148.png-wh_50

wKioL1nga2HA3lEZAAAahs3srCg566.png-wh_50

wKiom1ngbheDs4c-AACGWVdQxyI868.png-wh_50

5、Keepalived的健康檢測

HTTP_GET|SSL_GET|TCP_CHECK|SMTP_CHECK|MISC_CHECK

1)HTTP_GET|SSL_GET

這裏有幾個要點:

a、兩者都有兩種檢測方式,一種是簡單的基於返回碼確認;另一種是基於確認後端頁面內容hash值,確認前後是否發生變化(是不是感覺有點高端,還有簡單的防止頁面被篡改的作用,當然,動態頁面顯然不行);

b、兩者都是處理簡單的GET請求,基於post返回值確認是否正常,這種方法顯然不適用 ,不過POST方式是可以通過MISC_CHECK方式進行支持檢測的;

c、兩者配置語法上相同,只不過類型名不同而已 。同屬於大的web請求範疇,只不過一個走的HTTP協議,一個走的HTTPS協議;

基於狀態碼檢測,配置如下:

real_server 192.168.1.250 80 {
      weight 1
      HTTP_GET {
          url {
          path /index.html
          status_code 200      #http://192.168.1.250/index.html的返回狀態碼
            }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }

基於後端頁面內容檢測,配置如下:

real_server 192.168.1.250 80 {
     weight 1
     HTTP_GET {
       url {
       path /index.html
       digest 1366dcc22ca042f5e6a91232bc8f4c9f #http://192.168.1.202/index.html的digest值
        }
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }

digest是由genhash(通過該命令可以獲取頁面的hash串)生成,語法如下:

[root@localhost keepalived]# genhash -s 192.168.1.202 -p 80 -u /index.html
MD5SUM = 1366dcc22ca042f5e6a91232bc8f4c9f

2)TCP_CHECK

基於TCP的檢測,配置如下:

real_server 192.168.1.250 80 {
        weight 100
        TCP_CHECK {
            connect_timeout 3  
            nb_get_retry 3  
            delay_before_retry 3  
            connect_port 80    //檢測端口
        }
    }

3)MISC_CHECK

調用外部配置文件進行檢測,配置如下:

MISC_CHECK {
    misc_path <STRING>|<QUOTED-STRING># 外部程序或者腳本路徑
    misc_timeout <INT># 執行腳本的超時時間
    misc_dynamic #如果設置了misc_dynamic,healthchecker程序的退出狀態碼會用來動態調整服務器的權重(weight).
    #返回0:健康檢查OK,權重不被修改
    #返回1:健康檢查失敗,權重設爲0
    #返回2-255:健康檢查OK,權重設置爲:退出狀態碼-2,比如返回255,那麼weight=255-2=253
}

腳本是可以選擇傳參數還是不傳參數的,示例如下:

#不傳參配置
real_server 192.168.1.250 80 {
    weight 1
    MISC_CHECK {
      misc_path /usr/local/bin/script.sh
    }
}
#傳參配置
real_server 192.168.1.250 80 {
    weight 1
    MISC_CHECK {
      misc_path "/usr/local/bin/script.sh  arg1  arg2"
    }
}

6、實驗中遇到的問題

實驗中用當所有配置都配置完成後,有瀏覽器訪問VIP時,出現了只調度到一個realserver上的情景,過一段時間後能調度到另外一個realserver上,停止其中一個httpd,瀏覽器訪問時出現不能訪問,過段時間才能訪問運行的另一個realserver上。

查找網上資料後有以下兩種方案:

1、修改persistence_timeout 0 將連接保持時間設置爲0,修改後用瀏覽器訪問還是沒能解決。用curl可以看出效果

2、ipvsadm的時間

[root@localhost keepalived]# ipvsadm -l --timeout
Timeout (tcp tcpfin udp): 900 120 300

修改時間後訪問仍然不行

[root@localhost keepalived]# ipvsadm --set 1 1 1

上述兩種方法均不能解決瀏覽器訪問調度到一個realserver上的問題,但是用curl能看出效果,在此先做個記錄。


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