一、簡介
LVS是Linux Virtual Server的簡稱,也就是Linux虛拟伺服器, 是一個由章文嵩博士發起的自由軟體項目,它的官方站點是www.linuxvirtualserver.org。現在LVS已經是 Linux标準核心的一部分,在Linux2.4核心以前,使用LVS時必須要重新編譯核心以支援LVS功能子產品,但是從Linux2.4核心以後,已經完全内置了LVS的各個功能子產品,無需給核心打任何更新檔,可以直接使用LVS提供的各種功能。
使用LVS技術要達到的目标是:通過LVS提供的負載均衡技術和Linux作業系統實作一個高性能、高可用的伺服器群集,它具有良好可靠性、可擴充性和可操作性。進而以低廉的成本實作最優的服務性能。
LVS自從1998年開始,發展到現在已經是一個比較成熟的技術項目了。可以利用LVS技術實作高可伸縮的、高可用的網絡服務,例如WWW服務、Cache服務、DNS服務、FTP服務、MAIL服務、視訊/音頻點播服務等等,有許多比較著名網站群組織都在使用LVS架設的叢集系統,例如:Linux的門戶網站(www.linux.com)、向RealPlayer提供音頻視訊服務而聞名的Real公司(www.real.com)、全球最大的開源網站(sourceforge.net)等。
二、拓撲圖
<a href="http://s3.51cto.com/wyfs02/M02/24/3D/wKiom1NNM8HDW5YMAACXkLGNMeI888.jpg" target="_blank"></a>
說明:1.用戶端隻知道我們的LVS的VIP的位址
2.由于伺服器有限,此處我們的apache和php做在一台機器上
三。排程算法
Director在接收到來自于Client的請求時,會基于"schedule"從RealServer中選擇一個響應給Client。ipvs支援以下排程算法:
1、輪詢(round robin, rr),權重輪詢(Weighted round robin, wrr)——新的連接配接請求被輪流配置設定至各RealServer;算法的優點是其簡潔性,它無需記錄目前所有連接配接的狀态,是以它是一種無狀态排程。輪叫排程算法假設所有伺服器處理性能均相同,不管伺服器的目前連接配接數和響應速度。該算法相對簡單,不适用于伺服器組中處理性能不一的情況,而且當請求服務時間變化比較大時,輪叫排程算法容易導緻伺服器間的負載不平衡。
2、最少連接配接(least connected, lc), 權重最少連接配接(weighted least connection, wlc)——新的連接配接請求将被配置設定至目前連接配接數最少的RealServer;最小連接配接排程是一種動态排程算法,它通過伺服器目前所活躍的連接配接數來估計伺服器的負載情況。排程器需要記錄各個伺服器已建立連接配接的數目,當一個請求被排程到某台伺服器,其連接配接數加1;當連接配接中止或逾時,其連接配接數減一。
3、基于局部性的最少連結排程(Locality-Based Least Connections Scheduling,lblc)——針對請求封包的目标IP位址的負載均衡排程,目前主要用于Cache叢集系統,因為在Cache叢集中客戶請求封包的目标IP位址是變化的。這裡假設任何後端伺服器都可以處理任一請求,算法的設計目标是在伺服器的負載基本平衡情況下,将相同目标IP位址的請求排程到同一台伺服器,來提高各台伺服器的通路局部性和主存Cache命中率,進而整個叢集系統的處理能力。LBLC排程算法先根據請求的目标IP位址找出該目标IP位址最近使用的伺服器,若該伺服器是可用的且沒有超載,将請求發送到該伺服器;若伺服器不存在,或者該伺服器超載且有伺服器處于其一半的工作負載,則用“最少連結”的原則選出一個可用的伺服器,将請求發送到該伺服器。
4、帶複制的基于局部性最少連結排程(Locality-Based Least Connections with Replication Scheduling,lblcr)——也是針對目标IP位址的負載均衡,目前主要用于Cache叢集系統。它與LBLC算法的不同之處是它要維護從一個目标IP位址到一組伺服器的映射,而 LBLC算法維護從一個目标IP位址到一台伺服器的映射。對于一個“熱門”站點的服務請求,一台Cache 伺服器可能會忙不過來處理這些請求。這時,LBLC排程算法會從所有的Cache伺服器中按“最小連接配接”原則選出一台Cache伺服器,映射該“熱門”站點到這台Cache伺服器,很快這台Cache伺服器也會超載,就會重複上述過程選出新的Cache伺服器。這樣,可能會導緻該“熱門”站點的映像會出現在所有的Cache伺服器上,降低了Cache伺服器的使用效率。LBLCR排程算法将“熱門”站點映射到一組Cache伺服器(伺服器集合),當該“熱門”站點的請求負載增加時,會增加集合裡的Cache伺服器,來處理不斷增長的負載;當該“熱門”站點的請求負載降低時,會減少集合裡的Cache伺服器數目。這樣,該“熱門”站點的映像不太可能出現在所有的Cache伺服器上,進而提供Cache叢集系統的使用效率。LBLCR算法先根據請求的目标IP位址找出該目标IP位址對應的伺服器組;按“最小連接配接”原則從該伺服器組中選出一台伺服器,若伺服器沒有超載,将請求發送到該伺服器;若伺服器超載;則按“最小連接配接”原則從整個叢集中選出一台伺服器,将該伺服器加入到伺服器組中,将請求發送到該伺服器。同時,當該伺服器組有一段時間沒有被修改,将最忙的伺服器從伺服器組中删除,以降低複制的程度。
5、目标位址散列排程(Destination Hashing,dh)算法也是針對目标IP位址的負載均衡,但它是一種靜态映射算法,通過一個散列(Hash)函數将一個目标IP位址映射到一台伺服器。目标位址散列排程算法先根據請求的目标IP位址,作為散列鍵(Hash Key)從靜态配置設定的散清單找出對應的伺服器,若該伺服器是可用的且未超載,将請求發送到該伺服器,否則傳回空。
6、源位址散列排程(Source Hashing,sh)算法正好與目标位址散列排程算法相反,它根據請求的源IP位址,作為散列鍵(Hash Key)從靜态配置設定的散清單找出對應的伺服器,若該伺服器是可用的且未超載,将請求發送到該伺服器,否則傳回空。它采用的散列函數與目标位址散列排程算法的相同。除了将請求的目标IP位址換成請求的源IP位址外,它的算法流程與目标位址散列排程算法的基本相似。在實際應用中,源位址散列排程和目标位址散列排程可以結合使用在防火牆叢集中,它們可以保證整個系統的唯一出入口。
四、實作步驟
1.網絡規劃
用途
ip位址
版本号
系統版本号
叢集伺服器
192.168.1.202
ipvsadm1.26
centos6.5
apache+php1
192.168.1.201
apache2.4.9
php5.4.26
apache+php2
192.168.1.100
資料庫
192.168.1.200
MariaDB10.0.10
對外提供服務的ip位址
192.168.1.230
2.本處的apache、php、MariaDB都為編譯安裝
關于編譯安裝的操作,請移步本人的相關部落格http://wangfeng7399.blog.51cto.com/3518031/1381688,本處就不再做累贅
特别說明,如果是編譯安裝的話應該在httpd的配置檔案中添加KeepAlive Off用來關閉httpd的會話保持
3.叢集配置方法
①、前段LVS叢集伺服器的配置
1
2
3
4
<code>在eth0:</code><code>0</code><code>上設定對外提供的位址</code>
<code>[root@localhost ~]# ifconfig eth0:</code><code>0</code> <code>192.168</code><code>.</code><code>1.230</code><code>/</code><code>24</code> <code>netmask </code><code>255.255</code><code>.</code><code>255.255</code> <code>broadcast </code><code>192.168</code><code>.</code><code>1.230</code> <code>up</code>
<code>設定路由</code>
<code>[root@localhost ~]# route add -host </code><code>192.168</code><code>.</code><code>1.230</code> <code>dev eth0:</code><code>0</code>
②、背景兩個Real Server伺服器的配置
5
6
7
8
<code>設定網卡隻對有eth0網卡上的ip位址做通告</code>
<code>[root@httpweb ~]# echo </code><code>1</code> <code>> /proc/sys/net/ipv4/conf/all/arp_ignore</code>
<code>[root@httpweb ~]# echo </code><code>1</code> <code>> /proc/sys/net/ipv4/conf/eth0/arp_ignore</code>
<code>[root@httpweb ~]# echo </code><code>2</code> <code>> /proc/sys/net/ipv4/conf/eth0/arp_announce</code>
<code>[root@httpweb ~]# echo </code><code>2</code> <code>> /proc/sys/net/ipv4/conf/all/arp_announce</code>
<code>在lo上設定叢集服務的ip位址</code>
<code>[root@httpweb ~]# ifconfig lo:</code><code>0</code> <code>192.168</code><code>.</code><code>1.230</code> <code>netmask </code><code>255.255</code><code>.</code><code>255.255</code> <code>broadcast </code><code>192.168</code><code>.</code><code>1.230</code> <code>up</code>
<code>[root@httpweb ~]# route add -host </code><code>192</code><code>.l68.</code><code>1.230</code> <code>dev lo:</code><code>0</code>
③、兩台服務的配置均為一樣
④、設定叢集服務
<code>[root@localhost ~]# ipvsadm -A -t </code><code>192.168</code><code>.</code><code>1.230</code><code>:</code><code>80</code> <code>-s rr</code>
<code>[root@localhost ~]# ipvsadm -a -t </code><code>192.168</code><code>.</code><code>1.230</code><code>:</code><code>80</code> <code>-r </code><code>192.168</code><code>.</code><code>1.100</code> <code>-g</code>
<code>[root@localhost ~]# ipvsadm -a -t </code><code>192.168</code><code>.</code><code>1.230</code><code>:</code><code>80</code> <code>-r </code><code>192.168</code><code>.</code><code>1.201</code> <code>-g</code>
⑤、測試
<code>[root@localhost ~]# ipvsadm -L -n</code>
<code>IP Virtual Server version </code><code>1.2</code><code>.</code><code>1</code> <code>(size=</code><code>4096</code><code>)</code>
<code>Prot LocalAddress:Port Scheduler Flags</code>
<code> </code><code>-> RemoteAddress:Port Forward Weight ActiveConn InActConn</code>
<code>TCP </code><code>192.168</code><code>.</code><code>1.230</code><code>:</code><code>80</code> <code>rr</code>
<code> </code><code>-> </code><code>192.168</code><code>.</code><code>1.100</code><code>:</code><code>80</code> <code>Route </code><code>1</code> <code>0</code> <code>0</code>
<code> </code><code>-> </code><code>192.168</code><code>.</code><code>1.201</code><code>:</code><code>80</code> <code>Route </code><code>1</code> <code>0</code> <code>0</code>
我們會看到我們為兩個伺服器單獨書寫的網頁
<a href="http://s3.51cto.com/wyfs02/M01/24/51/wKioL1NOTROT5CJlAADikoUcpEE190.jpg" target="_blank"></a>
<a href="http://s3.51cto.com/wyfs02/M01/24/68/wKioL1NOdOKT5_GiAAEGCSPhYt4941.jpg" target="_blank"></a>
提供Director服務腳本
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<code>Director腳本:</code>
<code>#!/bin/bash</code>
<code>#</code>
<code># LVS script </code><code>for</code> <code>VS/DR</code>
<code>. /etc/rc.d/init.d/functions</code>
<code>VIP=</code><code>192.168</code><code>.</code><code>0.210</code>
<code>RIP1=</code><code>192.168</code><code>.</code><code>0.221</code>
<code>RIP2=</code><code>192.168</code><code>.</code><code>0.222</code>
<code>PORT=</code><code>80</code>
<code>case</code> <code>"$1"</code> <code>in</code>
<code>start) </code>
<code> </code><code>/sbin/ifconfig eth0:</code><code>1</code> <code>$VIP broadcast $VIP netmask </code><code>255.255</code><code>.</code><code>255.255</code> <code>up</code>
<code> </code><code>/sbin/route add -host $VIP dev eth0:</code><code>1</code>
<code># Since </code><code>this</code> <code>is</code> <code>the Director we must be able to forward packets</code>
<code> </code><code>echo </code><code>1</code> <code>> /proc/sys/net/ipv4/ip_forward</code>
<code># Clear all iptables rules.</code>
<code> </code><code>/sbin/iptables -F</code>
<code># Reset iptables counters.</code>
<code> </code><code>/sbin/iptables -Z</code>
<code># Clear all ipvsadm rules/services.</code>
<code> </code><code>/sbin/ipvsadm -C</code>
<code># Add an IP virtual service </code><code>for</code> <code>VIP </code><code>192.168</code><code>.</code><code>0.219</code> <code>port </code><code>80</code>
<code># In </code><code>this</code> <code>recipe, we will </code><code>use</code> <code>the round-robin scheduling method.</code>
<code># In production, however, you should </code><code>use</code> <code>a weighted, </code><code>dynamic</code> <code>scheduling method.</code>
<code> </code><code>/sbin/ipvsadm -A -t $VIP:</code><code>80</code> <code>-s wlc</code>
<code># Now direct packets </code><code>for</code> <code>this</code> <code>VIP to</code>
<code># the real server IP (RIP) inside the cluster</code>
<code> </code><code>/sbin/ipvsadm -a -t $VIP:</code><code>80</code> <code>-r $RIP1 -g -w </code><code>1</code>
<code> </code><code>/sbin/ipvsadm -a -t $VIP:</code><code>80</code> <code>-r $RIP2 -g -w </code><code>2</code>
<code> </code><code>/bin/touch /</code><code>var</code><code>/lock/subsys/ipvsadm &> /dev/</code><code>null</code>
<code>;;</code>
<code>stop)</code>
<code># Stop forwarding packets</code>
<code> </code><code>echo </code><code>0</code> <code>> /proc/sys/net/ipv4/ip_forward</code>
<code># Reset ipvsadm</code>
<code># Bring down the VIP </code><code>interface</code>
<code> </code><code>/sbin/ifconfig eth0:</code><code>1</code> <code>down</code>
<code> </code><code>/sbin/route del $VIP</code>
<code> </code>
<code> </code><code>/bin/rm -f /</code><code>var</code><code>/lock/subsys/ipvsadm</code>
<code> </code><code>echo </code><code>"ipvs is stopped..."</code>
<code>status)</code>
<code> </code><code>if</code> <code>[ ! -e /</code><code>var</code><code>/lock/subsys/ipvsadm ]; then</code>
<code> </code><code>echo </code><code>"ipvsadm is stopped ..."</code>
<code> </code><code>else</code>
<code> </code><code>echo </code><code>"ipvs is running ..."</code>
<code> </code><code>ipvsadm -L -n</code>
<code> </code><code>fi</code>
<code>*)</code>
<code> </code><code>echo </code><code>"Usage: $0 {start|stop|status}"</code>
<code>esac</code>
提供Real Server啟動腳本
<code># Script to start LVS DR real server.</code>
<code># description: LVS DR real server</code>
<code>. /etc/rc.d/init.d/functions</code>
<code>VIP=</code><code>192.168</code><code>.</code><code>0.219</code>
<code>host=`/bin/hostname`</code>
<code>start)</code>
<code> </code><code># Start LVS-DR real server on </code><code>this</code> <code>machine.</code>
<code> </code><code>/sbin/ifconfig lo down</code>
<code> </code><code>/sbin/ifconfig lo up</code>
<code> </code><code>echo </code><code>1</code> <code>> /proc/sys/net/ipv4/conf/lo/arp_ignore</code>
<code> </code><code>echo </code><code>2</code> <code>> /proc/sys/net/ipv4/conf/lo/arp_announce</code>
<code> </code><code>echo </code><code>1</code> <code>> /proc/sys/net/ipv4/conf/all/arp_ignore</code>
<code> </code><code>echo </code><code>2</code> <code>> /proc/sys/net/ipv4/conf/all/arp_announce</code>
<code> </code><code>/sbin/ifconfig lo:</code><code>0</code> <code>$VIP broadcast $VIP netmask </code><code>255.255</code><code>.</code><code>255.255</code> <code>up</code>
<code> </code><code>/sbin/route add -host $VIP dev lo:</code><code>0</code>
<code> </code><code># Stop LVS-DR real server loopback device(s).</code>
<code> </code><code>/sbin/ifconfig lo:</code><code>0</code> <code>down</code>
<code> </code><code>echo </code><code>0</code> <code>> /proc/sys/net/ipv4/conf/lo/arp_ignore</code>
<code> </code><code>echo </code><code>0</code> <code>> /proc/sys/net/ipv4/conf/lo/arp_announce</code>
<code> </code><code>echo </code><code>0</code> <code>> /proc/sys/net/ipv4/conf/all/arp_ignore</code>
<code> </code><code>echo </code><code>0</code> <code>> /proc/sys/net/ipv4/conf/all/arp_announce</code>
<code> </code><code># Status of LVS-DR real server.</code>
<code> </code><code>islothere=`/sbin/ifconfig lo:</code><code>0</code> <code>| grep $VIP`</code>
<code> </code><code>isrothere=`netstat -rn | grep </code><code>"lo:0"</code> <code>| grep $VIP`</code>
<code> </code><code>if</code> <code>[ ! </code><code>"$islothere"</code> <code>-o ! </code><code>"isrothere"</code> <code>];then</code>
<code> </code><code># Either the route or the lo:</code><code>0</code> <code>device</code>
<code> </code><code># not found.</code>
<code> </code><code>echo </code><code>"LVS-DR real server Stopped."</code>
<code> </code><code>else</code>
<code> </code><code>echo </code><code>"LVS-DR real server Running."</code>
<code> </code><code>fi</code>
<code> </code><code># Invalid entry.</code>
<code> </code><code>echo </code><code>"$0: Usage: $0 {start|status|stop}"</code>
<code> </code><code>exit </code><code>1</code>
提供LVS-NET的腳本
<code># chkconfig: - </code><code>88</code> <code>12</code>
<code># description: LVS script </code><code>for</code> <code>VS/NAT</code>
<code>DIP=</code><code>192.168</code><code>.</code><code>10.10</code>
<code>RIP1=</code><code>192.168</code><code>.</code><code>10.11</code>
<code>RIP2=</code><code>192.168</code><code>.</code><code>10.12</code>
<code> </code><code>/sbin/ifconfig eth0:</code><code>1</code> <code>$VIP netmask </code><code>255.255</code><code>.</code><code>255.0</code> <code>up</code>
<code> </code><code>/sbin/ipvsadm -A -t $VIP:</code><code>80</code> <code>-s rr</code>
<code> </code><code>/sbin/ipvsadm -a -t $VIP:</code><code>80</code> <code>-r $RIP1 -m</code>
<code> </code><code>/sbin/ipvsadm -a -t $VIP:</code><code>80</code> <code>-r $RIP2 -m</code>
<code> </code>
<code> </code><code>/bin/touch /</code><code>var</code><code>/lock/subsys/ipvsadm.lock</code>
<code> </code><code>ifconfig eth0:</code><code>1</code> <code>down</code>
<code> </code><code>rm -rf /</code><code>var</code><code>/lock/subsys/ipvsadm.lock</code>
<code> </code><code>[ -e /</code><code>var</code><code>/lock/subsys/ipvsadm.lock ] && echo </code><code>"ipvs is running..."</code> <code>|| echo </code><code>"ipvsadm is stopped..."</code>
<code> </code><code>echo </code><code>"Usage: $0 {start|stop}"</code>
本文轉自wangfeng7399 51CTO部落格,原文連結:http://blog.51cto.com/wangfeng7399/1396717,如需轉載請自行聯系原作者