why LVS
說到LVS,不得不說起F5柴淘。F5的LTM(本地流量管理器)在部署上蛔外、負載均衡原理上類似,但是也有十分大的區(qū)別也物,之前暑期實習的時候稍微接觸過F5的設備,不得不說其是一款十分優(yōu)秀的設備列疗,強悍的負載均衡能力滑蚯,人性化的界面、加上自身攜帶的Irules也是大大增加了其靈活性(就像是lua給nginx插上了飛翔的翅膀)作彤,他的代名詞是不僅僅是負載均衡膘魄,強大SSL卸載芯片,HTTP優(yōu)化竭讳、連接復用创葡、抗DDoS特性等等,再加上和GTM(廣域網流量管理器)的聯(lián)動绢慢,使得在其在同城雙活或者兩地三中心建設領域大放異彩灿渴,你,值得擁有~
然而好貨不便宜胰舆,它的價格昂貴讓許多企業(yè)望而卻步骚露。單單一臺LTM設備加license就是6位數(shù),這也讓一些企業(yè)開始擁抱開源缚窿,尋找免費的負載均衡產品棘幸,如今的開源文化已經十分繁榮,如本文介紹的LVS倦零,當然還有Nginx误续,Haproxy等等,都是很好的開源軟件扫茅,他們都有各自的應用領域和特點蹋嵌。(有時間會另說)
LVS和其他負載均衡產品相比有它自己的特點,它是一個純4層設備葫隙,仿佛就是一個四層的交換機栽烂,由于它不需要對應用層報文進行處理,不涉及代理工作(只考慮原生的lvs)恋脚,所以它的性能非常好腺办,得以廣泛應用,再加上自身就是開源的作品糟描,很方便給有研發(fā)能力互聯(lián)網企業(yè)足夠的空間來施展拳腳菇晃。如阿里他們開源的LVS-FULLNAT,給LVS增添了很多新的特性
LVS簡介
LVS(Linux Virtual Server)是一款優(yōu)秀的負載均衡軟件蚓挤,一般用于具備完善運維能力的互聯(lián)網企業(yè),為業(yè)務主機實現(xiàn)應用負載均衡一種技術,實現(xiàn)后端服務器壓力分擔、scale out的一種方式灿意。
LVS將多臺提供相同服務功能的server組成服務器池估灿,每次請求的時候根據(jù)負載均衡算法挑選出相對壓力較小或更適合被請求的服務器發(fā)送請求。我們一般稱這個節(jié)點為其為load balancer缤剧。其作者就是大明鼎鼎 chinese man
淘寶正明(現(xiàn)應叫DiDi正明~)章文嵩博士馅袁,它是一款四層的負載均衡軟件,表明其性能強悍荒辕,其已經被整合到linux內核內汗销;但是它無法對數(shù)據(jù)包進行更加詳細的分析,從負載均衡上說存在缺陷抵窒。
組成
LVS主要分為ipvsadm和IPVS弛针。ipvsadm是管理集群服務的命令行工具,工作在用戶空間李皇;而IPVS則是工作在INPUT鏈上的內核模塊削茁。在使用傳統(tǒng)的LVS時,只需安裝ipvsadm即可掉房,2.6后IPVS的代碼在內核中已經被編譯好茧跋,無需打補丁即可使用。安裝前建議查看kernel版本或直接查看內核是否支持:modprobe -l | grep ipvs
結構
- DS:director server卓囚,即負載均衡器瘾杭,根據(jù)一定的負載均衡算法將流量分發(fā)到后端的真實服務器上
- RS:Real server 真實的提供服務的server,可被DR劃分到一個或多個負載均衡組哪亿。
- BDS:backup director server粥烁,為了保證負載均衡器的高可用衍生出的備份
- VS:vitual server,負載均衡集群對外提供的IP+Port
- VIP:VS的IP锣夹,client請求服務的DIP(destination IP address)页徐,在DR上,client或其網關需要有其路由
原理
ipvs基于netfilter框架银萍,netfilter的架構就是在整個網絡流程的若干位置放置了一些檢測點(HOOK)变勇,而在每個檢測點上登記了一些處理函數(shù)進行處理(如包過濾,NAT等贴唇,甚至可以是用戶自定義的功能)搀绣。IPVS就是定義了一系列的“鉤子函數(shù)”,在INPUT鏈和Forward上放置一些HOOK點戳气,如匹配了ipvs的規(guī)則链患,就會通過函數(shù)來對數(shù)據(jù)包進行操作,比如修改目的IP為realserver的接口IP(NAT)瓶您,對MAC進行修改(DR)等等麻捻。
負載均衡算法
- RR:輪詢
- WRR:給后臺real server根據(jù)性能比例設定權重纲仍,根據(jù)權重進行輪詢
- SH:source hash 根據(jù)SIP進行哈希,生成hash表贸毕,收到結果根據(jù)sip進行哈希并和hash表進行比對郑叠。
- DH:destination hash 對同一個資源的請求發(fā)往同一臺服務器,常用于緩存服務器的場景
- LC:最少連接數(shù)明棍,計算當前后端server的活動連接數(shù)*256+非活動連接數(shù)乡革,最小的server被調度接受請求
- WLC:加權最少連接,(后端server的活動連接數(shù)*256+非活動連接數(shù))/weight摊腋,最小的server被調度接受請求
- Sed:最短期望延遲沸版,(active+1)*256/weight
- NQ:never queue
- LBLC:基于本地的最少連接,動態(tài)的DH
- LBLCR:基于本地的帶復制功能的最少連接
集群部署
NAT(DNAT)
原理:顧名思義兴蒸,進出的數(shù)據(jù)報文都需要經過director视粮,client請求報文請求VIP和對應的端口號時director根據(jù)負載均衡算法選出接受請求的Real server,并將DIP和Dport更換成real server的ip和監(jiān)聽端口类咧÷澹回包時需保證回復報文經過director,將其SIP和SPort替換為Virtual server的IP和port
(類似于F5 LTM的路由模式)
RS上的配置
在RS1痕惋,RS2上安裝httpd用于測試区宇,RS1上(RS2上類似RS1):
yum install -y httpd
echo 'Real server1' > /var/www/html/index.html
service httpd restart
iptables -F
DR上的配置
echo 1 > /proc/sys/net/ipv4/ip_forward #打開路由轉發(fā)功能
ipvsadm -C #清空ipvs的配置
ipvsadm -At 172.16.130.1:8080 -s wrr #添加VS,調度算法為wrr
ipvsadm -at 172.16.130.1:8080 -r 192.168.162.101:80 -m -w 3 #給VS指定realserver 權重為3
ipvsadm -at 172.16.130.1:8080 -r 192.168.162.100:80 -m -w 1
ipvsadm -L -n #查看ipvs的配置
ipvsadm -S > ipvs.conf #保存ipvs為一個配置文件ipvs.conf
ipvsadm -R < ipvs.conf #讀取配置文件
最后兩條在實驗的時候可以方便調試值戳,也可以將前面的幾條柔和成一個腳本運行
zhxfei@zhxfei-HP-ENVY-15-Notebook-PC:~$ sudo ./lvs.sh
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.130.1:8080 wrr
-> 192.168.162.100:80 Masq 1 0 0
-> 192.168.162.101:80 Masq 3 0 0
驗證
[root@localhost ~]# curl 172.16.130.1:8080
realserver1
[root@localhost ~]# curl 172.16.130.1:8080
realserver2
優(yōu)點:可以做端口映射议谷,如向外提供的端口和real server的服務端口可以不一樣;Realserver可使用任意操作系統(tǒng)
缺點:請求分發(fā)器存在屏頂;保證回包的流量經過director將SIP和Sport轉換(Real server一般將網關指向DIP)
DR(direct routing)
原理:流量三角走向,即client的請求報文路由到director的VIP接口堕虹,director根據(jù)負載均衡算法選出接受請求的real server后卧晓,將目的MAC轉換為real server的接口MAC(和VIP所在同一網段)。在realserver收到報文回復請求后赴捞,直接回復給客戶端逼裆,源地址為realserver的VIP接口(一般配置為環(huán)回口)。為實現(xiàn)以上赦政,請求報文到達director和realserver所在網關時胜宇,網關arp請求時應保證只有director會響應對VIP的ARP請求,real server對arp請求應保持靜默恢着。且為了保證real server響應報文的SIP為VIP桐愉,realserver需要配置接口地址和VIP相同。且回復時掰派,二層的SMAC應該保證為RIP接口的MAC地址从诲,不能為VIP接口的MAC地址,防止GW緩存VIP的mac在Realserver上靡羡,導致發(fā)包直接發(fā)到realserver系洛。(類似于LTM的n-path組網俊性,由于F5是基于TMOS全代理架構,所以需要保證來回路徑一致碎罚,現(xiàn)在基本不使用)
arp ignore
為了實現(xiàn)client的請求報文到達server所在的GW(Gateway)上磅废,廣播ARP請求時,只有LVS會回復其ARP請求荆烈,realserver不會回復,需要修改后臺服務器上的arp_ignore內核參數(shù)竟趾。
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
arp_announce
為了保證server將報文直接回復給client而不經過LVS憔购,我們需要在realserver上配置一個VIP接口來作為回復報文的源地址。但是接受報文的接口是VIP接口岔帽,我們回復的時候需要將realserver的VIP接口的MAC地址隱藏起來不作為恢復報文的源MAC地址玫鸟,防止GW上的MAC地址表動蕩。此時需要更改個內核參數(shù)犀勒,配置echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
,忽略源ip而使用本地路由的最佳出站接口的ip地址
架構如圖:
部署見下面的keepalived+LVS
優(yōu)點:直接路由屎飘,性能最好(只處理請求報文(很小)贾费,響應報文(很大)無需經過DR直接發(fā)往客戶端)
缺點:不支持端口映射钦购;大多數(shù)的操作系統(tǒng)支持realserver(realserver需要隱藏VIP);集群節(jié)點即realserver需要和director在一個網段中
TUN(ip tunnel)
Director收到DIP為VIP的報文褂萧,在IP包頭外再封裝一個IP頭部押桃,源為DIP和目的為RIP,協(xié)議號為4导犹,表示IPIP封裝唱凯。Realserver收到報文后拆開外層頭后發(fā)現(xiàn)是IPIP封裝繼續(xù)拆內部的三層頭,源IP為client目的IP為TUNL0即為本地接口地址谎痢,繼續(xù)拆解數(shù)據(jù)包磕昼,回包后即根據(jù)內部數(shù)據(jù)包的yuanIP直接路由回到client
優(yōu)點無需經過director路由,且realserver沒有地理位置的限制节猿,可以在不同的網段
缺點對realserver的系統(tǒng)有要求票从,linux和BSD系列的支持ipip tunl。
拓撲如下:
MTU問題::在ip_vs模塊中沐批,有相關MTU檢測的內容纫骑,當DF
標志位為1
,且len
超過MTU時九孩,會發(fā)送ICMP_FRAG_NEEDED
如果lvs的vs收到的數(shù)據(jù)以太網幀已經超過1.5K即接口MTU先馆,則LVS會回復一個icmp報文給客戶,如果客戶端支持路徑MTU(PMTU)躺彬,會把后續(xù)的報文調小于MTU煤墙。再把后面的交換機的mtu調大梅惯。或者在server端設置較小的MSS仿野。如可以使用iptables 來進行調整:
iptables -A FORWARD -p tcp -m tcpmss -j TCPMSS --class-mss-to-pmtu
铣减。可以關注/proc/sys/net/ipv4/ip_forward_use_pmtu
這個kernel參數(shù)
由于在LVS收到分片的報文之后網卡會交由協(xié)議棧需要將報文重組脚作,這樣會帶來一定的延時葫哗,此時可以在LVS上考慮使用ethtool
使用網卡對數(shù)據(jù)合并,而協(xié)議棧不需要對報文進行重組:
DS上的ipvs的配置文件:
[root@localhost ~]# cat ipvs.conf
-A -t 192.168.162.80:http -s rr
-a -t 192.168.162.80:http -r 192.168.100.50:http -i -w 1
-a -t 192.168.162.80:http -r 192.168.130.50:http -i -w 1
[root@localhost ~]# ipvsadm -R < ipvs.conf
[root@localhost ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.162.80:80 rr
-> 192.168.100.50:80 Tunnel 1 0 0
-> 192.168.130.50:80 Tunnel 1 0 0
[root@localhost ~]# ip addr add 192.168.162.80/32 dev eth0:1
RS上的配置腳本:
# description: RealServer's script # 關于腳本的簡短描述
# processname: realserver.sh # 第一個進程名球涛,后邊設置自動時會用到
# !/bin/bash
VIP=192.168.162.80
case "$1" in
start)
ifconfig tunl0 $VIP netmask 255.255.255.255 broadcast $VIP up
/sbin/route add -host $VIP dev tunl0
echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
echo "0" > /proc/sys/net/ipv4/conf/tunl0/rp_filter
echo "RealServer Start OK"
;;
stop)
ifconfig tunl0 down
route del $VIP >/dev/null 2>&1
echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce
echo "1" > /proc/sys/net/ipv4/conf/tunl0/rp_filter
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
esac
iptables -F
setenforce 0
exit 0
rp_filter
注意:echo "0" > /proc/sys/net/ipv4/conf/tunl0/rp_filter
是將RPF反向路徑檢查關閉劣针,其原本是為了防止DDoS攻擊偽造的IP源數(shù)據(jù)包在公網上穿行,將收到的報文的SIP作為目的IP查找路由表亿扁,將結果的出接口和收到報文的接口相比對捺典,將不一致的報文丟棄。如果其從eth0收到了VIP的數(shù)據(jù)包查找路由表會優(yōu)先匹配本地接口TUNL0从祝,出接口不一致會導致kernel將數(shù)據(jù)包丟棄襟己。
抓包
request:
reply:
keepalived+LVS
簡介
keepalived被成為LVS的黃金搭檔,其原先是負責了為負載均衡組內的realserver的健康檢查牍陌,將出現(xiàn)故障的realserver從負載均衡組中剔除擎浴,而當服務器恢復正常,再加入到負載均衡組呐赡。
后來加入了可以防止LVS單點故障的特性退客,基于VRRP協(xié)議為LVS節(jié)點保證了HA。
在keepalived啟動后會有三個進程
父進程:內存管理链嘀,子進程管理等等
子進程:VRRP子進程
子進程:healthchecker子進程萌狂,檢查各自服務器的健康狀態(tài)
Aug 5 08:01:49 localhost Keepalived[7233]: Starting Keepalived v1.2.19 (08/03,2016)
Aug 5 08:01:49 localhost Keepalived[7234]: Starting Healthcheck child process, pid=7236
Aug 5 08:01:49 localhost Keepalived[7234]: Starting VRRP child process, pid=7237
使用keepalived來構建高可用LVS的話,可以不用在LVS上使用ipvsadm來配置VIP怀泊,LB策略等等茫藏,直接使用keepalived配置模板拉取配置相關信息,注意關閉iptables和selinux
安裝
從keepalived官網上下載之本地霹琼,解壓并安裝:
tar -xvf keepalived-1.2.19.tar.gz
cd keepalived-1.2.19
./configure --sysconf=/etc --with-kernel-dir=/usr/src/kernels/`uname -r` #--with-kernel-dir表明使用內核源碼中的頭文件务傲,只有使用LVS時才會用到此文件
make && make install
ln -s /usr/local/sbin/keepalived /sbin/
keepalived -v #查看安裝版本
DS和BDS配置(基于DR模式)
配置模板(DS MASTER):
[root@localhost ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
root@localhost
}
notification_email_from admin@localdomain
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_DEVEL #顯示在郵件中
}
vrrp_instance VI_1 {
state MASTER !VRRP啟動時候的狀態(tài)
interface eth0 !指定監(jiān)視HA的接口
virtual_router_id 51 !虛擬路由器組的id號,在LVS中可以理解為負載均衡組的id號枣申,master和backup需要相同
priority 100 !優(yōu)先級售葡,越大越優(yōu)先(0沒有選舉資格,255為固定MASTER)
advert_int 1 !默認為1忠藤,表示1s發(fā)一次
authentication {
auth_type PASS !明文驗證挟伙,還支持MD5
auth_pass 1111
}
virtual_ipaddress {
192.168.162.80 !定義VIP
}
}
virtual_server 192.168.162.80 80 {
delay_loop 6 !運行狀況檢查時間
lb_algo rr !調度算法
lb_kind DR !負載均衡機制
persistence_timeout 1 !會話保持時間1s,在1s內,統(tǒng)一用戶的會話會調度到一臺機器上
protocol TCP
real_server 192.168.162.100 80 {
weight 1
HTTP_GET { !基于http get的健康檢查
url {
path /
status_code 200 !狀態(tài)碼200即正常
}
connect_timeout 3 !超時時間3S
nb_get_retry 3 !嘗試3次
delay_before_retry 3 !retry間隔3s
}
}
real_server 192.168.162.101 80 {
weight 1
HTTP_GET {
url {
path /
status_code 200
}
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
}
}
}
BDS BACKUP:
直接scp root@192.168.162.102:/etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf
之后
修改state和priority即可
開啟keepalived: service keepalived start
當開啟后模孩,client去訪問VIP的80端口尖阔,LVS DS會選出一臺realserver贮缅,當client在回話保持設置的超時時間內都會被調度到一臺realserver上。
(PS:實驗一直以為自己失敗了介却,明明設置了RR谴供,但是卻訪問的是一臺服務器_!)
RS配置
提供配置腳本:
[root@localhost ~]# cat realserver.sh
#/bin/bash
#
# description: RealServer's script # 關于腳本的簡短描述
# processname: realserver.sh # 第一個進程名,后邊設置自動時會用到
# !/bin/bash
VIP=192.168.162.80
case "$1" in
start)
ifconfig lo:0 $VIP netmask 255.255.255.255 broadcast $VIP
/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
echo "RealServer Start OK"
;;
stop)
ifconfig lo:0 down
route del $VIP >/dev/null 2>&1
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 "RealServer Stoped"
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
esac
iptables -F
setenforce 0
exit 0
VRRP
選舉
通過優(yōu)先級選舉齿坷,越大越優(yōu)先桂肌,相同即比較IP地址,priority為0沒有選舉資格胃夏,255為MASTER VIP的擁有者
優(yōu)先級相同比較IP地址越大越優(yōu)先成為MASTER
搶占和非搶占
BACKUP收到MASTER發(fā)來的通告報文中攜帶的優(yōu)先級比自己低就會搶占MASTER并向外發(fā)送VRRP通告報文(相同不會搶占)轴或,如果原MASTER比原BACKUP的優(yōu)先級低收到通告報文則會變?yōu)锽ACKUP
如果原BACKUP工作在非搶占模式下,只要MASTER出現(xiàn)故障仰禀,BACKUP即使優(yōu)先級更低也不會成為MASTER路由器
默認是搶占模式(搶占只比較優(yōu)先級不比較IP地址,即優(yōu)先級相同就不會搶占)
healthcheck
重啟后臺realserver httpd服務
Aug 5 08:43:23 localhost Keepalived_healthcheckers[7689]: Error connecting server [192.168.162.101]:80.
Aug 5 08:43:23 localhost Keepalived_healthcheckers[7689]: Removing service [192.168.162.101]:80 from VS [192.168.162.80]:80
Aug 5 08:43:23 localhost Keepalived_healthcheckers[7689]: Remote SMTP server [127.0.0.1]:25 connected.
Aug 5 08:43:23 localhost Keepalived_healthcheckers[7689]: SMTP alert successfully sent.
Aug 5 08:43:50 localhost Keepalived_healthcheckers[7689]: HTTP status code success to [192.168.162.101]:80 url(1).
Aug 5 08:43:56 localhost Keepalived_healthcheckers[7689]: Remote Web server [192.168.162.101]:80 succeed on service.
Aug 5 08:43:56 localhost Keepalived_healthcheckers[7689]: Adding service [192.168.162.101]:80 to VS [192.168.162.80]:80
Aug 5 08:43:56 localhost Keepalived_healthcheckers[7689]: Remote SMTP server [127.0.0.1]:25 connected.
Aug 5 08:43:56 localhost Keepalived_healthcheckers[7689]: SMTP alert successfully sent.
failover測試
在client使用webbench進行故障倒換壓測蚕愤,期間答恶,在DS上使用iptable將VRRP通告DROP:iptables -A OUTPUT -d 224.0.0.18 -j DROP
可以看到BDS上的VIP迅速浮上來:
[root@localhost webbench-1.5]# ./webbench -c 10000 -t 20 http://192.168.162.80:/index.html
Webbench - Simple Web Benchmark 1.5
Copyright (c) Radim Kolar 1997-2004, GPL Open Source Software.
Benchmarking: GET http://192.168.162.80:/index.html
10000 clients, running 20 sec.
Speed=3060 pages/min, 14122 bytes/sec.
Requests: 1016 susceed, 4 failed.
看到BDS上的日志
Aug 5 07:35:50 localhost Keepalived_vrrp[6905]: VRRP_Instance(VI_1) Transition to MASTER STATE
Aug 5 07:35:51 localhost Keepalived_vrrp[6905]: VRRP_Instance(VI_1) Entering MASTER STATE
Aug 5 07:35:51 localhost Keepalived_vrrp[6905]: VRRP_Instance(VI_1) setting protocol VIPs.
Aug 5 07:35:51 localhost Keepalived_healthcheckers[6904]: Netlink reflector reports IP 192.168.162.80 added
Aug 5 07:35:51 localhost Keepalived_vrrp[6905]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth4 for 192.168.162.80
Aug 5 07:35:56 localhost Keepalived_vrrp[6905]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth4 for 192.168.162.80
我們可以看到,當BACKUP成為MASTER的時候萍诱,發(fā)送了gratuitous ARPs(免費ARP)用于刷新GW的MAC地址表項悬嗓,表示BACKUP接手VIP的arp響應
此時原本的MASTER收到原BACKUP的通告消息(只有MASTER才會發(fā)送VRRP通告報文),也會重復發(fā)送通告報文和免費ARP信息告訴BACKUP“我才是MASTER裕坊!”并刷新GW的MAC地址表:
Aug 5 07:59:00 localhost Keepalived_vrrp[7060]: VRRP_Instance(VI_1) Received lower prio advert, forcing new election
Aug 5 07:59:00 localhost Keepalived_vrrp[7060]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.162.80
若心跳報文(Master發(fā)送的通告報文)被阻止或者丟棄沒有被Slave上的VRRP程序接受包竹,則LVS會產生腦裂,GW上的MAC地址表可能會產生動蕩籍凝,即MAC地址漂移,所以一般專業(yè)的設備都會有專門的心跳電纜互聯(lián)