LVS和Heartbeat的安裝配置說明

1. LVS

1.1. LVS介紹
LVS是LINUX VIRTUL SERVER的簡稱,是由章文嵩博士主持的著名開放源碼項目,一個實現“三高”系統的解決方案。LVS旨在解決高速發展的Web商務中日益凸現的問題:如何在有限資金投入的情況下,最大幅度的提高Web站點的潛在服務性能。核心就是通過一組服務器來進行負載均衡,通過前端的負載調度器(Load Balancer),無縫地將網絡請求調度到真實服務器上,從而使得服務器集羣的結構對客戶是透明的,客戶訪問集羣系統提供的網絡服務就像訪問一臺高性能、高可用的服務器一樣。客戶程序不受服務器集羣的影響不需作任何修改。

系統的伸縮性通過在服務機羣中透明地加入和刪除一個節點來達到,通過檢測節點或服務進程故障和正確地重置系統達到高可用性。由於我們的負載調度技術是在Linux內核中實現的,我們稱之爲Linux虛擬服務器(Linux Virtual Server)。以下爲其大體的結構圖

LVS的設計根據透明性、性能、高可用性、可管理性和可編程性的指導思想實現的。

我們把前面那臺負載均衡機器叫做:director server(DR)。後面的實際服務機器叫做:real server(RS)

具體介紹請參考以下網址:http://www.linuxvirtualserver.org/zh

1.2. LVS的三種負載均衡模式
調度器的實現技術中,IP負載均衡技術是效率最高的,IP虛擬服務器軟件(IPVS)是在linux內核中實現的。

1.2.1. NAT模式

NAT用法本來是因爲網絡IP地址不足而把內部保留IP地址通過映射轉換成公網地址的一種上網方式(原地址NAT)。如果把NAT的過程稍微變化,就可以成爲負載均衡的一種方式。原理其實就是把從客戶端發來的IP包的IP頭目的地址在DR上換成其中一臺REAL SERVER的IP地址併發至此REAL SERVER,而REAL SERVER則在處理完成後把數據經過DR主機發回給客戶端,DR在這個時候再把數據包的原IP地址改爲DR接口上的IP地址即可。期間,無論是進來的流量,還是出去的流量,都必須經過DR。

1.2.2. IP隧道模式

隧道模式則類似於***的方式,使用網絡分層的原理,在從客戶端發來的數據包的基礎上,封裝一個新的IP頭標記(不完整的IP頭,只有目的IP部)發給REAL SERVER,REAL SERVER收到後,先把DR發過來的數據包的頭給解開,還原其數據包原樣,處理後,直接返回給客戶端,而不需要再經過DR。需要注意的是,由於REAL SERVER需要對DR發過來的數據包進行還原,也就是說必須支持IP TUNNEL協議。所以,在REAL SERVER的內核中,必須編譯支持IP TUNNEL這個選項。IP TUNNEL也在Networking options裏面,如下圖所示。

1.2.3. 直接路由模式
直接路由模式比較特別,很難說和什麼方面相似,前2種模式基本上都是工作在網絡層上(三層),而直接路由模式則應該是工作在數據鏈路層上(二層)。其原理爲,DR和REAL SERVER都使用同一個IP對外服務。但只有DR對ARP請求進行響應,所有REAL SERVER對本身這個IP的ARP請求保持靜默。也就是說,網關會把對這個服務IP的請求全部定向給DR,而DR收到數據包後根據調度算法,找出對應的REAL SERVER,把目的MAC地址改爲REAL SERVER的MAC併發給這臺REAL SERVER。這時REAL SERVER收到這個數據包,則等於直接從客戶端收到這個數據包無異,處理後直接返回給客戶端。由於DR要對二層包頭進行改換,所以DR和REAL SERVER之間必須在一個廣播域,也可以簡單的理解爲在同一臺交換機上。

具體請參考以下網址:http://www.linuxvirtualserver.org/zh/lvs3.html

1.3. LVS的安裝和配置

LVS的安裝在其官方網站上有詳細的說明文檔。網址是:http://www.austintek.com/LVS/LVS-HOWTO/HOWTO/ 。不過一般說來以下網址http://www.austintek.com/LVS/LVS-HOWTO/mini-HOWTO/LVS-mini-HOWTO.html就足夠了。

1.3.1. 讓DR內核支持 IPVS
2.6及以上內核中已經支持了IPVS功能。至於2.4的內核則看版本,2.4.23及以上的內核已經有了ipvs,所以不必且不能打包,如果打了就會編譯出錯。對於2.4.23以下內核則必須打IPVS補丁。2.4.23/24的內核有問題,所以不建議使用這兩種內核。

IPVS只對DR需要,而RS則不需要。

Ipvs補丁和ipvsadm的下載地址:http://www.linuxvirtualserver.org/software/ipvs.html.

1.3.1.1. 打補丁來支持ipvs

對於2.4.23以下內核需要這個步驟,否則請按1.3.1.2步驟。

到http://www.linuxvirtualserver.org/software/ipvs.html下載對應的補丁。假設你使用的內核是2.4.18, 那麼下載Version 1.0.10,包爲ipvs-1.0.10.tar.gz。解包後閱讀README文件,按中其中的方法打包。不過我對這裏的說明有點不明白。下面我說說我的方法:

cd <ipvs的解壓目錄>

make patchkernel

make installsource

或者

cd /usr/src/linux

cp <ipvs的解壓目錄>/linux_kernel_ksyms_c.diff ./

cp <ipvs的解壓目錄>/linux_net_netsyms_c.diff ./

patch –p1 < linux_kernel_ksyms_c.diff

patch –p1 < linux_net_netsyms_c.diff

然後cd /usr/src/linux

make dep; make bzImage;

接着重新copy新的內核文件,然後lilo,然後reboot

1.3.1.2. 重新配置內核選項來支持IPVS
對於2.4.23及以上的內核已經有了ipvs,所以你可以直接在內核中配置來支持IPVS。

cd /usr/src/linux

make menuconfig

對於不同版本的內核來說,各個配置項的路徑是不一致的。對於2.6.8.1菜單路徑是:Device Drivers->Networking support -> Networking options->IP: Virtual Server Configuration。而在2.4.30的內核中Networking options就在第一層路徑下面。請到目的菜單Networking

請選中所有的選項。

要關注的是IPVS connection table size,這個東西意思是每個連接的hash table的大小,大家知道通常hash表越大,一次命中的機會越大。這裏取值範圍是2-20,2的2次方到2的20次方。有的資料建議用20,個人認爲默認值就足夠了。由於每個連接需要128BYTE,每個HASH位需要8BYTE,所以(128 + 8 ) * 2^20 = 128M + 8 M = 136M,對於我們的系統沒問題。

最後的是IPVS application helper,這種是專門針對多次連接的情況的(可以理解爲session),大家都知道一次FTP通訊需要2次連接,所以必須保證這兩次都在一臺服務器上,否則將連接失敗。這是個明顯針對協議,或者說針對應用層的分類。有點七層交換的味道,希望這個功能儘快把HTTP的SESSION給加上,到時就不用使用後臺同步SESSION或者對原地址做HASH定向處理了。

這裏負載調度算法的意思請具體參考:http://www.linuxvirtualserver.org/zh/lvs4.html

make dep; make bzImage;

接着重新copy新的內核文件,然後lilo,然後reboot。啓動時可以看到ipvs提示信息。

1.3.2. RS的NOARP問題解決
直接路由模式肯定要處理NOARP的問題,官方文檔《LVS-mini-HOWTO》3.7節指出在如下情況下必須處理:

IF( (you are using LVS-DR or LVS-Tun on the director)
AND
(you are running a Linux 2.2.x, 2.4.x, 2.6.x kernel on a realserver)
AND
(
the VIP on the realserver is on an ethernet device eg lo:0, tunl0:0
i.e. packets to the VIP are not being accepted by transparent proxy
)
AND
(
the realservers can answer arp requests from
the client/router (the realservers are on the same
piece of wire|network|segment as the director)
) )
THEN { YOU MUST HANDLE THE ARP PROBLEM }
FI
對於這斷話的,我不太理解。下面引用其它的文檔說明。

在使用LVS中的DR與IP Tunnel的時候,會需要有一塊網絡卡要設定兩個IP的情形,但是Linux在2.2.14之後,就將eth0:1的-NOARP這個FLAG關閉。也就是說在kernel 2.2.14以後,eth0:1就視爲eth0的別名,任何對eth0:1的設定也同樣作用在eth0,換句話說,我對eth0:1下-NOARP,同樣也會對eth0有作用,這樣會使得整張網絡卡收不到封包。

在直接路由、IP隧道模式下,因爲我所有的機器都放在同一個網段,當該網段的Router接收到客戶端(Client)對虛擬IP(Virtual IP)的TCP connection要求時,會先在網段中利用Arp request詢問誰有VIP的地址,而包含Director與RealServers上所有的interface(不管Primary還是Subinterface),只要他有那個ip,都會發送arp reply回去,造成網段內所有擁有Virtual IP的interface都會reply給Router,最後結果就是看誰的速度快,Router就將該封包送給誰,如此會造成LVS的Server並無法發揮其效果,因此需要利用hidden這個pattch,將Subinterface上的Virtual IP給隱藏起來,如此他就不會對Arp Request進行Reply,如此就可以解決ARP的問題,而這個NOARP的問題,kernel發展小組認爲不重要,所以以後都不會修改,要用請自行編譯。

所以從http://www.ssi.bg/~ja/#hidden下載對應的補丁,對於2.6.8.1的內核我選擇hidden-2.6.4-1.diff。

cp hidden-2.6.4-1.diff /usr/src/linux

cd /usr/src/linux

patch –p1 < hidden-2.6.4-1.diff

make dep;make bzImage;

copy新的內核文件到相應的啓動目錄。再lilo。最後reboot。

當然解決noarp的問題,不止這一種。譬如leofan在內核中通過以下四個命令解決,前提條件是有這些設備:

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

不過我在2.6.8.1的內核中試了一下好像不行。Lvs把包固定發給了rs1這臺機器,估計rs1arp reply響應最快。

1.3.3. 安裝ipvsadm
這是一個IPVS的管理工具,提供了一個和IPVS打交道的接口,包括配置IPVS和連接信息統計。到地址:http://www.linuxvirtualserver.org/software/ipvs.html去下載相應的版本。對於2.6.8.1內核,下了ipvsadm-1.24-5.src.rpm。

rpm ipvsadm的存放路徑/ipvsadm-1.24-5.src.rpm

cd /usr/src/rpm/SOURCE/

tar –zxvf ipvsadm-1.24.tar.gz

cd ipvsadm-1.24

make ; make install

然後:

ipvsadm,如果出現以下提示說明已經安裝成功。

IP Virtual Server version 1.2.0 (size=4096)

Prot LocalAddress:Port Scheduler Flags

-> RemoteAddress:Port Forward Weight ActiveConn InActConn

ipvsadm的具體用法可參考 man ipvsadm.

1.3.4. Ipvsadm的配置
根據http://www.austintek.com/LVS/LVS-HOWTO/mini-HOWTO/LVS-mini-HOWTO.html4節和5結節的說明,Ipvsadm的配置可以用官方的配置腳本配置,配置腳本可在http://www.austintek.com/LVS/下載,也可以手工敲入命令配置。

官方的腳本使用perl寫的,配置腳本的命令爲包中文件名爲cofigure的文件, 包中的lvs_dr.conf.one_NIC_one_network等文件是一些配置信息,作爲configure的參數傳入.下面這個命令對應兩臺real server的配置, 需要自己修改lvs_dr.conf.one_NIC_two_network中的信息.

./configure lvs_dr.conf.one_NIC_two_network

不過本人試了一下自動配置沒有成功,就手工配置了.讀者有興趣可自行研究如何使用官方配置腳本配置。

1.3.4.1. DR的配置
對於前臺負載均衡服務器Direcrt Server(DR)的配置,我自己做一個配置腳本 config_vs.sh。裏面的參數請自己替換。

#/bin/sh

#file: config_vs.sh 這裏默認使用網卡eth0,如果想用其它網卡請自行替換即可。

VIP=172.30.31.200 #DR的虛擬服務IP

DIP=172.30.31.68 #DR的eth0真實地址

RS1=172.30.31.66 #real server1的真實地址

RS2=172.30.31.67 #real server2的真實地址

GW=172.30.31.1 #DR使用的網關或路由的地址

SERVICE=22 #你的服務端口

cat /proc/sys/net/ipv4/ip_forward #腳本調試信息

echo "0" >/proc/sys/net/ipv4/ip_forward

echo "1" >/proc/sys/net/ipv4/conf/all/send_redirects #腳本調試信息

cat /proc/sys/net/ipv4/conf/all/send_redirects #腳本調試信息

echo "1" >/proc/sys/net/ipv4/conf/default/send_redirects

cat /proc/sys/net/ipv4/conf/default/send_redirects#腳本調試信息

echo "1" >/proc/sys/net/ipv4/conf/eth0/send_redirects

cat /proc/sys/net/ipv4/conf/eth0/send_redirects #腳本調試信息

/sbin/ifconfig eth0 ${DIP} #配置所使用的網卡IP

#配置虛擬服務IP

/sbin/ifconfig eth0:0 ${VIP} broadcast ${VIP} netmask 255.255.255.255

/sbin/route add -host ${VIP} dev eth0:0 #添加虛擬IP的路由

/sbin/route add default gw ${GW} #添加本地路由

/sbin/ifconfig eth0:0 #腳本調試信息, 顯示虛擬IP配置

#/bin/ping -b ${VIP} #腳本調試信息, 看看虛擬IP是否可以ping通

/sbin/route -n #腳本調試信息,顯示路由信息

/sbin/ipvsadm –C #清除虛擬服務器表,也就是清除IPVS的原配置

#添加服務及輪調調度算法,-t:tcp服務,-A:添加服務; -s rr:指定調度算法爲輪調

/sbin/ipvsadm -A -t ${VIP}:${SERVICE} -s rr

#添加real server, -a:添加一臺RS, -t:tcp服務,-r: RS的地址,-g:直接路由模式。

#這裏語句個數隨real server的個數而定

/sbin/ipvsadm -a -t ${VIP}:${SERVICE} -r ${RS1} -g

/sbin/ipvsadm -a -t ${VIP}:${SERVICE} -r ${RS2} -g

ping -c 1 ${RS1} #腳本調試信息

ping -c 1 ${RS2} #腳本調試信息

/sbin/ipvsadm #腳本調試信息

#end of config_vs.sh

補:由於DR是個單點,爲了保證高可用幸,我們使用了開源包Heartbeat來保證。所以有兩臺DR,一臺爲主,一臺爲輔。各自都可用這個腳本來配置,不過DIP要該成各自的真實地址,其它選項必須完全相同。

1.3.4.2. RS的配置

對於real server(RS)的配置,我自己做一個配置腳本 config_rs.sh。裏面的參數請自己替換。

#/bin/sh

#file: config_rs.sh這裏默認使用網卡eth0,如果想用其它網卡請自行替換即可。

VIP=172.30.31.200 #DR的虛擬服務IP

#DR的eth0真實地址,作用是在配置時測試DR的IP是否有效。但是DR切換後,DIP變了,所以這項取消了。

#DIP=172.30.31.68

LOCALIP=172.30.31.66 #real server1的真實地址

GW=172.30.31.1 #real server使用的網關或路由的地址

/sbin/ifconfig eth0 ${LOCALIP} #配置eth0的本地IP

/sbin/route add default gw ${GW} #添加默認路由

/bin/netstat -rn #腳本調試信息

ping -c 1 ${GW} #腳本調試信息,是否可以ping通網關

echo "0" >/proc/sys/net/ipv4/ip_forward

cat /proc/sys/net/ipv4/ip_forward #腳本調試信息,ip_forward是否配置正確

ping -c 1 ${DIP} #腳本調試信息, 是否可以ping通DR的真實地址

ping –c 1 ${VIP} #是否可以ping通虛擬DR的IP

#按照real server的虛擬IP

/sbin/ifconfig lo:0 ${VIP} broadcast ${VIP} netmask 0xffffffff up

#配置出口

/sbin/ifconfig lo:0

#在lo:0上添加去虛擬IP的路由

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

/bin/netstat -rn #腳本調試信息

echo "1" >/proc/sys/net/ipv4/conf/all/hidden

cat /proc/sys/net/ipv4/conf/all/hidden #腳本調試信息

echo "1" >/proc/sys/net/ipv4/conf/lo/hidden

cat /proc/sys/net/ipv4/conf/lo/hidden #腳本調試信息

#end of config_rs.sh

不同real server配置時只要改變LOCALIP選項就可以了。我只添加了172.30.31.66(real server 1)和172.30.31.67(real server 2)兩臺機器。DR的主節點名稱爲heatbeat1,副節點名稱爲heartbeat2

1.4. 試運行結果
安裝上面的說明走完所有的步驟後,我用ssh測試了一下。奇數次去了172.30.31.66這臺機器,偶數次去了172.30.31.67這臺機器

2. heartbeat

2.1. heartbeat的介紹

這裏的heartbeat就是linux-ha項目,被許多高可用系統採用。我們這裏lvs必須是個高可用系統,所以我們採用heartbeat。本文也以lvs作爲高可用服務來說明heartbeat的使用。Heartbeat的高版本可以負責3個及以上的節點。本文2個節點來說明,在你的兩臺機器(一臺作爲主節點,另一臺爲從節點)上運行heartbeat, 並配置好相關的選項,最重要的是lvs資源一定要配置進去。那麼開始時主節點提供lvs服務,一旦主節點崩潰,那麼從節點立即接管lvs服務。如果是自己開啓了其它的服務資源,那麼接管的時候,該服務資源相應的tcp連接必須重連,而且主從節點的應用層邏輯狀態有應用層自己保證一致。Lvs不存在應用層的邏輯狀態。

具體介紹請參考:http://www.linux-ha.org/

2.2. libnet的安裝
安裝heatbeat前必須先安裝libnet包,請到http://www.packetfactory.net/projects/libnet/地址下載。libnet提供了一些高層的api,讓應用程序開發者可以修改網絡包。我下的包爲libnet.tar.gz,版本爲1.1.2.1

cd 存放路徑

tar –zxvf libnet.tar.gz

cd libnet

./configure; make ; make install

2.3. heartbeat的安裝
到http://linux-ha.org/download/index.html下載相應的版本,對於2.6.8.1我下載了最新的穩定版本heartbeat-2.0.2.tar.gz。

cd 存放路徑

tar –zxvf heartbeat-2.0.2.tar.gz

cd heartbeat-2.0.2

./Configureme configure

make ; make install

上述步驟完成後,heartbeat的運行程序文件爲/etc/rc.d/heartbeat。並且出現/etc/ha.d目錄。

2.4. heartbeat的配置

heartbeat的配置信息非常複雜,但是最關鍵也就是那麼幾項。如果你要自己弄懂所有配置選項,那麼自己參考:http://www.linux-ha.org/ConfiguringHeartbeat中的文檔,特別是《Getting Started with Linux-HA(heartbeat)》文檔。

這裏需要配置文件有三個:ha.cf、haresources、authkeys。這三個配置文件需要在/etc/ha.d目錄下面,但是默認是沒有這三個文件的,所以你要

copy存放路徑/ heartbeat-2.0.2/doc/ha.cf /etc/ha.d/

copy存放路徑/ heartbeat-2.0.2/doc/ haresources /etc/ha.d/

copy存放路徑/ heartbeat-2.0.2/doc/ authkeys /etc/ha.d/

2.4.1. authkeys
這個配置文件非常簡單,就是在auth選擇一個值。每個值對應一種算法,這個算法是在主節點和從節點間數據校驗用的。這個配置文件權限必須是0600。

Chmod 0600 authkeys

自己選一種算法。我選md5。

配置文件的值如下:

auth 3

#1 crc

#2 sha1 HI!

3 md5 Hello!

2.4.2. haresources
這個文件配置的是節點要管理的資源也就你的高可用服務,這些資源在主節點down調時候,從節點就會開啓這些資源。Heartbeat認爲

你配置資源名稱 start/stop

就可以開啓/停止這些資源。所以讓你的資源支持start/stop。其實這你只需要對你的應用服務作個腳本,腳本接受start參數就會啓動應用服務,接受stop參數就會停止服務。個人建議,你什麼都不要做,就把應用程序名當作資源名就可以了,啓動資源名的時候就自動啓動你的服務了。而在down機的時候,所有的程序都死了,根本就不需要heartbeat調用

你配置資源名稱stop

命令來結束程序。

在文件中找到:

#node1 10.0.0.170 Filesystem::/dev/sda1::/data1::ext2

這一項,去掉#號,根據格式配置你的資源。第一字段(Node1):主節點名稱(必須uname –n的保持一致);第二字段(10.0.0.170):對外虛擬服務IP;第三字段(Filesystem::/dev/sda1::/data1::ext2):Filesystem表示資源名稱,/dev/sda1表示資源啓動時的第一個參數,/data1表示第二個參數,/ext2表示第三個參數,依此類推。我們的lvs的配置如下所示:

heartbeat1 172.30.27.200 config_vs.sh

heartbeat1是主節點的名稱。172.30.27.200是對外服務的虛擬IP,也是lvs對外服務的虛擬IP。Config_vs.sh是資源名稱,因爲這個就是DR的配置文件腳本,只要執行過這個腳本那麼機器就變成DR了。

2.4.3. ha.cf
這個配置文件比較複雜。我只配了關鍵的幾項:

debugfile /var/log/ha-debug

說明:調試日誌文件文件,取默認值

logfile /var/log/ha-log

說明:系統運行日誌文件,取默認值

logfacility local0

說明:日誌等級,取默認值

keepalive 1

說明:心跳頻率,自己設定。1:表示1秒;200ms:表示200毫秒

deadtime 10

說明:節點死亡時間閥值,就是從節點在過了10後還沒有收到心跳就認爲主節點死亡,自己設定

warntime 5

說明:發出警告時間,自己設定

udpport 28855

說明:心跳信息傳遞的udp端口,自己設定

#bcast eth0 # Linux

說明:採用udp廣播播來通知心跳,建議在副節點不只一臺時使用

ucast eth0 172.30.31.68

說明:採用網卡eth0的udp單播來通知心跳,eth0的IP

#mcast eth0 225.0.0.1 694 1 0

說明:採用udp多播播來通知心跳,建議在副節點不只一臺時使用

auto_failback off

說明:主節點重啓成功後,資源是自動拿回到主節點還是等到副節點down調後拿回資源

node heartbeat1

說明:主節點名稱,與uname –n保持一致。排在第一的默認爲主節點,所以不要搞措順序

node heartbeat2

說明:副節點名稱,與uname –n保持一致

watchdog /dev/watchdog

說明:看門狗。如果本節點在超過一分鐘後還沒有發出心跳,那麼本節點自動重啓

以上這些是我個人認爲必配項,下面這些是可選項。

stonith baytech /etc/ha.d/conf/stonith.baytech

說明:主/副等所有節點的一種校驗。

respawn userid /path/name/to/run

說明:和heartbeat必須一起啓動的本地服務

ping 10.10.10.254

說明:僞節點IP,僞節點就是其失效時主/副節點不會正常工作但本身不是主/副節點之一。

respawn hacluster /usr/lib/heartbeat/ipfail

說明:與ping選項一起使用,取默認值。

baud 19200

說明:串口波特率,與serial一起使用。

serial /dev/ttyS0 # Linux

說明:採用串口來傳遞心跳信息。

2.5. 運行結果

在主節點heartbeat1(172.30.31.68)和副節點heartbeat2(172.30.31.69)啓動heatbeat

/etc/rc.d/heartbeat start

這時,我用ssh登錄172.30.31.200,第一次登錄進17230.31.66,第二次則17230.31.67,第三次17230.31.66. 在主節點輸入ipvsadm,顯示

IP Virtual Server version 1.2.0 (size=4096)

Prot LocalAddress:Port Scheduler Flags

-> RemoteAddress:Port Forward Weight ActiveConn InActConn

TCP 172.30.31.200:ssh rr

-> 172.30.31.67:ssh Route 1 1 1

-> 172.30.31.66:ssh Route 1 2 0

這時,reboot 主節點172.30.31.68, 那麼以前的連接失效, 副節點172.30.31.69::/var/log/ha-log中顯示主節點死亡,然後本節點接管資源. 這時再用ssh登錄172.30.31.200,依然可以.只是所有的登錄已經通過副節點轉發.

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