簡介:
Linux 虛擬服務器(Linux Virtual Server. LVS),是一個由章文松開發(fā)的自由軟件.利用KVS可以實現(xiàn)高可用的、可伸縮縮的Web, Mail, Cache和Medial等網(wǎng)絡股務..井在此基 礎(chǔ)上開發(fā)支持龐大用戶數(shù)的,可伸縮的,高可用的電子商務應用。LVS1998年發(fā)展到現(xiàn)在,已經(jīng)變得比較成熟,目前廣泛應用在各種網(wǎng)絡服務和電了商務應用 中.
LVS具有很好的伸縮縮性、可靠性和管埋性,通過LVS要實現(xiàn)的最終目標是:利用linux 操作系統(tǒng)和LVS集群軟件實現(xiàn)一個高可用、高性能,低成本的服務器應用集群。
LVS集群的組成
利用LVS架設的服務器群系統(tǒng)由3個部分組成:最前端的是負栽均衡層(這里用 Lo ad Balancer表示),中間是服務器集群層(用Server Array表示).
LVS體系結(jié)構(gòu)如下圖所示:
下面對LVS的各個組成部分進行詳細介紹
負 栽均衡層:位于整個集群系統(tǒng)的最前端,由一臺或多臺負栽調(diào)度器(Dircctm Server)組成.LVS核心模塊IPVS就安裝在director Server上,而director的主要作用類似于一個路由器,它含有為完成LVS功能所設定的路由表,通過這些路由表把用戶的請求分發(fā)給服務器群組層 的應用服務器(real Server)。同時,在director server上還要安裝隊real server的監(jiān)控模塊Ldirectord,此模塊用于監(jiān)測各個real server 服務的健康狀況。在real server 不可同時可以講其從LVS路由表中剔除,在恢復時重新加入。
服務器群組層:由一組實際運行應用服務的機器組成,real Server可以是Web服務器、Mail服務器、FTP服務器、DNS服務器、視頰服務器中的一個或多個,每個Real Server之間通過高速的LAN或分布在各地的WAN相連接:實際的應用中, Director Server也可以同時兼任Real Server的角色
共字存儲層是為所有Real Server提供共亨存儲空問和內(nèi)容一致性的存儲區(qū)域,一般由磁盤陣列設備組成。為了提俱內(nèi)容的一致性,一般可以通過NFS網(wǎng)絡義件系統(tǒng)共 亨數(shù)據(jù),但是NFS在繁忙的業(yè)務系統(tǒng)中,性能并不是很好,此時可以采用集群文件 系統(tǒng),例如Red Hat的GFS文件系統(tǒng),Oracle提供的OS2文件系統(tǒng)等。
從整個LVS結(jié)構(gòu)可以看出,Director Server是整個LVS的核心。目前,用干Director Server 的操作系統(tǒng)只有Linux和FreeBSD, Linux 2.6內(nèi)核完全內(nèi)置了LVS的各個模塊,不用任何 設置就可以支持LVS功能。
對丁 Real.Server,幾乎所有的系統(tǒng)平臺,如 Linux、.. Windows、Solaris、AIX、BSD 系列等都能很好地支持它
LVS集群的特點
1. IP 負載均衡與負載調(diào)度
1負栽均衡技術(shù)有很多實現(xiàn)方案,有基于DNS.域名輪流解析的方法,有基于客戶端調(diào)度訪問的方法,還有基于應用層系統(tǒng)負栽的調(diào)度方法,還有基于p地址的調(diào)度方法。在這些負栽 調(diào)度算法中,執(zhí)行效率最卨的是IP負栽均衡技術(shù)。
LVS 的IP負栽均衡技術(shù)是通過IPVS模塊來實現(xiàn)的。IPVS是LVS集群系統(tǒng)的核心軟件, 它的主要作用是:安裝在Director Server上,同時在Director Server ..上虛擬出一個IP地址, 用戶必須通過這個虛擬的IP地址訪問服務器,這個虛擬IP —般稱為LVS的VIP,即Virtual IP 訪問的請求首先經(jīng)過VIP到達負栽調(diào)度器,然后由負栽調(diào)度器從Real Server列表中選取 一個服務節(jié)點響應用戶的請求。
在用戶的清求到達負栽調(diào)度器后,調(diào)度器如何將請求發(fā)送到提供服務的Real Server節(jié) 點,而Real Server節(jié)點如何返回數(shù)據(jù)給用戶,是IPVS實現(xiàn)的重點技術(shù)。IPVS實現(xiàn)負栽均 衡的方式有4種.分別是NAT|Full NAT、TUN和DR。下面進行詳細介紹。
IPVS/NAT :即 Virtual Server via Network Address Translation,也就是網(wǎng)絡地址翻譯技術(shù)實現(xiàn)虛擬服務器。當用戶請求到達調(diào)度器時,調(diào)度器將請求報文的目標地址(即 虛擬IP地址)改寫成選定的Real Server地址,同時將報文的目標端口也改成選定的 Real Server的相應端口,最后將報文請求發(fā)送到選定的Real Server。在服務器端得到數(shù)據(jù)后,Real Server將數(shù)據(jù)返回給用戶時,需要再次經(jīng)過負栽調(diào)度器將報文的源地址和源端口改成虛擬IP地址和相應端口,然后把數(shù)據(jù)發(fā)送給用戶,完成整個負栽調(diào)度過 程。可以看出,在NAT方式下,用戶請求和響應報文都必須經(jīng)過Director Server地址重寫, 當用戶請求越來越多時,調(diào)度器的處理能力將成為瓶頸. 如下圖所示:IPVS/NAT 架構(gòu)圖
NAT:多目標的DNAT
特性:
RS應該使用私有地址;
RS的網(wǎng)關(guān)必須指向DIP;
RIP和DIP必須在同一網(wǎng)段內(nèi);
請求和響應的報文都得經(jīng)過Director;(在高負載應用場景中,Director很可能成為系統(tǒng)性能瓶頸)
支持端口映射;
RS可以使用任意支持集群服務的OS(如Windows)
適用場景:
非高并發(fā)請求場景,10個RS以內(nèi);可隱藏內(nèi)部的DIP和RIP地址;
結(jié)構(gòu)圖:
LVS/TUN :即Virtual Server via IP Tunneling,也就是通過IP隧道技術(shù)實現(xiàn)虛擬服務器。這種方式的連接調(diào)度度和管理與VS/NAT方式一樣,只是報文轉(zhuǎn)發(fā)方法不同。在 VS/TUN方式中,調(diào)度器采用IP隧道技術(shù)將用戶清求轉(zhuǎn)發(fā)到某個Real Server,而這 個Real Server 將直接響應用戶的請求,不再經(jīng)過前端調(diào)度器。此外,對Real Server 的地域位置沒有要求,可以和Director Server位于同一個網(wǎng)段,也可以在獨立的一個 網(wǎng)絡中。因此,在TUN方式中,調(diào)度器將只處理用戶的報文請求,從而使集群系統(tǒng) 的吞吐量大大提高。如下圖所示VS/TUN 架構(gòu)圖:
TUN:IP隧道,即含有多個IP報頭
特性:
RIP、DIP、VIP都得是公網(wǎng)地址;
RS的網(wǎng)關(guān)不會指向也不可能指向DIP;
請求報文經(jīng)過Director,但響應報文一定不經(jīng)過Director;
不支持端口映射;
RS的操作系統(tǒng)必須得支持隧道功能,即部署ipip模塊
適用場景:
跨互聯(lián)網(wǎng)的請求轉(zhuǎn)發(fā)
結(jié)構(gòu)圖:
FULLNAT是一種新的轉(zhuǎn)發(fā)模式
– 主要思想:引入local address(內(nèi)網(wǎng)ip地址),cip-vip轉(zhuǎn)
換為lip->rip,而 lip和rip均為IDC內(nèi)網(wǎng)ip,可以跨vlan通
訊;FULLNAT:NAT模型的改進版
特性:
實現(xiàn)RS間跨VLAN通信,是NAT模式的改進版;
默認內(nèi)核不支持,需重新編譯內(nèi)核,才能使用;
適用場景:
內(nèi)網(wǎng)服務器跨VLAN的負載分擔
結(jié)構(gòu)圖:
LVS/DR: 即Virtual Server via Direct Routing,也就是用直接路由技術(shù)實現(xiàn)虛擬服務器。 這種方式的連按調(diào)度和管理與前兩種一樣,但它的報文轉(zhuǎn)發(fā)方法又有所不同,VS/DR 通過改寫請求報文的MAC地址,將請求發(fā)送到Real Server,而Real Server將響應直接返回給客戶.免去了VS/TUN中的IP隧道開銷,這種方式是3種負莪調(diào)度方式中 性能最好的,但是要求Director Server與Real Server必須由一塊網(wǎng)卡連在同一物理網(wǎng)段上。
如下圖所示:VS/DR 架構(gòu)圖
DR:Direct Routing
需解決的關(guān)鍵問題:
讓前端路由將請求發(fā)往VIP時,只能是Director上的VIP進行響應;實現(xiàn)方式是修改RS上的Linux內(nèi)核參數(shù),將RS上的VIP配置為lo接口的別名,并限制Linux僅對對應接口的ARP請求做響應
特性:
RS可以使用私有地址,但也可以使用公網(wǎng)地址,此時可以直接通過互聯(lián)網(wǎng)連入RS以實現(xiàn)配置,監(jiān)控等;
RS的網(wǎng)關(guān)一定不能指向DIP;
RS和Director要在同一物理網(wǎng)絡(即不能由路由器分隔)
請求報文經(jīng)過Director,但響應報文一定不進過Director;
不支持端口映射;
RS可以使用大多數(shù)的操作系統(tǒng)
適用場景:
因為響應報文不經(jīng)過Director,極大的減輕了Director的負載壓力,故Director可以支持更大的并發(fā)訪問,一般RS在100臺以內(nèi);
結(jié)構(gòu)圖:
LVS-DR配置架構(gòu)根據(jù)其VIP與RIP是否在同一個網(wǎng)段內(nèi)又分為兩種模型:
LVS調(diào)度算法
(2)負我調(diào)度算法
靜態(tài)方法:僅根據(jù)算法本身進行調(diào)度
rr:Round Robin # 即輪詢wrr:Weighted RR # 即加權(quán)輪詢sh:Source Hashing # 即來源IP地址hashdh:Destination Hashing # 即目標地址hash(不常用,僅用于前端多防火墻的場景,保證防火墻的連接追蹤功能有效)
動態(tài)方法:根據(jù)算法及RS當前的負載情況
lc:Least Connection# 評判標準:Overhead=Active*256+Inactive# Overhead最小者勝出wlc:Weighted LC# 評判標準:Overhead=(Active*256+Inactive)/weight# Overhead最小者勝出sed:Shortest Expect Delay# 評判標準:Overhead=(Active+1)*256/weight# Overhead最小者勝出nq:Never Queue # 集群開始時工作時,每臺服務器都至少分配一個連接請求,然后再根據(jù)sed算法調(diào)度;lblc:Locality-based Least Connection # 類似于dh+lclblcr:Relicated and Locality-based Least Connection # 主要用于后端服務器是緩存服務器時
前 面介紹過,負載調(diào)度器是根據(jù)各個服務器的負栽情況,動態(tài)地選擇一臺Real Server響 應用戶請求。那么動態(tài)選擇是如何實現(xiàn)呢?其實就是通過這里要說的負栽調(diào)度算法。根據(jù)不同的網(wǎng)絡眼務需求和眼務器配IPVS實現(xiàn)T8種負栽調(diào)度算法。這里詳 細講述最常用的4 種調(diào)度算法。
1、 輪詢(round robin, rr),加權(quán)輪詢(Weighted round robin, wrr)——新的連接請求被輪流分配至各RealServer;算法的優(yōu)點是其簡潔性,它無需記錄當前所有連接的狀態(tài),所以它是一種無狀態(tài)調(diào)度。輪叫調(diào)度 算法假設所有服務器處理性能均相同,不管服務器的當前連接數(shù)和響應速度。該算法相對簡單,不適用于服務器組中處理性能不一的情況,而且當請求服務時間變化 比較大時,輪叫調(diào)度算法容易導致服務器間的負載不平衡。
2、 最少連接(least connected, lc), 加權(quán)最少連接(weighted least connection, wlc)——新的連接請求將被分配至當前連接數(shù)最少的RealServer;最小連接調(diào)度是一種動態(tài)調(diào)度算法,它通過服務器當前所活躍的連接數(shù)來估計服務 器的負載情況。調(diào)度器需要記錄各個服務器已建立連接的數(shù)目,當一個請求被調(diào)度到某臺服務器,其連接數(shù)加1;當連接中止或超時,其連接數(shù)減一。
3、 基于局部性的最少鏈接調(diào)度(Locality-Based Least Connections Scheduling,lblc)——針對請求報文的目標IP地址的負載均衡調(diào)度,目前主要用于Cache集群系統(tǒng),因為在Cache集群中客戶請求報文 的目標IP地址是變化的。這里假設任何后端服務器都可以處理任一請求,算法的設計目標是在服務器的負載基本平衡情況下,將相同目標IP地址的請求調(diào)度到同 一臺服務器,來提高各臺服務器的訪問局部性和主存Cache命中率,從而整個集群系統(tǒng)的處理能力。LBLC調(diào)度算法先根據(jù)請求的目標IP地址找出該目標 IP地址最近使用的服務器,若該服務器是可用的且沒有超載,將請求發(fā)送到該服務器;若服務器不存在,或者該服務器超載且有服務器處于其一半的工作負載,則 用“最少鏈接”的原則選出一個可用的服務器,將請求發(fā)送到該服務器。
4、 帶復制的基于局部性最少鏈接調(diào)度(Locality-Based Least Connections with Replication Scheduling,lblcr)——也是針對目標IP地址的負載均衡,目前主要用于Cache集群系統(tǒng)。它與LBLC算法的不同之處是它要維護從一個 目標IP地址到一組服務器的映射,而 LBLC算法維護從一個目標IP地址到一臺服務器的映射。對于一個“熱門”站點的服務請求,一臺Cache 服務器可能會忙不過來處理這些請求。這時,LBLC調(diào)度算法會從所有的Cache服務器中按“最小連接”原則選出一臺Cache服務器,映射該“熱門”站 點到這臺Cache服務器,很快這臺Cache服務器也會超載,就會重復上述過程選出新的Cache服務器。這樣,可能會導致該“熱門”站點的映像會出現(xiàn) 在所有的Cache服務器上,降低了Cache服務器的使用效率。LBLCR調(diào)度算法將“熱門”站點映射到一組Cache服務器(服務器集合),當該“熱 門”站點的請求負載增加時,會增加集合里的Cache服務器,來處理不斷增長的負載;當該“熱門”站點的請求負載降低時,會減少集合里的Cache服務器 數(shù)目。這樣,該“熱門”站點的映像不太可能出現(xiàn)在所有的Cache服務器上,從而提供Cache集群系統(tǒng)的使用效率。LBLCR算法先根據(jù)請求的目標IP 地址找出該目標IP地址對應的服務器組;按“最小連接”原則從該服務器組中選出一臺服務器,若服務器沒有超載,將請求發(fā)送到該服務器;若服務器超載;則按 “最小連接”原則從整個集群中選出一臺服務器,將該服務器加入到服務器組中,將請求發(fā)送到該服務器。同時,當該服務器組有一段時間沒有被修改,將最忙的服 務器從服務器組中刪除,以降低復制的程度。
5、 目標地址散列調(diào)度(Destination Hashing,dh)算法也是針對目標IP地址的負載均衡,但它是一種靜態(tài)映射算法,通過一個散列(Hash)函數(shù)將一個目標IP地址映射到一臺服務 器。目標地址散列調(diào)度算法先根據(jù)請求的目標IP地址,作為散列鍵(Hash Key)從靜態(tài)分配的散列表找出對應的服務器,若該服務器是可用的且未超載,將請求發(fā)送到該服務器,否則返回空。
6、 源地址散列調(diào)度(Source Hashing,sh)算法正好與目標地址散列調(diào)度算法相反,它根據(jù)請求的源IP地址,作為散列鍵(Hash Key)從靜態(tài)分配的散列表找出對應的服務器,若該服務器是可用的且未超載,將請求發(fā)送到該服務器,否則返回空。它采用的散列函數(shù)與目標地址散列調(diào)度算法 的相同。除了將請求的目標IP地址換成請求的源IP地址外,它的算法流程與目標地址散列調(diào)度算法的基本相似。在實際應用中,源地址散列調(diào)度和目標地址散列 調(diào)度可以結(jié)合使用在防火墻集群中,它們可以保證整個系統(tǒng)的唯一出入口。
7、加權(quán)最少連接調(diào)度(Weighted Least Connections)。
“加 權(quán)最少連接調(diào)度”是“最少連接調(diào)度”的超集。每個服務節(jié)點可以用相應的權(quán)值表示其處理能力,而系統(tǒng)管理員可以動態(tài)地設置相應的權(quán)值,默認權(quán)值為1。加權(quán)最 小連接調(diào) 度在分新連接請求時盡可能使服務節(jié)點的已建立連接數(shù)和其權(quán)值成正比。算法: overhead=active*256+inactive/weight overhead最小值勝出;
8、sed:shorttest expect delay 最小期望延遲(改進的wlc) 算法:overhead=(active+1)*256/weight,案例:假如DFG三臺機器分別權(quán)重123,連接數(shù)也分別是123.那么如果使用WLC算法的話一個新請求進入時它可能會分給DFG中的任意一個。使用sed算法后會進行這樣一個運算:
D(1+1)/1
F(1+2)/2
G(1+3)/3
9、nq:nerver queue 增強改進的sed算法.如果有臺real Server的連接數(shù)=0直接分配,不需要再進行sed運算
2.高可用性
LVS 是一個基于內(nèi)核級別的應用軟件,因此具有很髙的處理性能。由LVS構(gòu)建的負載 均衡集群系統(tǒng)具有優(yōu)秀的處理能力,每個服務節(jié)點的故障不會影響整個系統(tǒng)的正常使用,又能夠?qū)崿F(xiàn)負載的合理均衡,使應用具有超高負荷的服務能力,可支持上百 萬個并發(fā)連接請 求。如配置百兆網(wǎng)卡,采用VS/TUN或VS/DR調(diào)度技術(shù),整個集群系統(tǒng)的吞吐量可高達 1 Gbit/s;又如配置千兆網(wǎng)卡,系統(tǒng)的最大吞吐量可接近10Gbit/s。
3.高可靠性
LVS負載均衡集群軟件已經(jīng)在 企業(yè)和學校中得到了很好的普及,國內(nèi)外很多大型的、關(guān)鍵性的Web站點也都采用了 LVS集群軟件,所以它的可靠性在實踐中得到了很好印證。有 很多由LVS構(gòu)成的負載均衡系統(tǒng),運行很長時間,從未進行過重新啟動。這些都說明了 LVS 的髙穩(wěn)定性和高可靠性。
4、配置LVS
1、定義在Director上進行dispatching的服務(service),以及哪此服務器(server)用來提供此服務;
2、為每臺同時提供某一種服務的服務器定義其權(quán)重(即概據(jù)服務器性能確定的其承擔負載的能力);
注:權(quán)重用整數(shù)來表示,有時候也可以將其設置為atomic_t;其有效表示值范圍為24bit整數(shù)空間,即(2^24-1);
因此,ipvsadm命令的主要作用表現(xiàn)在以下方面:
1、添加服務(通過設定其權(quán)重>0);
2、關(guān)閉服務(通過設定其權(quán)重>0);此應用場景中,已經(jīng)連接的用戶將可以繼續(xù)使用此服務,直到其退出或超時;新的連接請求將被拒絕;
3、保存ipvs設置,通過使用“ipvsadm-sav > ipvsadm.sav”命令實現(xiàn);
4、恢復ipvs設置,通過使用“ipvsadm-sav < ipvsadm.sav”命令實現(xiàn);
5、顯示ip_vs的版本號,下面的命令顯示ipvs的hash表的大小為4k;
# ipvsadm
IP Virtual Server version 1.2.1 (size=4096)
6、顯示ipvsadm的版本號
# ipvsadm --version
ipvsadm v1.24 2003/06/07 (compiled with popt and IPVS v1.2.0)
二、ipvsadm使用中應注意的問題
默 認情況下,ipvsadm在輸出主機信息時使用其主機名而非IP地址,因此,Director需要使用名稱解析服務。如果沒有設置名稱解析服務、服務不可 用或設置錯誤,ipvsadm將會一直等到名稱解析超時后才返回。當然,ipvsadm需要解析的名稱僅限于RealServer,考慮到DNS提供名稱 解析服務效率不高的情況,建議將所有RealServer的名稱解析通過/etc/hosts文件來實現(xiàn);
三、調(diào)度算法
Director在接收到來自于Client的請求時,會基于"schedule"從RealServer中選擇一個響應給Client。ipvs支持以下調(diào)度算法:
四、關(guān)于LVS追蹤標記fwmark:
如果LVS放置于多防火墻的網(wǎng)絡中,并且每個防火墻都用到了狀態(tài)追蹤的機制,那么在回應一個針對于LVS的連接請求時必須經(jīng)過此請求連接進來時的防火墻,否則,這個響應的數(shù)據(jù)包將會被丟棄。
常用命令:
查看LVS上當前的所有連接
# ipvsadm -Lcn
或者
#cat /proc/net/ip_vs_conn
查看虛擬服務和RealServer上當前的連接數(shù)、數(shù)據(jù)包數(shù)和字節(jié)數(shù)的統(tǒng)計值,則可以使用下面的命令實現(xiàn):
# ipvsadm -l --stats
查看包傳遞速率的近似精確值,可以使用下面的命令:
# ipvsadm -l --rate
VS/NAT
LVS- NAT基于cisco的LocalDirector。VS/NAT不需要在RealServer上做任何設置,其只要能提供一個tcp/ip的協(xié)議棧即 可,甚至其無論基于什么OS。基于VS/NAT,所有的入站數(shù)據(jù)包均由Director進行目標地址轉(zhuǎn)換后轉(zhuǎn)發(fā)至內(nèi)部的 RealServer,RealServer響應的數(shù)據(jù)包再由Director轉(zhuǎn)換源地址后發(fā)回客戶端。
VS/NAT模式不能與netfilter兼容,因此,不能將VS/NAT模式的Director運行在netfilter的保護范圍之中?,F(xiàn)在已經(jīng)有補丁可以解決此問題,但尚未被整合進ip_vs code。
__________ | | | client | |____________| CIP=192.168.0.253 (eth0) | | VIP=192.168.0.220 (eth0) ____________ | | | director | |____________| DIP=192.168.10.10 (eth1) | (switch)------------------------ | | RIP=192.168.10.2 (eth0) RIP=192.168.10.3 (eth0) _____________ _____________ | | | | | realserver1 | | realserver2 | |_____________| |_____________|
設置VS/NAT模式的LVS(這里以web服務為例)
Director:
建立服務# ipvsadm -A -t VIP:PORT -s rr如:# ipvsadm -A -t 192.168.0.220:80 -s rr設置轉(zhuǎn)發(fā):# ipvsadm -a -t VIP:PORT -r RIP_N:PORT -m -w N如:# ipvsadm -a -t 192.168.0.220:80 -r 192.168.10.2 -m -w 1# ipvsadm -a -t 192.168.0.220:80 -r 192.168.10.3 -m -w 1打開路由轉(zhuǎn)發(fā)功能# echo "1" > /proc/sys/net/ipv4/ip_forward服務控制腳本:#!/bin/bash## chkconfig: - 88 12# description: LVS script for VS/NAT#. /etc/rc.d/init.d/functions#VIP=192.168.0.219DIP=192.168.10.10RIP1=192.168.10.11RIP2=192.168.10.12#case "$1" instart) /sbin/ifconfig eth0:1 $VIP netmask 255.255.255.0 up# Since this is the Director we must be able to forward packets echo 1 > /proc/sys/net/ipv4/ip_forward# Clear all iptables rules. /sbin/iptables -F# Reset iptables counters. /sbin/iptables -Z# Clear all ipvsadm rules/services. /sbin/ipvsadm -C# Add an IP virtual service for VIP 192.168.0.219 port 80# In this recipe, we will use the round-robin scheduling method.# In production, however, you should use a weighted, dynamic scheduling method. /sbin/ipvsadm -A -t $VIP:80 -s rr# Now direct packets for this VIP to# the real server IP (RIP) inside the cluster /sbin/ipvsadm -a -t $VIP:80 -r $RIP1 -m /sbin/ipvsadm -a -t $VIP:80 -r $RIP2 -m /bin/touch /var/lock/subsys/ipvsadm.lock;;stop)# Stop forwarding packets echo 0 > /proc/sys/net/ipv4/ip_forward# Reset ipvsadm /sbin/ipvsadm -C# Bring down the VIP interface ifconfig eth0:1 down rm -rf /var/lock/subsys/ipvsadm.lock;;status) [ -e /var/lock/subsys/ipvsadm.lock ] && echo "ipvs is running..." || echo "ipvsadm is stopped...";;*) echo "Usage: $0 {start|stop}";;esac
Real Server:
route add default gw 192.168.10.10 注釋:在real server 上網(wǎng)關(guān)一定要指向director服務器的DIP,不然用戶請求的數(shù)據(jù)報文,在LVS/NAT模型中將無法發(fā)送出去.
#!/bin/bashVIP=192.168.0.219chmod 755 /etc/rc.d/init.d/functions/etc/rc.d/init.d/functionscase "$1" instart)echo " start LVS of REALServer"/sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up/sbin/route add -host $VIP dev lo:0echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignoreecho "2" >/proc/sys/net/ipv4/conf/lo/arp_announceecho "1" >/proc/sys/net/ipv4/conf/all/arp_ignoreecho "2" >/proc/sys/net/ipv4/conf/all/arp_announcesysctl -p >/dev/null 2>&1;;stop)/sbin/ifconfig lo:0 downecho "close LVS Directorserver"echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignoreecho "0" >/proc/sys/net/ipv4/conf/lo/arp_announceecho "0" >/proc/sys/net/ipv4/conf/all/arp_ignoreecho "0" >/proc/sys/net/ipv4/conf/all/arp_announce;;*)echo "Usage: $0 {start|stop}"exit 1esac
ARP問題:
__________ | | | client | |________| | | (router) | | | __________ | DIP | | |------| director | | VIP |__________| | | | ------------------------------------ | | | | | | RIP1, VIP RIP2, VIP RIP3, VIP______________ ______________ ______________| | | | | || realserver1 | | realserver2 | | realserver3 ||______________| |______________| |______________|
在如上圖的VS/DR或VS/TUN 應用的一種模型中(所有機器都在同一個物理網(wǎng)絡),所有機器(包括Director和RealServer)都使用了一個額外的IP地址,即VIP。當一 個客戶端向VIP發(fā)出一個連接請求時,此請求必須要連接至Director的VIP,而不能是RealServer的。因為,LVS的主要目標就是要 Director負責調(diào)度這些連接請求至RealServer的。
因此,在Client發(fā)出至VIP的連接請求后,只能由Director將其 MAC地址響應給客戶端(也可能是直接與Director連接的路由設備),而Director則會相應的更新其ipvsadm table以追蹤此連接,而后將其轉(zhuǎn)發(fā)至后端的RealServer之一。
如果Client在請求建立至VIP的連接時由某RealServer 響應了其請求,則Client會在其MAC table中建立起一個VIP至RealServer的對就關(guān)系,并以至進行后面的通信。此時,在Client看來只有一個RealServer而無法意 識到其它服務器的存在。
為了解決此問題,可以通過在路由器上設置其轉(zhuǎn)發(fā)規(guī)則來實現(xiàn)。當然,如果沒有權(quán)限訪問路由器并做出相應的設置,則只能通過傳統(tǒng)的本地方式來解決此問題了。這些方法包括:
1、禁止RealServer響應對VIP的ARP請求;
2、在RealServer上隱藏VIP,以使得它們無法獲知網(wǎng)絡上的ARP請求;
3、基于“透明代理(Transparent Proxy)”或者“fwmark (firewall mark)”;
4、禁止ARP請求發(fā)往RealServers;
傳 統(tǒng)認為,解決ARP問題可以基于網(wǎng)絡接口,也可以基于主機來實現(xiàn)。Linux采用了基于主機的方式,因為其可以在大多場景中工作良好,但LVS卻并不屬于 這些場景之一,因此,過去實現(xiàn)此功能相當麻煩。現(xiàn)在可以通過設置arp_ignore和arp_announce,這變得相對簡單的多了。
Linux 2.2和2.4(2.4.26之前的版本)的內(nèi)核解決“ARP問題”的方法各不相同,且比較麻煩。幸運的是,2.4.26和2.6的內(nèi)核中引入了兩個新的 調(diào)整ARP棧的標志(device flags):arp_announce和arp_ignore。基于此,在DR/TUN的環(huán)境中,所有IPVS相關(guān)的設定均可使用 arp_announce=2和arp_ignore=1/2/3來解決“ARP問題”了。
arp_annouce:Define different restriction levels for announcing the local source IP address from IP packets in ARP requests sent on interface;
0 - (default) Use any local address, configured on any interface.
1 - Try to avoid local addresses that are not in the target's subnet for this interface.
2 - Always use the best local address for this target.
arp_ignore: Define different modes for sending replies in response to received ARP requests that resolve local target IP address.
0 - (default): reply for any local target IP address, configured on any interface.
1 - reply only if the target IP address is local address configured on the incoming interface.
2 - reply only if the target IP address is local address configured on the incoming interface and both with the sender's IP address are part from same subnet on this interface.
3 - do not reply for local address configured with scope host, only resolutions for golbal and link addresses are replied.
4-7 - reserved
8 - do not reply for all local addresses
在RealServers上,VIP配置在本地回環(huán)接口lo上。如果回應給Client的數(shù)據(jù)包路由到了eth0接口上,則arp通告或請應該通過eth0實現(xiàn),因此,需要在sysctl.conf文件中定義如下配置:
#vim /etc/sysctl.confnet.ipv4.conf.eth0.arp_ignore = 1net.ipv4.conf.eth0.arp_announce = 2net.ipv4.conf.all.arp_ignore = 1net.ipv4.conf.all.arp_announce = 2
以上選項需要在啟用VIP之前進行,否則,則需要在Drector上清空arp表才能正常使用LVS。
到 達Director的數(shù)據(jù)包首先會經(jīng)過PREROUTING,而后經(jīng)過路由發(fā)現(xiàn)其目標地址為本地某接口的地址,因此,接著就會將數(shù)據(jù)包發(fā)往 INPUT(LOCAL_IN HOOK)。此時,正在運行內(nèi)核中的ipvs(始終監(jiān)控著LOCAL_IN HOOK)進程會發(fā)現(xiàn)此數(shù)據(jù)包請求的是一個集群服務,因為其目標地址是VIP。于是,此數(shù)據(jù)包的本來到達本機(Director)目標行程被改變?yōu)榻?jīng)由 POSTROUTING HOOK發(fā)往RealServer。這種改變數(shù)據(jù)包正常行程的過程是根據(jù)IPVS表(由管理員通過ipvsadm定義)來實現(xiàn)的。
如果有 多臺Realserver,在某些應用場景中,Director還需要基于“連接追蹤”實現(xiàn)將由同一個客戶機的請求始終發(fā)往其第一次被分配至的 Realserver,以保證其請求的完整性等。其連接追蹤的功能由Hash table實現(xiàn)。Hash table的大小等屬性可通過下面的命令查看:
# ipvsadm -lcn
為了保證其時效性,Hash table中“連接追蹤”信息被定義了“生存時間”。LVS為記錄“連接超時”定義了三個計時器:
1、空閑TCP會話;
2、客戶端正常斷開連接后的TCP會話;
3、無連接的UDP數(shù)據(jù)包(記錄其兩次發(fā)送數(shù)據(jù)包的時間間隔);
上面三個計時器的默認值可以由類似下面的命令修改,其后面的值依次對應于上述的三個計時器:
# ipvsadm --set 28800 30 600
數(shù)據(jù)包在由Direcotr發(fā)往 Realserver時,只有目標MAC地址發(fā)生了改變(變成了Realserver的MAC地址)。Realserver在接收到數(shù)據(jù)包后會根據(jù)本地路 由表將數(shù)據(jù)包路由至本地回環(huán)設備,接著,監(jiān)聽于本地回環(huán)設備VIP上的服務則對進來的數(shù)據(jù)庫進行相應的處理,而后將處理結(jié)果回應至RIP,但數(shù)據(jù)包的原地 址依然是VIP。
ipvs的持久連接:
無論基于什么樣的算法,只要期望源于同一個客戶端的請求都由同一臺Realserver響應時,就需要用到持久連接。比如,某一用戶連續(xù)打開了三個telnet連接請求時,根據(jù)RR算法,其請求很可能會被分配至不同的Realserver,這通常不符合使用要求。
2、IPVS/DR
Director:
IP分配
VIP=192.168.0.210
RIP1=192.168.0.221
RIP2=192.168.0.222
1、下載安裝ipvsadm
wget http://www.linuxvirtualserver.org/software/kernel-2.6/ipvsadm-1.26.tar.gztar zxvf ipvsadm-1.26.tar.gzcd ipvsadm-1.26make && make install
2、編寫并運行腳本(LVS服務器的腳本)
vim director.sh #!/bin/bash## LVS script for VS/DR#. /etc/rc.d/init.d/functions#VIP=192.168.0.210RIP1=192.168.0.221RIP2=192.168.0.222PORT=80#case "$1" instart) /sbin/ifconfig eth0:1 $VIP broadcast $VIP netmask 255.255.255.255 up /sbin/route add -host $VIP dev eth0:1# Since this is the Director we must be able to forward packets echo 1 > /proc/sys/net/ipv4/ip_forward# Clear all iptables rules. /sbin/iptables -F# Reset iptables counters. /sbin/iptables -Z# Clear all ipvsadm rules/services. /sbin/ipvsadm -C# Add an IP virtual service for VIP 192.168.0.219 port 80# In this recipe, we will use the round-robin scheduling method.# In production, however, you should use a weighted, dynamic scheduling method. /sbin/ipvsadm -A -t $VIP:80 -s wlc# Now direct packets for this VIP to# the real server IP (RIP) inside the cluster /sbin/ipvsadm -a -t $VIP:80 -r $RIP1 -g -w 1 /sbin/ipvsadm -a -t $VIP:80 -r $RIP2 -g -w 2 /bin/touch /var/lock/subsys/ipvsadm &> /dev/null;;stop)# Stop forwarding packets echo 0 > /proc/sys/net/ipv4/ip_forward# Reset ipvsadm /sbin/ipvsadm -C# Bring down the VIP interface /sbin/ifconfig eth0:1 down /sbin/route del $VIP /bin/rm -f /var/lock/subsys/ipvsadm echo "ipvs is stopped...";;status) if [ ! -e /var/lock/subsys/ipvsadm ]; then echo "ipvsadm is stopped ..." else echo "ipvs is running ..." ipvsadm -L -n fi;;*) echo "Usage: $0 {start|stop|status}";;esac
3、給腳本加權(quán)限,并執(zhí)行
chmod 755 /etc/rc.d/init.d/functionschmod +x director.sh./director.sh start
4、配置后端的WEB服務器腳本
vim realserver.sh#!/bin/bash## Script to start LVS DR real server.# description: LVS DR real server#. /etc/rc.d/init.d/functionsVIP=192.168.0.219host=`/bin/hostname`case "$1" instart) # 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
5、給腳本加權(quán)限,并執(zhí)行
chmod 755 /etc/rc.d/init.d/functionschmod +x realserver.sh./realserver.sh start
IPvsadm 的用法和格式如下:
ipvsadm -A|E -t|u|f virutal-service-address:port [-s scheduler] [-p [timeout]] [-M netmask]ipvsadm -D -t|u|f virtual-service-addressipvsadm -Cipvsadm -Ripvsadm -S [-n]ipvsadm -a|e -t|u|f service-address:port -r real-server-address:port [-g|i|m] [-w weight]ipvsadm -d -t|u|f service-address -r server-addressipvsadm -L|l [options]ipvsadm -Z [-t|u|f service-address]ipvsadm --set tcp tcpfin udpipvsadm --start-daemon state [--mcast-interface interface]ipvsadm --stop-daemonipvsadm -h命令選項解釋:有兩種命令選項格式,長的和短的,具有相同的意思。在實際使用時,兩種都可以。-A --add-service 在內(nèi)核的虛擬服務器表中添加一條新的虛擬服務器記錄。也就是增加一臺新的虛擬服務器。-E --edit-service 編輯內(nèi)核虛擬服務器表中的一條虛擬服務器記錄。 修改定義過的集群服務-D --delete-service 刪除內(nèi)核虛擬服務器表中的一條虛擬服務器記錄。-C --clear 清除內(nèi)核虛擬服務器表中的所有記錄。-R --restore 恢復虛擬服務器規(guī)則-S --save 保存虛擬服務器規(guī)則,輸出為-R 選項可讀的格式-a --add-server 在內(nèi)核虛擬服務器表的一條記錄里添加一條新的真實服務器記錄。也就是在一個虛擬服務器中增加一臺新的真實服務器-e --edit-server 編輯一條虛擬服務器記錄中的某條真實服務器記錄-d --delete-server 刪除一條虛擬服務器記錄中的某條真實服務器記錄-L|-l --list 顯示內(nèi)核虛擬服務器表 userver 列表;-Z --zero 虛擬服務表計數(shù)器清零(清空當前的連接數(shù)量等)--set tcp tcpfin udp 設置連接超時值--start-daemon 啟動同步守護進程。他后面可以是master 或backup,用來說明LVS Router 是master 或是backup。在這個功能上也可以采用keepalived 的VRRP 功能。--stop-daemon 停止同步守護進程-h --help 顯示幫助信息其他的選項:-t --tcp-service service-address 說明虛擬服務器提供的是tcp 的服務[vip:port] or [real-server-ip:port]-u --udp-service service-address 說明虛擬服務器提供的是udp 的服務[vip:port] or [real-server-ip:port]-f --fwmark-service fwmark 說明是經(jīng)過iptables 標記過的服務類型。通常用于將兩個或兩個以上的服務綁定為一個服務進行處理時使用;-s --scheduler scheduler 使用的調(diào)度算法,有這樣幾個選項 rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq,默認的調(diào)度算法是:wlc.-p --persistent [timeout] 持久穩(wěn)固的服務。這個選項的意思是來自同一個客戶的多次請求,將被同一臺真實的服務器處理。timeout 的默認值為300 秒。 持久連接;-M --netmask netmask persistent granularity mask-r --real-server server-address 真實的服務器[Real-Server:port]-g --gatewaying 指定LVS 的工作模式為直接路由模式(也是LVS 默認的模式) DR模型-i --ipip 指定LVS 的工作模式為隧道模式-m --masquerading 指定LVS 的工作模式為NAT 模式-w --weight weight 真實服務器的權(quán)值--mcast-interface interface 指定組播的同步接口-c --connection 顯示LVS 目前的連接 如:ipvsadm -L -c--timeout 顯示tcp tcpfin udp 的timeout 值 如:ipvsadm -L --timeout--daemon 顯示同步守護進程狀態(tài)--stats 顯示統(tǒng)計信息 ipvsadm –Ln --state 總共的數(shù)量--rate 顯示速率信息 ipvsadm –Ln --rete 平均值--sort 對虛擬服務器和真實服務器排序輸出--numeric -n 輸出IP 地址和端口的數(shù)字形式
集群相關(guān)的命令參數(shù):
-A --add-service 在內(nèi)核的虛擬服務器表中添加一條新的虛擬服務器記錄。也就是增加一臺新的虛擬服務器。-t --tcp-service service-address 說明虛擬服務器提供的是tcp 的服務[vip:port] or [real-server-ip:port]-u --udp-service service-address 說明虛擬服務器提供的是udp 的服務[vip:port] or [real-server-ip:port]-s --scheduler scheduler 使用的調(diào)度算法,有這樣幾個選項 rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq,默認的調(diào)度算法是:wlc.-p --persistent [timeout] 持久穩(wěn)固的服務。這個選項的意思是來自同一個客戶的多次請求,將被同一臺真實的服務器處理。timeout 的默認值為300 秒。 持久連接;-E --edit-service 編輯內(nèi)核虛擬服務器表中的一條虛擬服務器記錄。 修改定義過的集群服務-D :刪除指定集群服務
RS相關(guān)的命令參數(shù):
-a --add-server 在內(nèi)核虛擬服務器表的一條記錄里添加一條新的真實服務器記錄。也就是在一個虛擬服務器中增加一臺新的真實服務器 向指定的CS中添加RS-r --real-server server-address 真實的服務器[Real-Server:port],只有支持端口映射的LVS類型才允許此處使用跟集群服務中不同的端口LVS 類型:-g : gateway,DR # 指定集群類型為LVS/DR-i ipip,TUN # 指定集群類型為LVS/TUN-m:masquerade,NAT # 指定集群類型為 NAT-w:指定RS權(quán)重:-e:修改指定的RS屬性-d :從指定的集群服務中刪除某RS
LVS的持久連接:
lvs持久連接適用于大部分調(diào)度算法。當某一種請求需要定向到一個real server 時,就要用到持久連接
Directory-------RealServer1(192.168.1.11) | |____RealServer2(192.168.1.12)VIP=192.168.1.10
Directory上的配置:
#ifconfig eth0 192.168.1.9/24#ifconfig eth0:0 192.168.1.10 broadcast 192.168.1.10 netmask 255.255.255.255 up#route add -host 192.168.1.10 dev eth0:0#echo 1 >/proc/sys/net/ipv4/ip_forward#ipvsadm -A -t 192.168.1.10:0 -s rr -p 600#ipvsadm -a -t 192.168.1.10:0 -r 192.168.1.11:0 -g#ipvsadm -a -t 192.168.1.10:0 -r 192.168.1.12:0 -g
RealServer1上的配置:
#ifconfig eth0 192.168.1.11/24#ifconfig lo:0 192.168.1.10 broadcast 192.168.1.10 netmask 255.255.255.255 up#route add -host 192.168.1.10 dev lo:0#echo 1 >/proc/sys/net/ipv4/conf/lo/arp_ignore#echo 1 >/proc/sys/net/ipv4/conf/all/arp_ignore#echo 2 >/proc/sys/net/ipv4/conf/lo/arp_announce#echo 2 >/proc/sys/net/ipv4/conf/all/arp_announce#yum install httpd#echo "rs1" > /var/www/html/index.html#service httpd start
RealServer2上的配置:
#ifconfig eth0 192.168.1.12/24#ifconfig lo:0 192.168.1.10 broadcast 192.168.1.10 netmask 255.255.255.255 up#route add -host 192.168.1.10 dev lo:0#echo 1 >/proc/sys/net/ipv4/conf/lo/arp_ignore#echo 1 >/proc/sys/net/ipv4/conf/all/arp_ignore#echo 2 >/proc/sys/net/ipv4/conf/lo/arp_announce#echo 2 >/proc/sys/net/ipv4/conf/all/arp_announce#yum install httpd#echo "rs2" > /var/www/html/index.html#service httpd start
#ipvsadm -C?。蹇読pvs表#iptables -t mangle -A PREROUTING -d 192.168.1.10 -p tcp --dport 80 -j MARK --set-mark 10 把目的地為1982.168.1.10:80標記為10#ipvsadm -A -f 10 -s rr -p 60 //使用上面標記的10定義集群服務#ipvsadm -a -f 10 -r 192.168.1.11 -g //為集群定義RealServer#ipvsadm -a -f 10 -r 192.168.1.12 -g
#yum install mod_ssl#cd /etc/pki/tls/certs#make httpd.pem //在設置的時候,Common Name設置和Directory的主機名一樣就行了#mkdir /etc/httpd/ssl#cp httpd.pem /etc/httpd/ssl#vim /etc/httpd/conf.d/ssl.conf SSLCertificateFile /etc/httpd/ssl/httpd.pem SSLCertificateKeyFile /etc/httpd/ssl/httpd.pem ServerName node1.a.org:443 //我的Directory的主機名是node1.a.org#service httpd restart
#iptables -t mangle -A PREROUTING -d 192.168.1.10 -p tcp --dport 443 -j MARK --set-mark 10 //這里的標記和http的80端口的標記是一樣的,這個時候在訪問的時候,就會建立姻親關(guān)系,其他的配置和C的配置一樣,不多演示了
測試:在瀏覽器中輸入http://192.168.1.80和https://192.168.1.80發(fā)現(xiàn)訪問的是同一個頁面,就證明成功啦!
因為LVS自身本沒有多后端real server 做健康狀態(tài)檢測的功能所以:
編寫健康狀態(tài)監(jiān)測腳本:
LVS負載均衡器本身是沒有對后端服務器做健康狀態(tài)監(jiān)測的功能的;所以我們可以編寫一個小小的腳本來完成這個功能; 注釋:這些腳本的列子很粗糙,只是讓你們了解整個過程是怎樣的;
健康狀態(tài)監(jiān)測腳本實例:
RS健康狀態(tài)檢查腳本示例第一版: #!/bin/bash # VIP=192.168.10.3 CPORT=80 FAIL_BACK=127.0.0.1 FBSTATUS=0 RS=("192.168.10.7" "192.168.10.8") RSTATUS=("1" "1") RW=("2" "1") RPORT=80 TYPE=g add() { ipvsadm -a -t $VIP:$CPORT -r $1:$RPORT -$TYPE -w $2 [ $? -eq 0 ] && return 0 || return 1 } del() { ipvsadm -d -t $VIP:$CPORT -r $1:$RPORT [ $? -eq 0 ] && return 0 || return 1 } while :; do let COUNT=0 for I in ${RS[*]}; do if curl --connect-timeout 1 http://$I &> /dev/null; then if [ ${RSTATUS[$COUNT]} -eq 0 ]; then add $I ${RW[$COUNT]} [ $? -eq 0 ] && RSTATUS[$COUNT]=1 fi else if [ ${RSTATUS[$COUNT]} -eq 1 ]; then del $I [ $? -eq 0 ] && RSTATUS[$COUNT]=0 fi fi let COUNT++ done sleep 5 done RS健康狀態(tài)檢查腳本示例第二版: #!/bin/bash # VIP=192.168.10.3 CPORT=80 FAIL_BACK=127.0.0.1 RS=("192.168.10.7" "192.168.10.8") declare -a RSSTATUS RW=("2" "1") RPORT=80 TYPE=g CHKLOOP=3 LOG=/var/log/ipvsmonitor.log addrs() { ipvsadm -a -t $VIP:$CPORT -r $1:$RPORT -$TYPE -w $2 [ $? -eq 0 ] && return 0 || return 1 } delrs() { ipvsadm -d -t $VIP:$CPORT -r $1:$RPORT [ $? -eq 0 ] && return 0 || return 1 } checkrs() { local I=1 while [ $I -le $CHKLOOP ]; do if curl --connect-timeout 1 http://$1 &> /dev/null; then return 0 fi let I++ done return 1 } initstatus() { local I local COUNT=0; for I in ${RS[*]}; do if ipvsadm -L -n | grep "$I:$RPORT" && > /dev/null ; then RSSTATUS[$COUNT]=1 else RSSTATUS[$COUNT]=0 fi let COUNT++ done } initstatus while :; do let COUNT=0 for I in ${RS[*]}; do if checkrs $I; then if [ ${RSSTATUS[$COUNT]} -eq 0 ]; then addrs $I ${RW[$COUNT]} [ $? -eq 0 ] && RSSTATUS[$COUNT]=1 && echo "`date +'%F %H:%M:%S'`, $I is back." >> $LOG fi else if [ ${RSSTATUS[$COUNT]} -eq 1 ]; then delrs $I [ $? -eq 0 ] && RSSTATUS[$COUNT]=0 && echo "`date +'%F %H:%M:%S'`, $I is gone." >> $LOG fi fi let COUNT++ done sleep 5 done