簡介:
Linux 虛擬服務器(Linux Virtual Server. LVS),是一個由章文鬆開發的自由軟件.利用KVS能夠實現高可用的、可伸縮縮的Web, Mail, Cache和Medial等網絡股務..井在此基 礎上開發支持龐大用戶數的,可伸縮的,高可用的電子商務應用。LVS1998年發展到如今,已經變得比較成熟,目前普遍應用在各類網絡服務和電了商務應用 中.
LVS具備很好的伸縮縮性、可靠性和管埋性,經過LVS要實現的最終目標是:利用linux 操做系統和LVS集羣軟件實現一個高可用、高性能,低成本的服務器應用集羣。
LVS集羣的組成
利用LVS架設的服務器羣系統由3個部分組成:最前端的是負栽均衡層(這裏用 Lo ad Balancer表示),中間是服務器集羣層(用Server Array表示).
LVS體系結構以下圖所示:
html
下面對LVS的各個組成部分進行詳細介紹
負 栽均衡層:位於整個集羣系統的最前端,由一臺或多臺負栽調度器(Dircctm Server)組成.LVS核心模塊IPVS就安裝在director Server上,而director的主要做用相似於一個路由器,它含有爲完成LVS功能所設定的路由表,經過這些路由表把用戶的請求分發給服務器羣組層 的應用服務器(real Server)。同時,在director server上還要安裝隊real server的監控模塊Ldirectord,此模塊用於監測各個real server 服務的健康情況。在real server 不可同時能夠講其從LVS路由表中剔除,在恢復時從新加入。
服務器羣組層:由一組實際運行應用服務的機器組成,real Server能夠是Web服務器、Mail服務器、FTP服務器、DNS服務器、視頰服務器中的一個或多個,每一個Real Server之間經過高速的LAN或分佈在各地的WAN相鏈接:實際的應用中, Director Server也能夠同時兼任Real Server的角色
共字存儲層是爲全部Real Server提供共亨存儲空問和內容一致性的存儲區域,通常由磁盤陣列設備組成。爲了提俱內容的一致性,通常能夠經過NFS網絡義件系統共 亨數據,可是NFS在繁忙的業務系統中,性能並非很好,此時能夠採用集羣文件 系統,例如Red Hat的GFS文件系統,Oracle提供的OS2文件系統等。
從整個LVS結構能夠看出,Director Server是整個LVS的核心。目前,用幹Director Server 的操做系統只有Linux和FreeBSD, Linux 2.6內核徹底內置了LVS的各個模塊,不用任何 設置就能夠支持LVS功能。
對丁 Real.Server,幾乎全部的系統平臺,如 Linux、.. Windows、Solaris、AIX、BSD 系列等都能很好地支持它
LVS集羣的特色
1. IP 負載均衡與負載調度
1負栽均衡技術有不少實現方案,有基於DNS.域名輪流解析的方法,有基於客戶端調度訪問的方法,還有基於應用層系統負栽的調度方法,還有基於p地址的調度方法。在這些負栽 調度算法中,執行效率最卨的是IP負栽均衡技術。
LVS 的IP負栽均衡技術是經過IPVS模塊來實現的。IPVS是LVS集羣系統的核心軟件, 它的主要做用是:安裝在Director Server上,同時在Director Server ..上虛擬出一個IP地址, 用戶必須經過這個虛擬的IP地址訪問服務器,這個虛擬IP —般稱爲LVS的VIP,即Virtual IP 訪問的請求首先通過VIP到達負栽調度器,而後由負栽調度器從Real Server列表中選取 一個服務節點響應用戶的請求。
在用戶的清求到達負栽調度器後,調度器如何將請求發送到提供服務的Real Server節 點,而Real Server節點如何返回數據給用戶,是IPVS實現的重點技術。IPVS實現負栽均 衡的方式有4種.分別是NAT|Full NAT、TUN和DR。下面進行詳細介紹。前端
IPVS/NAT :即 Virtual Server via Network Address Translation,也就是網絡地址翻譯技術實現虛擬服務器。當用戶請求到達調度器時,調度器將請求報文的目標地址(即 虛擬IP地址)改寫成選定的Real Server地址,同時將報文的目標端口也改爲選定的 Real Server的相應端口,最後將報文請求發送到選定的Real Server。在服務器端獲得數據後,Real Server將數據返回給用戶時,須要再次通過負栽調度器將報文的源地址和源端口改爲虛擬IP地址和相應端口,而後把數據發送給用戶,完成整個負栽調度過 程。能夠看出,在NAT方式下,用戶請求和響應報文都必須通過Director Server地址重寫, 當用戶請求愈來愈多時,調度器的處理能力將成爲瓶頸. 以下圖所示:IPVS/NAT 架構圖node
NAT:多目標的DNATlinux
特性:web
RS應該使用私有地址;算法
RS的網關必須指向DIP;數據庫
RIP和DIP必須在同一網段內;vim
請求和響應的報文都得通過Director;(在高負載應用場景中,Director極可能成爲系統性能瓶頸)後端
支持端口映射;瀏覽器
RS可使用任意支持集羣服務的OS(如Windows)
適用場景:
非高併發請求場景,10個RS之內;可隱藏內部的DIP和RIP地址;
結構圖:
LVS/TUN :即Virtual Server via IP Tunneling,也就是經過IP隧道技術實現虛擬服務器。這種方式的鏈接調度度和管理與VS/NAT方式同樣,只是報文轉發方法不一樣。在 VS/TUN方式中,調度器採用IP隧道技術將用戶清求轉發到某個Real Server,而這 個Real Server 將直接響應用戶的請求,再也不通過前端調度器。此外,對Real Server 的地域位置沒有要求,能夠和Director Server位於同一個網段,也能夠在獨立的一個 網絡中。所以,在TUN方式中,調度器將只處理用戶的報文請求,從而使集羣系統 的吞吐量大大提升。以下圖所示VS/TUN 架構圖:
TUN:IP隧道,即含有多個IP報頭
特性:
RIP、DIP、VIP都得是公網地址;
RS的網關不會指向也不可能指向DIP;
請求報文通過Director,但響應報文必定不通過Director;
不支持端口映射;
RS的操做系統必須得支持隧道功能,即部署ipip模塊
適用場景:
跨互聯網的請求轉發
結構圖:
FULLNAT是一種新的轉發模式
– 主要思想:引入local address(內網ip地址),cip-vip轉
換爲lip->rip,而 lip和rip均爲IDC內網ip,能夠跨vlan通
訊;FULLNAT:NAT模型的改進版
特性:
實現RS間跨VLAN通訊,是NAT模式的改進版;
默認內核不支持,需從新編譯內核,才能使用;
適用場景:
內網服務器跨VLAN的負載分擔
結構圖:
LVS/DR: 即Virtual Server via Direct Routing,也就是用直接路由技術實現虛擬服務器。 這種方式的連按調度和管理與前兩種同樣,但它的報文轉發方法又有所不一樣,VS/DR 經過改寫請求報文的MAC地址,將請求發送到Real Server,而Real Server將響應直接返回給客戶.免去了VS/TUN中的IP隧道開銷,這種方式是3種負莪調度方式中 性能最好的,可是要求Director Server與Real Server必須由一塊網卡連在同一物理網段上。
以下圖所示:VS/DR 架構圖
DR:Direct Routing
需解決的關鍵問題:
讓前端路由將請求發往VIP時,只能是Director上的VIP進行響應;實現方式是修改RS上的Linux內核參數,將RS上的VIP配置爲lo接口的別名,並限制Linux僅對對應接口的ARP請求作響應
特性:
RS可使用私有地址,但也可使用公網地址,此時能夠直接經過互聯網連入RS以實現配置,監控等;
RS的網關必定不能指向DIP;
RS和Director要在同一物理網絡(即不能由路由器分隔)
請求報文通過Director,但響應報文必定不進過Director;
不支持端口映射;
RS可使用大多數的操做系統
適用場景:
由於響應報文不通過Director,極大的減輕了Director的負載壓力,故Director能夠支持更大的併發訪問,通常RS在100臺之內;
結構圖:
LVS-DR配置架構根據其VIP與RIP是否在同一個網段內又分爲兩種模型:
LVS調度算法
(2)負我調度算法
靜態方法:僅根據算法自己進行調度
rr:Round Robin # 即輪詢 wrr:Weighted RR # 即加權輪詢 sh:Source Hashing # 即來源IP地址hash dh:Destination Hashing # 即目標地址hash(不經常使用,僅用於前端多防火牆的場景,保證防火牆的鏈接追蹤功能有效)
動態方法:根據算法及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 # 集羣開始時工做時,每臺服務器都至少分配一個鏈接請求,而後再根據sed算法調度; lblc:Locality-based Least Connection # 相似於dh+lc lblcr:Relicated and Locality-based Least Connection # 主要用於後端服務器是緩存服務器時
前 面介紹過,負載調度器是根據各個服務器的負栽狀況,動態地選擇一臺Real Server響 應用戶請求。那麼動態選擇是如何實現呢?其實就是經過這裏要說的負栽調度算法。根據不一樣的網絡眼務需求和眼務器配IPVS實現T8種負栽調度算法。這裏詳 細講述最經常使用的4 種調度算法。
一、 輪詢(round robin, rr),加權輪詢(Weighted round robin, wrr)——新的鏈接請求被輪流分配至各RealServer;算法的優勢是其簡潔性,它無需記錄當前全部鏈接的狀態,因此它是一種無狀態調度。輪叫調度 算法假設全部服務器處理性能均相同,無論服務器的當前鏈接數和響應速度。該算法相對簡單,不適用於服務器組中處理性能不一的狀況,並且當請求服務時間變化 比較大時,輪叫調度算法容易致使服務器間的負載不平衡。
二、 最少鏈接(least connected, lc), 加權最少鏈接(weighted least connection, wlc)——新的鏈接請求將被分配至當前鏈接數最少的RealServer;最小鏈接調度是一種動態調度算法,它經過服務器當前所活躍的鏈接數來估計服務 器的負載狀況。調度器須要記錄各個服務器已創建鏈接的數目,當一個請求被調度到某臺服務器,其鏈接數加1;當鏈接停止或超時,其鏈接數減一。
三、 基於局部性的最少連接調度(Locality-Based Least Connections Scheduling,lblc)——針對請求報文的目標IP地址的負載均衡調度,目前主要用於Cache集羣系統,由於在Cache集羣中客戶請求報文 的目標IP地址是變化的。這裏假設任何後端服務器均可以處理任一請求,算法的設計目標是在服務器的負載基本平衡狀況下,將相同目標IP地址的請求調度到同 一臺服務器,來提升各臺服務器的訪問局部性和主存Cache命中率,從而整個集羣系統的處理能力。LBLC調度算法先根據請求的目標IP地址找出該目標 IP地址最近使用的服務器,若該服務器是可用的且沒有超載,將請求發送到該服務器;若服務器不存在,或者該服務器超載且有服務器處於其一半的工做負載,則 用「最少連接」的原則選出一個可用的服務器,將請求發送到該服務器。
四、 帶複製的基於局部性最少連接調度(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地址對應的服務器組;按「最小鏈接」原則從該服務器組中選出一臺服務器,若服務器沒有超載,將請求發送到該服務器;若服務器超載;則按 「最小鏈接」原則從整個集羣中選出一臺服務器,將該服務器加入到服務器組中,將請求發送到該服務器。同時,當該服務器組有一段時間沒有被修改,將最忙的服 務器從服務器組中刪除,以下降複製的程度。
五、 目標地址散列調度(Destination Hashing,dh)算法也是針對目標IP地址的負載均衡,但它是一種靜態映射算法,經過一個散列(Hash)函數將一個目標IP地址映射到一臺服務 器。目標地址散列調度算法先根據請求的目標IP地址,做爲散列鍵(Hash Key)從靜態分配的散列表找出對應的服務器,若該服務器是可用的且未超載,將請求發送到該服務器,不然返回空。
六、 源地址散列調度(Source Hashing,sh)算法正好與目標地址散列調度算法相反,它根據請求的源IP地址,做爲散列鍵(Hash Key)從靜態分配的散列表找出對應的服務器,若該服務器是可用的且未超載,將請求發送到該服務器,不然返回空。它採用的散列函數與目標地址散列調度算法 的相同。除了將請求的目標IP地址換成請求的源IP地址外,它的算法流程與目標地址散列調度算法的基本類似。在實際應用中,源地址散列調度和目標地址散列 調度能夠結合使用在防火牆集羣中,它們能夠保證整個系統的惟一出入口。
七、加權最少鏈接調度(Weighted Least Connections)。
「加 權最少鏈接調度」是「最少鏈接調度」的超集。每一個服務節點能夠用相應的權值表示其處理能力,而系統管理員能夠動態地設置相應的權值,默認權值爲1。加權最 小鏈接調 度在分新鏈接請求時儘量使服務節點的已創建鏈接數和其權值成正比。算法: overhead=active*256+inactive/weight overhead最小值勝出;
八、sed:shorttest expect delay 最小指望延遲(改進的wlc) 算法:overhead=(active+1)*256/weight,案例:假如DFG三臺機器分別權重123,鏈接數也分別是123.那麼若是使用WLC算法的話一個新請求進入時它可能會分給DFG中的任意一個。使用sed算法後會進行這樣一個運算:
D(1+1)/1
F(1+2)/2
G(1+3)/3
九、nq:nerver queue 加強改進的sed算法.若是有臺real Server的鏈接數=0直接分配,不須要再進行sed運算
2.高可用性
LVS 是一個基於內核級別的應用軟件,所以具備很髙的處理性能。由LVS構建的負載 均衡集羣系統具備優秀的處理能力,每一個服務節點的故障不會影響整個系統的正常使用,又可以實現負載的合理均衡,使應用具備超高負荷的服務能力,可支持上百 萬個併發鏈接請 求。如配置百兆網卡,採用VS/TUN或VS/DR調度技術,整個集羣系統的吞吐量可高達 1 Gbit/s;又如配置千兆網卡,系統的最大吞吐量可接近10Gbit/s。
3.高可靠性
LVS負載均衡集羣軟件已經在 企業和學校中獲得了很好的普及,國內外不少大型的、關鍵性的Web站點也都採用了 LVS集羣軟件,因此它的可靠性在實踐中獲得了很好印證。有 不少由LVS構成的負載均衡系統,運行很長時間,從未進行太重新啓動。這些都說明了 LVS 的髙穩定性和高可靠性。
四、配置LVS
一、定義在Director上進行dispatching的服務(service),以及哪此服務器(server)用來提供此服務;
二、爲每臺同時提供某一種服務的服務器定義其權重(即概據服務器性能肯定的其承擔負載的能力);
注:權重用整數來表示,有時候也能夠將其設置爲atomic_t;其有效表示值範圍爲24bit整數空間,即(2^24-1);
所以,ipvsadm命令的主要做用表如今如下方面:
一、添加服務(經過設定其權重>0);
二、關閉服務(經過設定其權重>0);此應用場景中,已經鏈接的用戶將能夠繼續使用此服務,直到其退出或超時;新的鏈接請求將被拒絕;
三、保存ipvs設置,經過使用「ipvsadm-sav > ipvsadm.sav」命令實現;
四、恢復ipvs設置,經過使用「ipvsadm-sav < ipvsadm.sav」命令實現;
五、顯示ip_vs的版本號,下面的命令顯示ipvs的hash表的大小爲4k;
# ipvsadm
IP Virtual Server version 1.2.1 (size=4096)
六、顯示ipvsadm的版本號
# ipvsadm --version
ipvsadm v1.24 2003/06/07 (compiled with popt and IPVS v1.2.0)
2、ipvsadm使用中應注意的問題
默 認狀況下,ipvsadm在輸出主機信息時使用其主機名而非IP地址,所以,Director須要使用名稱解析服務。若是沒有設置名稱解析服務、服務不可 用或設置錯誤,ipvsadm將會一直等到名稱解析超時後才返回。固然,ipvsadm須要解析的名稱僅限於RealServer,考慮到DNS提供名稱 解析服務效率不高的狀況,建議將全部RealServer的名稱解析經過/etc/hosts文件來實現;
3、調度算法
Director在接收到來自於Client的請求時,會基於"schedule"從RealServer中選擇一個響應給Client。ipvs支持如下調度算法:
4、關於LVS追蹤標記fwmark:
若是LVS放置於多防火牆的網絡中,而且每一個防火牆都用到了狀態追蹤的機制,那麼在迴應一個針對於LVS的鏈接請求時必須通過此請求鏈接進來時的防火牆,不然,這個響應的數據包將會被丟棄。
經常使用命令:
查看LVS上當前的全部鏈接
# ipvsadm -Lcn
或者
#cat /proc/net/ip_vs_conn
查看虛擬服務和RealServer上當前的鏈接數、數據包數和字節數的統計值,則可使用下面的命令實現:
# ipvsadm -l --stats
查看包傳遞速率的近似精確值,可使用下面的命令:
# ipvsadm -l --rate
VS/NAT
LVS- NAT基於cisco的LocalDirector。VS/NAT不須要在RealServer上作任何設置,其只要能提供一個tcp/ip的協議棧即 可,甚至其不管基於什麼OS。基於VS/NAT,全部的入站數據包均由Director進行目標地址轉換後轉發至內部的 RealServer,RealServer響應的數據包再由Director轉換源地址後發回客戶端。
VS/NAT模式不能與netfilter兼容,所以,不能將VS/NAT模式的Director運行在netfilter的保護範圍之中。如今已經有補丁能夠解決此問題,但還沒有被整合進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 設置轉發: # 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 打開路由轉發功能 # 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.219 DIP=192.168.10.10 RIP1=192.168.10.11 RIP2=192.168.10.12 # case "$1" in start) /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 上網關必定要指向director服務器的DIP,否則用戶請求的數據報文,在LVS/NAT模型中將沒法發送出去.
#!/bin/bash VIP=192.168.0.219 chmod 755 /etc/rc.d/init.d/functions /etc/rc.d/init.d/functions case "$1" in start) 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: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 ;; stop) /sbin/ifconfig lo:0 down echo "close LVS Directorserver" 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 "Usage: $0 {start|stop}" exit 1 esac
ARP問題:
__________ | | | client | |________| | | (router) | | | __________ | DIP | | |------| director | | VIP |__________| | | | ------------------------------------ | | | | | | RIP1, VIP RIP2, VIP RIP3, VIP ______________ ______________ ______________ | | | | | | | realserver1 | | realserver2 | | realserver3 | |______________| |______________| |______________|
在如上圖的VS/DR或VS/TUN 應用的一種模型中(全部機器都在同一個物理網絡),全部機器(包括Director和RealServer)都使用了一個額外的IP地址,即VIP。當一 個客戶端向VIP發出一個鏈接請求時,此請求必需要鏈接至Director的VIP,而不能是RealServer的。由於,LVS的主要目標就是要 Director負責調度這些鏈接請求至RealServer的。
所以,在Client發出至VIP的鏈接請求後,只能由Director將其 MAC地址響應給客戶端(也多是直接與Director鏈接的路由設備),而Director則會相應的更新其ipvsadm table以追蹤此鏈接,然後將其轉發至後端的RealServer之一。
若是Client在請求創建至VIP的鏈接時由某RealServer 響應了其請求,則Client會在其MAC table中創建起一個VIP至RealServer的對就關係,並以致進行後面的通訊。此時,在Client看來只有一個RealServer而沒法意 識到其它服務器的存在。
爲了解決此問題,能夠經過在路由器上設置其轉發規則來實現。固然,若是沒有權限訪問路由器並作出相應的設置,則只能經過傳統的本地方式來解決此問題了。這些方法包括:
一、禁止RealServer響應對VIP的ARP請求;
二、在RealServer上隱藏VIP,以使得它們沒法獲知網絡上的ARP請求;
三、基於「透明代理(Transparent Proxy)」或者「fwmark (firewall mark)」;
四、禁止ARP請求發往RealServers;
傳 統認爲,解決ARP問題能夠基於網絡接口,也能夠基於主機來實現。Linux採用了基於主機的方式,由於其能夠在大多場景中工做良好,但LVS卻並不屬於 這些場景之一,所以,過去實現此功能至關麻煩。如今能夠經過設置arp_ignore和arp_announce,這變得相對簡單的多了。
Linux 2.2和2.4(2.4.26以前的版本)的內核解決「ARP問題」的方法各不相同,且比較麻煩。幸運的是,2.4.26和2.6的內核中引入了兩個新的 調整ARP棧的標誌(device flags):arp_announce和arp_ignore。基於此,在DR/TUN的環境中,全部IPVS相關的設定都可使用 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配置在本地迴環接口lo上。若是迴應給Client的數據包路由到了eth0接口上,則arp通告或請應該經過eth0實現,所以,須要在sysctl.conf文件中定義以下配置:
#vim /etc/sysctl.conf net.ipv4.conf.eth0.arp_ignore = 1 net.ipv4.conf.eth0.arp_announce = 2 net.ipv4.conf.all.arp_ignore = 1 net.ipv4.conf.all.arp_announce = 2
以上選項須要在啓用VIP以前進行,不然,則須要在Drector上清空arp表才能正常使用LVS。
到 達Director的數據包首先會通過PREROUTING,然後通過路由發現其目標地址爲本地某接口的地址,所以,接着就會將數據包發往 INPUT(LOCAL_IN HOOK)。此時,正在運行內核中的ipvs(始終監控着LOCAL_IN HOOK)進程會發現此數據包請求的是一個集羣服務,由於其目標地址是VIP。因而,此數據包的原本到達本機(Director)目標行程被改變爲經由 POSTROUTING HOOK發往RealServer。這種改變數據包正常行程的過程是根據IPVS表(由管理員經過ipvsadm定義)來實現的。
若是有 多臺Realserver,在某些應用場景中,Director還須要基於「鏈接追蹤」實現將由同一個客戶機的請求始終發往其第一次被分配至的 Realserver,以保證其請求的完整性等。其鏈接追蹤的功能由Hash table實現。Hash table的大小等屬性可經過下面的命令查看:
# ipvsadm -lcn
爲了保證其時效性,Hash table中「鏈接追蹤」信息被定義了「生存時間」。LVS爲記錄「鏈接超時」定義了三個計時器:
一、空閒TCP會話;
二、客戶端正常斷開鏈接後的TCP會話;
三、無鏈接的UDP數據包(記錄其兩次發送數據包的時間間隔);
上面三個計時器的默認值能夠由相似下面的命令修改,其後面的值依次對應於上述的三個計時器:
# ipvsadm --set 28800 30 600
數據包在由Direcotr發往 Realserver時,只有目標MAC地址發生了改變(變成了Realserver的MAC地址)。Realserver在接收到數據包後會根據本地路 由表將數據包路由至本地迴環設備,接着,監聽於本地迴環設備VIP上的服務則對進來的數據庫進行相應的處理,然後將處理結果迴應至RIP,但數據包的原地 址依然是VIP。
ipvs的持久鏈接:
不管基於什麼樣的算法,只要指望源於同一個客戶端的請求都由同一臺Realserver響應時,就須要用到持久鏈接。好比,某一用戶連續打開了三個telnet鏈接請求時,根據RR算法,其請求極可能會被分配至不一樣的Realserver,這一般不符合使用要求。
二、IPVS/DR
Director:
IP分配
VIP=192.168.0.210
RIP1=192.168.0.221
RIP2=192.168.0.222
一、下載安裝ipvsadm
wget http://www.linuxvirtualserver.org/software/kernel-2.6/ipvsadm-1.26.tar.gz tar zxvf ipvsadm-1.26.tar.gz cd ipvsadm-1.26 make && make install
二、編寫並運行腳本(LVS服務器的腳本)
vim director.sh #!/bin/bash # # LVS script for VS/DR # . /etc/rc.d/init.d/functions # VIP=192.168.0.210 RIP1=192.168.0.221 RIP2=192.168.0.222 PORT=80 # case "$1" in start) /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
三、給腳本加權限,並執行
chmod 755 /etc/rc.d/init.d/functions chmod +x director.sh ./director.sh start
四、配置後端的WEB服務器腳本
vim realserver.sh #!/bin/bash # # Script to start LVS DR real server. # description: LVS DR real server # . /etc/rc.d/init.d/functions VIP=192.168.0.210 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
五、給腳本加權限,並執行
chmod 755 /etc/rc.d/init.d/functions chmod +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-address ipvsadm -C ipvsadm -R ipvsadm -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-address ipvsadm -L|l [options] ipvsadm -Z [-t|u|f service-address] ipvsadm --set tcp tcpfin udp ipvsadm --start-daemon state [--mcast-interface interface] ipvsadm --stop-daemon ipvsadm -h 命令選項解釋: 有兩種命令選項格式,長的和短的,具備相同的意思。在實際使用時,兩種均可以。 -A --add-service 在內核的虛擬服務器表中添加一條新的虛擬服務器記錄。也就是增長一臺新的虛擬服務器。 -E --edit-service 編輯內核虛擬服務器表中的一條虛擬服務器記錄。 修改定義過的集羣服務 -D --delete-service 刪除內核虛擬服務器表中的一條虛擬服務器記錄。 -C --clear 清除內核虛擬服務器表中的全部記錄。 -R --restore 恢復虛擬服務器規則 -S --save 保存虛擬服務器規則,輸出爲-R 選項可讀的格式 -a --add-server 在內核虛擬服務器表的一條記錄裏添加一條新的真實服務器記錄。也就是在一個虛擬服務器中增長一臺新的真實服務器 -e --edit-server 編輯一條虛擬服務器記錄中的某條真實服務器記錄 -d --delete-server 刪除一條虛擬服務器記錄中的某條真實服務器記錄 -L|-l --list 顯示內核虛擬服務器表 userver 列表; -Z --zero 虛擬服務表計數器清零(清空當前的鏈接數量等) --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 說明是通過iptables 標記過的服務類型。一般用於將兩個或兩個以上的服務綁定爲一個服務進行處理時使用; -s --scheduler scheduler 使用的調度算法,有這樣幾個選項 rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq,默認的調度算法是:wlc. -p --persistent [timeout] 持久穩固的服務。這個選項的意思是來自同一個客戶的屢次請求,將被同一臺真實的服務器處理。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 真實服務器的權值 --mcast-interface interface 指定組播的同步接口 -c --connection 顯示LVS 目前的鏈接 如:ipvsadm -L -c --timeout 顯示tcp tcpfin udp 的timeout 值 如:ipvsadm -L --timeout --daemon 顯示同步守護進程狀態 --stats 顯示統計信息 ipvsadm –Ln --state 總共的數量 --rate 顯示速率信息 ipvsadm –Ln --rete 平均值 --sort 對虛擬服務器和真實服務器排序輸出 --numeric -n 輸出IP 地址和端口的數字形式
集羣相關的命令參數:
-A --add-service 在內核的虛擬服務器表中添加一條新的虛擬服務器記錄。也就是增長一臺新的虛擬服務器。 -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 使用的調度算法,有這樣幾個選項 rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq,默認的調度算法是:wlc. -p --persistent [timeout] 持久穩固的服務。這個選項的意思是來自同一個客戶的屢次請求,將被同一臺真實的服務器處理。timeout 的默認值爲300 秒。 持久鏈接; -E --edit-service 編輯內核虛擬服務器表中的一條虛擬服務器記錄。 修改定義過的集羣服務 -D :刪除指定集羣服務
RS相關的命令參數:
-a --add-server 在內核虛擬服務器表的一條記錄裏添加一條新的真實服務器記錄。也就是在一個虛擬服務器中增長一臺新的真實服務器 向指定的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權重: -e:修改指定的RS屬性 -d :從指定的集羣服務中刪除某RS
LVS的持久鏈接:
lvs持久鏈接適用於大部分調度算法。當某一種請求須要定向到一個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 //清空ipvs表 #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端口的標記是同樣的,這個時候在訪問的時候,就會創建姻親關係,其餘的配置和C的配置同樣,很少演示了
測試:在瀏覽器中輸入http://192.168.1.80和https://192.168.1.80發現訪問的是同一個頁面,就證實成功啦!
由於LVS自身本沒有多後端real server 作健康狀態檢測的功能因此:
編寫健康狀態監測腳本:
LVS負載均衡器自己是沒有對後端服務器作健康狀態監測的功能的;因此咱們能夠編寫一個小小的腳原本完成這個功能; 註釋:這些腳本的列子很粗糙,只是讓大家瞭解整個過程是怎樣的;
健康狀態監測腳本實例:
RS健康狀態檢查腳本示例初版: #!/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健康狀態檢查腳本示例第二版: #!/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