LVS是Linux Virtual Server的簡寫,意即Linux虛拟伺服器,是一個虛拟的伺服器叢集系統。本項目在1998年5月由章文嵩博士成立,是中國國内最早出現的自由軟體項目之一。
組成部分:ipvs(真正工作在核心中),ipvsadm
ipvs工作于netfilter的INPUT鍊路:
ipvsadm用于在ipvs上定義叢集服務;同時也得定義此叢集服務對應于有哪個後端主機可用;根據所指定的排程方法(算法)作出排程決策;
LVS體系結構如下圖所示:

lvs中的常用術語約定:
Host:
Director:排程器
Real Server:RS,後端真正提供服務的主機
IP:
Client:CIP (用戶端IP)
Director Virtual IP:VIP(與用戶端主機通信的位址)(也被稱為流動IP位址)
Director IP:DIP(與後端主機通信的位址)
Real IP:RIP(後端真正提供服務的位址)
負載均衡技術有很多實作方案,有基于DNS域名輪流解析的方法,有基于用戶端排程通路的方法,還有基于應用層系統負載的排程方法,還有基于ip位址的排程方法。在這些負載排程算法中,執行效率最高的是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種:
lvs-nat:masquerade
lvs-dr:direct routing
lvs-tun:tunneling
lvs-fullnet:(淘寶研發的) fullnat
IPVS/NAT :即 Virtual Server via NetworkAddress Translation,也就是網絡位址翻譯技術實作虛拟伺服器。當使用者請求到達排程器時,排程器将請求封包的目标位址(即虛拟IP位址)改寫成標明的Real Server位址,同時将封包的目标端口也改成標明的Real Server的相應端口,最後将封包請求發送到標明的RealServer。在伺服器端得到資料後,Real Server将資料傳回給使用者時,需要再次經過負載排程器将封包的源位址和源端口改成虛拟IP位址和相應端口,然後把資料發送給使用者,完成整個負載排程過程。可以看出在NAT方式下,使用者請求和響應封包都必須經過Director Server位址重寫,當使用者請求越來越多時,排程器的處理能力将成為瓶頸.
架構特性:
(1)RS應該使用私有位址,即RIP應該為私有位址;各RS的網關必須指向DIP;
(2)請求和響應封包都經由Director轉發;高負載場景中,Director易于成為系統瓶頸;
(3)支援端口映射;
(4)RS可以使用任意類型的OS;
(5)RS的RIP必須與Director的DIP在同一網絡;
VS/DR: 即Virtual Server via DirectRouting,也就是用直接路由技術實作虛拟伺服器。 這種方式的連接配接排程和管理與前兩種一樣,但它的封包轉發方法又有所不同,VS/DR 通過改寫請求封包的MAC位址,将請求發送到Real Server,而Real Server将響應直接傳回給客戶.免去了VS/TUN中的IP隧道開銷,這種方式是3種負莪排程方式中性能最好的,但是要求Director Server與Real Server必須由一塊網卡連在同一實體網段上。
LVS-DR:直接路由
Director在實作轉發時不修改請求的IP首部,而是通過直接封裝MAC首部完成轉發;
目标MAC是Director根據排程方法挑選出某RS的MAC位址;拓撲結構有别NAT類型;
(1) 保證前端路由器将目标位址為VIP的請求封包通過ARP位址解析後送往Director;
解決方案:
靜态綁定:在前端路由直接将VIP對應的目标MAC靜态配置為Director的MAC位址;
arptables:在各RS上,通過arptables規則拒絕其響應對VIP的ARP廣播請求;
核心參數(常用方法):在RS上修改核心參數,并結合位址的配置方式實作拒絕響應對VIP的ARP廣播請求;
(2) RS的RIP可以使用私有位址:但也可以使用公網位址,此時可以通過網際網路上的主機 直接對此RS發起管理操作;
(3) 請求封包必須經由Director排程,但響應封包必須不能經由Director;
(4) 各RIP必須與DIP在同一個實體網絡中;
(5) 不支援端口映射;
(6) RS可以使用大多數的OS;
(7) RS的網關一定不能指向Director;
lvs-tun:不修改請求封包IP首部,而是通過IP隧道機制在原有的IP封包之外再封裝IP首部, 經由網際網路把請求交給標明的RS;CIP;VIP DIR;RIP.
架構特性:
(1) RIP,DIP,VIP都是公網位址;
(2) RS的網關不能,也不可能指向DIP;
(3) 請求封包由Director分發,但響應封包直接由RS響應給Client;
(4) 不支援端口映射;
(5) RS的OS必須得支援IP隧道;
lvs-fullnat:通過修改請求封包的源位址為DIP,目标為DIP來實作轉發;對于響應封包而言,修改源位址為VIP,目标地 址為CIP來實作轉發;
架構特性:
(1) RIP,DIP可以使用私有位址;
(2) RIP,DIP可以不在同一個網絡中,且RIP的網關未必需要指向DIP;
(3) 支援端口映射;
(4) RS的OS可以使用任意類型;
(5) 請求封包經由Director,響應封包經由Director;
lvsscheduler:排程算法
靜态方法:僅根據算法本身實作排程;(起點公平)
rr:Round Robin # 即輪詢
wrr:WeR # 即權重ighted R輪詢 算法:Overhead=conn/weight
sh:Source Hashing # 即來源IP位址hash
dh: Destination ip Hashing # 目标位址哈希;把來自同一位址請求,統統定向至此前標明的RS;把通路同一個目标位址 的請求,統統定向至此前標明的某RS;
動态方法:根據算法及後端RS目前的負載狀況實作排程;(結果公平)
LC:least connection(最少連接配接)
Overhead=Active*256+Inactive (計算目前負載狀态的值)
WLC(預設排程算法,用的最多的):weighted least connection(權重最小連接配接)
Overhead=(Active*256+Inactive)/weight
SED:Shorted Expection Delay(最短期望延遲)
Overhead=(Active+1)*256/weight權重 (第一個請求一定會給權重最大的;
問題前幾個請求會一直給權重較大的主機而權重小的主機一直得不到請求,)
NQ:Never queue 永不排隊;
LBLC: Local-Based Least Connection,動态方式的DH算法;
LBLCR:Replicated LBLC; 帶複制的LBLC,共享緩存内容,(複制是有限的,複制特定的目标)
session 保持:
session sticky:(會話粘性):sh;基于源ip綁定,基于cookie綁定;
session replication cluster:session複制
在各server之間以多點傳播方式”複制“各session資訊,進而每個server會持有所有的 session;(tomcat)
session server:引入第三方存儲,專用于共享存儲session資訊;(redis,memcached)
常用指令:
建立或修改:
ipvsadm -A|E -t|u|f service-address [-sscheduler]
-A:在核心的虛拟伺服器表中添加一條新的虛拟伺服器記錄。也就是增加一台新的虛拟伺服器。
-E: 修改,編輯核心虛拟伺服器表中的一條虛拟伺服器記錄。 修改定義過的叢集服務
-t:承載的應用層協定為基于TCP協定提供服務的協定;其service-address的格式為“VIP:PORT”,如“172.16.8.100:80”;
-u:承載的應用層協定為基于UDP協定提供服務的協定;其service-address的格式為“VIP:PORT”,如“172.16.8.100:53”
-f:承載的應用層協定為基于TCP或UDP協定提供服務的協定,但此類封包會經由iptables/netfilter打标記,即為防火牆标記;其 service-address的格式為“FWM”, 例如“10”;
-s scheduler:指明排程方法;預設為WLC;有這樣幾個選項rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq
-p --persistent [timeout] :持久穩固的服務。這個選項的意思是來自同一個客戶的多次請求,将被同一台真實的伺服器 處理。timeout的預設值為360秒。
-D :删除指定叢集服務
# ipvsadm -A172.16.8.100:80 [-s WLC] 定義服務;
删除: ipvsadm -D -t|u|f service-address
# ipvsadm-D -t 172.16.8.100:80 删除服務定義
# ipvsadm-L –n 檢視服務定義
檢視LVS上目前的所有連接配接
# ipvsadm -Lcn
或者
#cat /proc/net/ip_vs_conn
檢視虛拟服務和Real Server上目前的連接配接數、資料包數和位元組數的統計值,則可以使用 下面的指令實作:
# ipvsadm -L --stats
檢視包傳遞速率的近似精确值,可以使用下面的指令:
# ipvsadm -L --rate
管理叢集服務上的RS:
添加或修改:
ipvsadm -a|e -t|u|f service-address -rserver-address [-g|i|m] [-w weight] [-x upper] [-y lower]
-r server-address:指明RS,server-address格式一般為”IP[:PORT]“;
注意,隻支援端口映射的lvs類型中才應該顯示定義此處端口;
-a --add-server: 在核心虛拟伺服器表的一條記錄裡添加一條新的真實伺服器記錄。也就是在一個虛拟伺服器中增加一台新的 真實伺服器。向指定的CS中添加RS
-t service-address: 說明虛拟伺服器提供的是tcp的服務
-u service-address: 說明虛拟伺服器提供的是udp的服務
-f:承載的應用層協定為基于TCP或UDP協定提供服務的協定,但此類封包會經由 iptables/netfilter打标記,即為防火牆标記;其service-address的格式為“FWM”, 例如“10”;
-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
例如: -r 192.16.1.7:80
[-g|i|m]:指明lvs類型
-g:gateway,意為dr類型;(預設類型)
-i:ipip,意為tun類型;
-m:masquerade,意為nat類型;
[-w weight]:目前RS的權重;
注意: 僅對于支援權重排程的scheduler,權重才有意義;
例:# ipvsadm -A -t172.16.8.100:80 添加一個叢集服務;
# ipvsadm -L -n
# ipvsadm -a -t 172.16.8.100:80-r 192.168.1.7[:8080] -m -w 2
# ipvsadm -a -t 172.16.8.100:80-r 192.168.1.8[:8080] -m -w 5
删除:
ipvsadm -d -t|u|fservice-address -r server-address
# ipvsadm -d -t 172.16.8.100:80-r 192.168.1.7
# ipvsadm -L –n
清空所有叢集服務的定義:ipvsadm -C
清空所有服務定義:# ipvsadm -C
#ipvsadm -L -n
保持叢集服務及RS的定義:
ipvsadm -S >/etc/sysconfig/ipvsadm
ipvsadm-save > /etc/sysconfig/ipvsadm
service ipvsadm save 直接儲存到配置檔案中.
===========================================================================
NAT模型:
環境要求:
兩台内部的RS服務位址:
RS1:192.168.1.2 預設網關:192.168.1.1
RS2:192.168.1.3 預設網關:192.168.1.1
Director主機:VIP:172.16.8.100
RIP:192.168.1.1
配置:
RS1:
# vim/var/www/html/index.html
<h1>RS1.blue.com</h1>
# service httpd start
設定預設網關指向Director 主機:
# route add defaultgw 192.168.1.1
# route -n 進行驗證
RS2:
<h1> RS2.blue.com </h1>
# service httpd start
Director主機:進行驗證;
注意: 確定iptables 是放行狀态,還有SELINUX是關閉的;
[root@localhost ~]# curlhttp://192.168.1.2
<h1> RS1.blue.com </h1>
[root@localhost~]# curl http://192.168.1.3
<h1> RS2.blue.com </h1>
配置ipvsadm規則:
# iptables -L -n -v 確定iptables規則都是空的;
# ipvsadm -A -t172.16.8.100:80 -s rr 輪詢;
# ipvsadm -a -t172.16.8.100:80 -r 192.168.1.2 -m -w 1
# ipvsadm -a -t172.16.8.100:80 -r 192.168.1.3 -m -w 3
# ipvsadm -L -n
現在通路還是不能通路,檢視核心轉發是否打開了;
# cat/proc/sys/net/ipv4/ip_forward
開啟,并讓它永久生效:
# vim /etc/sysctl.conf
修改成:
net.ipv4.ip_forward = 1
# sysctl -p 立即生效;
通路:172.16.8.100
[root@localhost ~]# ipvsadm -L -n --stats
IP Virtual Server version 1.2.1(size=4096)
Prot LocalAddress:Port Conns InPkts OutPkts InBytes OutBytes
-> RemoteAddress:Port
TCP 172.16.8.100:80 198 976 949 127437 95539
-> 192.168.1.2:80 99 486 473 63414 47482
->192.168.1.3:80 99 490 476 64023 48057
修改排程算法類型:
# ipvsadm -E -t 172.16.8.100:80 -s wrr
[root@localhost ~]# ipvsadm -ln 權重比是1比3;
IP Virtual Server version 1.2.1(size=4096)
Prot LocalAddress:Port SchedulerFlags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.8.100:80 wrr
-> 192.168.10.2:80 Masq 1 0 31
->192.168.10.3:80 Masq 3 0 93
[root@localhost ~]# ipvsadm -L -n--stats
Prot LocalAddress:Port Conns InPkts OutPkts InBytes OutBytes
-> RemoteAddress:Port
TCP 172.16.8.100:80 323 1604 1572 210534 149387
-> 192.168.10.2:80 130 643 628 84202 63137
-> 192.168.10.3:80 193 961 944 126332 86250
# ab -n 10000 -c 100http://172.16.8.100/index.html
[root@localhost~]# ipvsadm -L -n --stats
TCP 172.16.8.100:80 10353 51756 51722 3801354 5776205
-> 192.168.10.2:80 2637 13178 13163 981708 1469564
-> 192.168.10.3:80 7716 38578 38559 2819646 4306641
抓包方法:
#tcpdump -i eth0
# tcpdump -i eth0 src host 172.16.8.1
#tcpdump -i eth0 src host 172.16.8.1 and tcp port 80
============================================================================
Lvs-DR模型:
(1)各RS要直接響應Client,是以,各RS均得配置VIP;但僅能夠讓Director上的
VIP能夠與本地路由直接通信;
(2)Director 不會拆除或修改請求封包的IP首部,而是通過封裝新的幀首部
(源MAC為Director的MAC,目标MAC為挑選出的RS的MAC)完成排程;
示例:
RS1:RIP,eth0:17.16.8.11
VIP,lo0:172.16.8.200
RS2:RIP,eth0:17.16.8.12
VIP,lo:0: 172.16.8.200
DIP: eth017.16.8.100
VIP,eth0:0 : 172.16.8.200
RS1: lo接口可以,eth0接口也可以;
# cd/proc/sys/net/ipv4/conf/
# ls
# echo 1 >/proc/sys/net/ipv4/conf/all/arp_ignore
# echo 1 >/proc/sys/net/ipv4/conf/lo/arp_ignore
# echo 2 >/proc/sys/net/ipv4/conf/lo/arp_announce
#echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
# sysctl -a | grep arp 驗證結果;
配置位址:
# ifconfig lo:0 172.16.8.200broadcast 172.16.8.200 netmask 255.255.255.255 up
# ifconfig
# ping 172.16.8.200
# arp -a 檢視 MAC位址是誰的;
# ss -tnl 檢視 http服務 是否啟動;
實體機進行通路: 驗證web服務是否正常;
172.16.8.11
172.16.8.12
添加路由條目:
# route add -host 172.16.8.200dev lo:0
RS2: lo接口可以,eth0接口也可以;
# echo 2 >/proc/sys/net/ipv4/conf/all/arp_announce
# sysctl -a | grep arp 驗證結果;
# ifconfig
# route add -host 172.16.8.200dev lo:0
DIP:
配置VIP:
# ifconfig eth0:0 172.16.8.200netmask 255.255.255.255 broadcast 172.16.8.200 up
# ifconfig 限制廣播範圍;
# ipvsadm -C
# iptables -F
# route add -host 172.16.8.200 deveth0:0
#sysctl -a | grep ip_forward
打開轉發功能:
# cat/proc/sys/net/ipv4/ip_forward
開啟,并讓它永久生效:
# vim /etc/sysctl.conf
修改成:
net.ipv4.ip_forward =1
# sysctl -p
添加規則:
# ipvsadm -A -t 172.16.8.200:80-s rr
# ipvsadm -a -t 172.16.8.200:80-r 172.16.8.11 -g -w 1
# ipvsadm -a -t 172.16.8.200:80-r 172.16.8.12 -g -w 3
# ipvsadm -Ln
==============================================================================
示例: 不在同一網絡中;(根據上面示例進行修改即可;)
路由器位址:打開了路由間轉發的功能的;
172.16.0.1
192.168.0.254
192.168.1.254
RS1:RIP,eth0:192.168.0.11
VIP,lo0:172.16.8.200
網關要指向:192.168.0.254
# ifconfig eth0192.168.0.11/24 up
# ping 192.168.0.254
# route add defaultgw 192.168.0.254
RS2:RIP,eth0:192.168.0.12
VIP,lo:0:172.16.8.200
# ifconfig eth0192.168.0.12/24 up
# ping 172.16.0.1
DIP: eth0:192.168.0.10
VIP,eth0:0 :172.16.8.200
# ipvsadm -C
# ifconfig eth0192.168.0.10/24 up
# ifconfig
# ipvsadm -A -t172.16.100.7:80 -s rr
# ipvsadm -a -t172.16.100.7:80 -r 192.168.0.11 -g -w 1
# ipvsadm -a -t172.16.100.7:80 -r 192.168.0.12 -g -w 3
# ipvsadm -Ln
浏覽器:172.16.100.7 進行通路;
======================================================================
DR類型RS腳本示例:
#!/bin/bash
#
vip=172.16.100.7
interface="lo:0"
case $1 in
start)
echo 1 >/proc/sys/net/ipv4/conf/all/arp_ignore
echo 1 >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 2 >/proc/sys/net/ipv4/conf/lo/arp_announce
ifconfig $interface $vipbroadcast $vip netmask 255.255.255.255 up
route add -host $vip dev$interface
;;
stop)
echo0 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 0 >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo 0 >/proc/sys/net/ipv4/conf/all/arp_announce
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
ifconfig $interface down
status)
if ifconfig lo:0 |grep $vip&> /dev/null; then
echo "ipvs isrunning."
else
echo "ipvs isstopped."
fi
*)
echo "Usage: `basename $0` {start|stop|status}"
exit 1
esac
=============================================================================
lvs的persistence: lvs持久連接配接
無論使用哪一種排程方法,持久連接配接功能都能保證在指定時間範圍之内,
來自于同一個IP的請求将始終被定向至同一個RS;
persistencetemplate:持久連接配接模闆
PPC:每端口持久,持久連接配接的生效範圍僅為單個叢集服務;如果有多個叢集服務,每服務 被單獨持久排程;
例:
#ipvsadm -A -t 172.16.100.7 -s rr –p [#]
-p:不管是什麼服務都被排程到同一個用戶端上; 預設時長360秒;
PCC:每用戶端持久;持久連接配接生效範圍為所有服務;定義叢集服務時,其TCP或UDP協定 的目标端口要使用0;
# ipvsadm -A -t172.16.100.7:0 -s rr -p
0:表示持久一個用戶端; 不管是什麼服務都被排程到同一個用戶端上;
PFWM:每FWM持久;持久連接配接生效範圍為定義為同一個FWM下的所有服務;