企業(yè)級(jí)WEB的負(fù)載均衡高可用之LVS+Keepalived
原創(chuàng)【51CTO.com獨(dú)家特稿】前言:
①如果四臺(tái)機(jī)器均置于IDC機(jī)房,前端無防火墻時(shí),這種情況好處理,只需要向你的IDC申請5個(gè)公網(wǎng)IP即可,多余的一個(gè)公網(wǎng)ip用于VIP;
②如果是上述網(wǎng)絡(luò)拓?fù)?,后面四臺(tái)機(jī)器均用內(nèi)網(wǎng);此時(shí)只需要前面的Juniper將內(nèi)網(wǎng)VIP映射成公網(wǎng)IP即可,注:非映射80和443端口,感謝田逸兄提供的技術(shù)性指導(dǎo)意見;
③lvs就比較依賴于網(wǎng)絡(luò)環(huán)境,可以用苛求來形容;要做好LVS管理員,確實(shí)得跟進(jìn)學(xué)習(xí)很多有關(guān)網(wǎng)絡(luò)通信方面的知識(shí),就不再是一個(gè)HTTP那么簡單了;相對而言,nginx對網(wǎng)絡(luò)的依賴較小,理論上只要ping得通,網(wǎng)頁訪問正常,nginx就能連得通。
④本來我想將公司的web環(huán)境生級(jí)成LVS+Keepalived架構(gòu),卻發(fā)現(xiàn)lvs怎么都不能轉(zhuǎn)發(fā);結(jié)果查了下機(jī)器的route情況,發(fā)現(xiàn)每臺(tái)機(jī)器都有十幾條靜態(tài)路由,二個(gè)網(wǎng)關(guān),而Network engineer也說明了網(wǎng)絡(luò)環(huán)境不可能更改,只能由系統(tǒng)環(huán)境牽就網(wǎng)絡(luò)環(huán)境;最后只能將LVS+Keepalvied更改為Nginx+Keepalived架構(gòu),甚是遺憾。
這里首先說下LVS/DR的網(wǎng)絡(luò)拓?fù)淝闆r,如果均置于電信IDC機(jī)房,用5個(gè)外網(wǎng)IP的話,整個(gè)網(wǎng)絡(luò)拓?fù)淝逦髁?,?shí)施起來也非常方便;但如果是置于Juniper防火墻后,情況就有點(diǎn)小復(fù)雜了,這時(shí)仍可用內(nèi)網(wǎng)IP,只要將內(nèi)網(wǎng)的VIP通過Juniper防火墻轉(zhuǎn)換成一個(gè)公網(wǎng)IP即可,注:此時(shí)不要做80端口的映射,在這里感謝田逸兄的指導(dǎo)性意見。
服務(wù)器故障:(服務(wù)器故障包括:服務(wù)器宕機(jī)、web服務(wù)終止、網(wǎng)線松動(dòng)等等)
①當(dāng)lvs-master故障時(shí),無法再接受用戶請求并將請求轉(zhuǎn)發(fā)給真實(shí)的web服務(wù)器(即便真實(shí)web服務(wù)器正常)從而導(dǎo)致整個(gè)web服務(wù)的癱瘓,也就是lvs控制器存在單點(diǎn)故障問題。
②當(dāng)lvs-master正常時(shí),真實(shí)地web服務(wù)器如web1-realserver故障。此時(shí)lvs-master并不知道真實(shí)服務(wù)器是否在正常提供web服務(wù),所以仍然在向故障的web1-realserver轉(zhuǎn)發(fā)用戶請求。這樣的結(jié)果是用戶請求無法被故障web服務(wù)器相應(yīng),某些用戶可以訪問網(wǎng)站有些則無法訪問。
基于以上的問題,我們需要想辦法實(shí)現(xiàn)對lvs控制器和web服務(wù)器的健康監(jiān)測,一旦服務(wù)出現(xiàn)問題能保證服務(wù)不中斷的情況下排除故障。即增加lvs控制器實(shí)現(xiàn)主備模式避免單點(diǎn)故障以及自動(dòng)刪除故障web服務(wù)結(jié)點(diǎn)并當(dāng)它恢復(fù)后再自動(dòng)添加到群集中這樣的功能,這就是LVS+keepalived能實(shí)現(xiàn)的功能。整個(gè)系統(tǒng)的拓?fù)淙缦拢?/p>
實(shí)施步驟:
①在realserver主機(jī)上實(shí)行腳本realserver,為lo:0綁定VIP地址192.168.5.188,這步分別在二個(gè)web主機(jī)上192.168.5.104、192.168.5.105實(shí)施。這步提前做,是因?yàn)橐院蟮倪^程中這一步是不會(huì)發(fā)生更改的。
- #vim /usr/local/sbin/realserver
- #!/bin/bash
- SNS_VIP=192.168.5.188
- . /etc/rc.d/init.d/functions
- case "$1" in
- start)
- ifconfig lo:0 $SNS_VIP netmask 255.255.255.255 broadcast $SNS_VIP
- /sbin/route add -host $SNS_VIP dev lo:0
- 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
- sysctl -p >/dev/null 2>&1
- echo "RealServer Start OK"
- ;;
- stop)
- ifconfig lo:0 down
- route del $SNS_VIP >/dev/null 2>&1
- 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
- echo "RealServer Stoped"
- ;;
- *)
- echo "Usage: $0 {start|stop}"
- exit 1
- esac
- exit 0
簡單說明下上述腳本的作用:
1)vip(virtual ip)。直接路由模式的vip必須跟服務(wù)器對外提供服務(wù)的ip地址在同一個(gè)網(wǎng)段,并且lvs 負(fù)載均衡器和其他所有提供相同功能的服務(wù)器都使用這個(gè)vip;
2)vip被綁定在環(huán)回接口lo0:0上,其廣播地址是其本身,子網(wǎng)掩碼是255.255.255.255。這與標(biāo)準(zhǔn)的網(wǎng)絡(luò)地址設(shè)置有很大的不同。采用這種可變長掩碼方式把網(wǎng)段劃分成只含一個(gè)主機(jī)地址的目的是避免ip地址沖突;
3)echo這段的作用是抑制arp廣播。如果不做arp抑制,將會(huì)有眾多的機(jī)器向其他宣稱:“嗨!我是奧巴馬,我在這里呢!”,這樣就亂套了。
②為二臺(tái)lvs主機(jī)安裝lvs+keepalived軟件。安裝lvs軟件是必須做的,因?yàn)閗eepalived是運(yùn)行在lvs之上的,因此lvs及keepalived必須裝在一個(gè)系統(tǒng)里面。過程如下:
- #mkdir /usr/local/src/lvs
- #cd /usr/local/src/lvs
- #wget http://www.linuxvirtualserver.org/software/kernel-2.6/ipvsadm-1.24.tar.gz
- #ln -s /usr/src/kernels/2.6.18-53.el5PAE-i686/ /usr/src/linux
- #tar zxvf ipvsadm-1.24.tar.gz
- #cd ipvsadm-1.24
- #make
- #make install
#p#③編輯keepalived.conf文件,直接用keepalived實(shí)現(xiàn)負(fù)載均衡及高可用性。
a)Keepalved的安裝
- a)Keepalved的安裝
- #wget http://www.keepalived.org/software/keepalived-1.1.15.tar.gz
- #tar zxvf keepalived-1.1.15.tar.gz
- #cd keepalived-1.1.15
- #./configure
- #make
- #make install
將keepalived做成啟動(dòng)腳務(wù),方便管理:
- #cp /usr/local/etc/rc.d/init.d/keepalived /etc/rc.d/init.d/
- #cp /usr/local/etc/sysconfig/keepalived /etc/sysconfig/
- #mkdir /etc/keepalived
- #cp /usr/local/etc/keepalived/keepalived.conf /etc/keepalived/
- #cp /usr/local/sbin/keepalived /usr/sbin/
- #service keepalived start|stop
b)Keealived的配置
①分別在主從負(fù)載均衡服務(wù)器上配置keepalived.conf ,內(nèi)容分別如下:
- ! Configuration File for keepalived
- global_defs {
- notification_email {
- yuhongchun027@163.com
- }
- notification_email_from sns-lvs@gmail.com
- smtp_server 127.0.0.1
- router_id LVS_DEVEL
- }
- vrrp_instance VI_1 {
- state MASTER
- interface eth0
- virtual_router_id 51
- priority 100
- advert_int 1
- authentication {
- auth_type PASS
- auth_pass 1111
- }
- virtual_ipaddress {
- 192.168.5.188
- }
- }
- virtual_server 192.168.5.188 80 {
- delay_loop 6
- lb_algo wrr
- lb_kind DR
- persistence_timeout 60
- protocol TCP
- real_server 192.168.5.104 80 {
- weight 3
- TCP_CHECK {
- connect_timeout 10
- nb_get_retry 3
- delay_before_retry 3
- connect_port 80
- }
- }
- real_server 192.168.5.105 80 {
- weight 3
- TCP_CHECK {
- connect_timeout 10
- nb_get_retry 3
- delay_before_retry 3
- connect_port 80
- }
- }
- }
- ! Configuration File for keepalived
- global_defs {
- notification_email {
- yuhongchun027@163.com
- }
- notification_email_from sns-lvs@gmail.com
- smtp_server 127.0.0.1
- router_id LVS_DEVEL
- }
- vrrp_instance VI_1 {
- state BACKUP
- interface eth0
- virtual_router_id 51
- priority 99
- advert_int 1
- authentication {
- auth_type PASS
- auth_pass 1111
- }
- virtual_ipaddress {
- 192.168.5.188
- }
- }
- virtual_server 192.168.5.188 80 {
- delay_loop 6
- lb_algo wrr
- lb_kind DR
- persistence_timeout 60
- protocol TCP
- real_server 192.168.5.104 80 {
- weight 3
- TCP_CHECK {
- connect_timeout 10
- nb_get_retry 3
- delay_before_retry 3
- connect_port 80
- }
- }
- real_server 192.168.5.105 80 {
- weight 3
- TCP_CHECK {
- connect_timeout 10
- nb_get_retry 3
- delay_before_retry 3
- connect_port 80
- }
- }
- }
#p#②分別在二臺(tái)lvs機(jī)上啟動(dòng)servcie keepalived start就可實(shí)現(xiàn)負(fù)載均衡及高可用集群;keepalived.conf內(nèi)容說明如下:
●全局定義塊
1、email通知。作用:有故障,發(fā)郵件報(bào)警。
2、Lvs負(fù)載均衡器標(biāo)識(shí)(lvs_id)。在一個(gè)網(wǎng)絡(luò)內(nèi),它應(yīng)該是唯一的。
3、花括號(hào)“{}”。用來分隔定義塊,因此必須成對出現(xiàn)。如果寫漏了,keepalived運(yùn)行時(shí),不會(huì)得到預(yù)期的結(jié)果。由于定義塊內(nèi)存在嵌套關(guān)系,因此很容易遺漏結(jié)尾處的花括號(hào),這點(diǎn)要特別注意。
●VRRP定義塊
1、同步vrrp組vrrp_sync_group。作用:確定失敗切換(FailOver)包含的路由實(shí)例個(gè)數(shù)。即在有2個(gè)負(fù)載均衡器的場景,一旦某個(gè)負(fù)載均衡器失效,需要自動(dòng)切換到另外一個(gè)負(fù)載均衡器的實(shí)例是哪些?
2、實(shí)例組group。至少包含一個(gè)vrrp實(shí)例。
3、Vrrp實(shí)例vrrp_instance。實(shí)例名出自實(shí)例組group所包含的那些名字。
(1)實(shí)例狀態(tài)state。只有MASTER和BACKUP兩種狀態(tài),并且需要大寫這些單詞。其中MASTER為工作狀態(tài),BACKUP為備用狀態(tài)。當(dāng)MASTER所在的服務(wù)器失效時(shí),BACKUP所在的系統(tǒng)會(huì)自動(dòng)把它的狀態(tài)有BACKUP變換成MASTER;當(dāng)失效的MASTER所在的系統(tǒng)恢復(fù)時(shí),BACKUP從MASTER恢復(fù)到BACKUP狀態(tài)。
(2)通信接口interface。對外提供服務(wù)的網(wǎng)絡(luò)接口,如eth0,eth1.當(dāng)前主流的服務(wù)器都有2個(gè)或2個(gè)以上的接口,在選擇服務(wù)接口時(shí),一定要核實(shí)清楚。
(3)lvs_sync_daemon_inteface。負(fù)載均衡器之間的監(jiān)控接口,類似于HA HeartBeat的心跳線。但它的機(jī)制優(yōu)于Heartbeat,因?yàn)樗鼪]有“裂腦”這個(gè)問題,它是以優(yōu)先級(jí)這個(gè)機(jī)制來規(guī)避這個(gè)麻煩的。在DR模式中,lvs_sync_daemon_inteface 與服務(wù)接口interface 使用同一個(gè)網(wǎng)絡(luò)接口。
(4)虛擬路由標(biāo)識(shí)virtual_router_id。這個(gè)標(biāo)識(shí)是一個(gè)數(shù)字,并且同一個(gè)vrrp實(shí)例使用唯一的標(biāo)識(shí)。即同一個(gè)vrrp_stance,MASTER和BACKUP的virtual_router_id是一致的,同時(shí)在整個(gè)vrrp內(nèi)是唯一的。
(5)優(yōu)先級(jí)priority。這是一個(gè)數(shù)字,數(shù)值愈大,優(yōu)先級(jí)越高。在同一個(gè)vrrp_instance里,MASTER 的優(yōu)先級(jí)高于BACKUP。若MASTER的priority值為150,那么BACKUP的priority只能是140或更小的數(shù)值。
(6)同步通知間隔advert_int。MASTER與BACKUP負(fù)載均衡器之間同步檢查的時(shí)間間隔,單位為秒。
(7)驗(yàn)證authentication。包含驗(yàn)證類型和驗(yàn)證密碼。類型主要有PASS、AH兩種,通常使用的類型為PASS,據(jù)說AH使用時(shí)有問題。驗(yàn)證密碼為明文,同一vrrp實(shí)例MASTER與BACKUP 使用相同的密碼才能正常通信。
4、 虛擬ip地址virtual_ipaddress??梢杂卸鄠€(gè)地址,每個(gè)地址占一行,不需要指定子網(wǎng)掩碼。注意:這個(gè)ip必須與我們在lvs客戶端設(shè)定的vip相一致!
●虛擬服務(wù)器virtual_server定義塊
虛擬服務(wù)器定義是keepalived框架最重要的項(xiàng)目了,是keepalived.conf必不可少的部分。
1、虛擬服務(wù)器virtual_server。這個(gè)ip來自于vrrp定義塊的第“4”步,后面一個(gè)空格,然后加上端口號(hào)。定義一個(gè)vip,可以實(shí)現(xiàn)多個(gè)tcp端口的負(fù)載均衡功能。
(1)delay_loop。健康檢查時(shí)間間隔,單位是秒。
(2)lb_algo。負(fù)載均衡調(diào)度算法,互聯(lián)網(wǎng)應(yīng)用常使用wlc或rr。
(3)lb_kind。負(fù)載均衡轉(zhuǎn)發(fā)規(guī)則。一般包括DR、NAT、TUN3種,在我的方案中,都使用DR的方式。
(4)persistence_timeout。會(huì)話保持時(shí)間,單位是秒。這個(gè)選項(xiàng)對動(dòng)態(tài)網(wǎng)站很有用處:當(dāng)用戶從遠(yuǎn)程用帳號(hào)進(jìn)行登陸網(wǎng)站時(shí),有了這個(gè)會(huì)話保持功能,就能把用戶的請求轉(zhuǎn)發(fā)給同一個(gè)應(yīng)用服務(wù)器。在這里,我們來做一個(gè)假設(shè),假定現(xiàn)在有一個(gè)lvs 環(huán)境,使用DR轉(zhuǎn)發(fā)模式,真實(shí)服務(wù)器有3個(gè),負(fù)載均衡器不啟用會(huì)話保持功能。當(dāng)用戶第一次訪問的時(shí)候,他的訪問請求被負(fù)載均衡器轉(zhuǎn)給某個(gè)真實(shí)服務(wù)器,這樣他看到一個(gè)登陸頁面,第一次訪問完畢;接著他在登陸框填寫用戶名和密碼,然后提交;這時(shí)候,問題就可能出現(xiàn)了---登陸不能成功。因?yàn)闆]有會(huì)話保持,負(fù)載均衡器可能會(huì)把第2次的請求轉(zhuǎn)發(fā)到其他的服務(wù)器。
(5)轉(zhuǎn)發(fā)協(xié)議protocol。一般有tcp和udp兩種。實(shí)話說,我還沒嘗試過udp協(xié)議類的轉(zhuǎn)發(fā)。
2、真實(shí)服務(wù)器real_server,也即服務(wù)器池。Real_server的值包括ip地址和端口號(hào),多個(gè)連續(xù)的真實(shí)ip。
(1)權(quán)重weight,權(quán)重值是一個(gè)數(shù)字,數(shù)值越大,權(quán)重越高。使用不同的權(quán)重值的目的在于為不同性能的機(jī)器分配不同的負(fù)載,性能較好的機(jī)器,負(fù)載分擔(dān)大些;反之,性能差的機(jī)器,則分擔(dān)較少的負(fù)載,這樣就可以合理的利用不同性能的機(jī)器資源。
(2)Tcp檢查tcp_check。
附注:以上就是lvs+keepalived的基本配置步驟,有興趣的同學(xué)建議可做下lvs的1+2的基本架構(gòu)實(shí)驗(yàn),即不需要keepalived,采用單lvs的方式,其lvs_dr腳本如下
- #vim /usr/local/sbin/lvs-dr.sh
- #!/bin/bash
- #website director vip.
- SNS_VIP=192.168.1.188
- SNS_RIP1=192.168.1.104
- SNS_RIP2=192.168.1.105
- ./etc/rc.d/init.d/functions
- logger $0 called with $1
- case "$1" in
- start)
- # set squid vip
- /sbin/ipvsadm --set 30 5 60
- /sbin/ifconfig eth0:0 $SNS_VIP broadcast $SNS_VIP netmask 255.255.255.255 broadcast $SNS_VIP up
- /sbin/route add -host $SNS_VIP dev eth0:0
- /sbin/ipvsadm -A -t $SNS_VIP:80 -s wrr -p 3
- /sbin/ipvsadm -a -t $SNS_VIP:80 -r $SNS_RIP1:80 -g -w 1
- /sbin/ipvsadm -a -t $SNS_VIP:80 -r $SNS_RIP2:80 -g -w 1
- touch /var/lock/subsys/ipvsadm >/dev/null 2>&1
- ;;
- stop)
- /sbin/ipvsadm -C
- /sbin/ipvsadm -Z
- ifconfig eth0:0 down
- route del $SNS_VIP
- rm -rf /var/lock/subsys/ipvsadm >/dev/null 2>&1
- echo "ipvsadm stoped"
- ;;
- status)
- if [ ! -e /var/lock/subsys/ipvsadm ];then
- echo "ipvsadm stoped"
- exit 1
- else
- echo "ipvsadm OK"
- fi
- ;;
- *)
- echo "Usage: $0 {start|stop|status}"
- exit 1
- esac
- exit 0
最新版更新內(nèi)容如下:
①每臺(tái)服務(wù)器都有二塊網(wǎng)卡,分別連接內(nèi)外網(wǎng);后端的mysql數(shù)據(jù)庫與web連接采用內(nèi)網(wǎng)方式,整個(gè)網(wǎng)絡(luò)環(huán)境采用內(nèi)網(wǎng);
②增加了keepalivedyiyyy .conf語法內(nèi)容;
③刪除了lvs.sh腳本內(nèi)容,直接讓keepalived內(nèi)容更直接明了,新增加了單lvs的配置腳本lvs_dr.sh;
④lvs主從機(jī)上的keepalived.conf文件我直接從生產(chǎn)服務(wù)器上download下來了,可方便大家使用。
部分內(nèi)容參考了田逸和netseek的文章,如果有任何疑問和咨詢,歡迎來郵撫琴煮酒yuhongchun027@163.com #p#
※值得注意的是:
1、你必須向你的服務(wù)器所在機(jī)房IDC多申請一個(gè)IP供VIP使用;多關(guān)注/var/log/messages和ipvsadm -ln,利用其有效信息排錯(cuò)。
2、服務(wù)器的iptables、Selinux均關(guān)閉;在生產(chǎn)環(huán)境中,我就遇到了iptables的NAT轉(zhuǎn)發(fā)問題,導(dǎo)致了lvs失敗。
3、keepalived的啟動(dòng)過程并不會(huì)對配置文件進(jìn)行語法檢查,就算沒有配置文件,keepalived的守護(hù)進(jìn)程照樣能夠被運(yùn)行起來。在默認(rèn)狀態(tài)下,即不指定配置文件的位置--keepalived先查找文件/etc/keepalived/keepalived.conf。
4、session的過程默認(rèn)是以文件的形式存在,在瀏覽器關(guān)閉或重啟時(shí)刪除;會(huì)話保持我建議寫成120秒,如果這個(gè)值設(shè)置得不合理,用戶將得到非常糟糕的訪問效果。
5、keepalived是lvs的擴(kuò)展項(xiàng)目,因此它們之間具備良好的兼容性,這點(diǎn)應(yīng)該是keepalived部署比其他類似工具能更簡潔的原因吧,lvs+keepalived目前是一個(gè)應(yīng)用于生產(chǎn)環(huán)境的成熟架構(gòu),實(shí)現(xiàn)了真正意義上的負(fù)載均衡高可用(尤其是對于Nginx+Keepalived而言),尤其適用于bbs和blog(它們均是訪問頻繁,用戶量大的對象),建議熟練掌握。





























