一、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
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的日誌
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能看出效果,在此先做個記錄。