系列一文章簡述了LVS常見的五種工做模式,接下來主要講述LVS的工做原理
LVS負責四層均衡負載調度,當咱們要定義集羣的調度規則時須要藉助於一個管理工具,就是ipvsadm
。而ipvsadm
定義的規則最終是經過IPVS
來實現,也就是說ipvsadm
是IPVS
的管理工具,ipvsadm
工做於用戶空間,IPVS
工做於內核空間,二者之間的關係比如iptables與netfliter。html
IPVS
支持TCP/UDP協議,會從TCP SYNC包開始爲一個TCP鏈接全部的數據包創建狀態跟蹤機制,保證一個TCP鏈接中全部的數據包能到同一個後端。因此IPVS是基於TCP狀態機進行控制管理,只感知TCP頭而不對TCP的payload進行查看;所以,對IPVS後端服務器集羣還有一個假定,那就是全部後端都具備一樣的應用層的服務功能,可是因爲IPVS能夠給後端設定權重,因此每一個後端的服務的能力能夠不一樣。linux
`IPVS(IP Virtual Server)發展史:nginx
IPVS
就已經之內核補丁的形式出現。IPVS
軟件就是合併到linux內核的經常使用版本的內核補丁的集合。IPVS
已經成爲linux官方標準內核的一部分並做爲Netfilter的一個模塊存在
當Client訪問服務時,會訪問VIP及其對應的端口,因此LVS接收到的請求報文首先通過PREROUTING鏈而後進行路由判斷,因爲此時的DIP爲VIP,爲設備IP(網卡接口上有配置)因此請求報文會通過INPUT鏈,此時若是IPVS
發現報文訪問的VIP和端口與定義的規則相匹配,IPVS
會根據定義好的規則和算法將報文直接發往POSTROUTING鏈,最後報文會從LVS發出到達後端RS。算法
咱們以LVS的DR模式爲例,安裝好ipvsadm
後在調度機上執行如下命令後端
ipvsadm -A -t VIP:port -s rr ipvsadm -a -t VIP:port -r RIP1 -g ipvsadm -a -t VIP:port -r RIP2 -g //本案例中配置以下 //ipvsadm -A -t 192.168.0.100:80 -s rr //ipvsadm -a -t 192.168.0.100:80 -r 192.168.0.4 -g //ipvsadm -a -t 192.168.0.100:80 -r 192.168.0.5 -g
ipvsadm -A -t VIP:port -s rrcentos
-A 選項爲添加一條虛擬服務器記錄,即建立一個LVS集羣
-t 標識建立的LVS集羣服務爲tcp協議,VIP:port 標識集羣服務IP及端口號
-s Scheduling 調度之意,後面參數爲指定的調度算法,有rr、wrr、lc、wlc、lblc、lblcr、dh、sh、sed、nq,默認爲wlc,其中rr爲Round-Robin縮寫,表明輪詢算法
因此在建立好一個LVS服務集羣后,咱們須要設置具體的後端RS、調度算法等信息服務器
ipvsadm -a -t VIP:port -r RIP -g負載均衡
-a 選項表示添加一個RS到集羣中
-t 同上
-r 用於指定須要添加的RIP(RS對應IP)
-g 表示LVS工做模式爲DR模式,-i爲TUN模式,-m爲NAT模式curl
配置完後咱們經過 ipvsadm -Ln
查看生效的規則,但要注意一點,若是沒有提早將規則進行保存,在設備重啓後配置會消失,因此咱們配置完須要用 service ipvsadm save 保存命令,重啓後用 service ipvsadm reload
從新載入規則。除此以外,能夠用-S將LVS規則保存在指定文件中,經過-R進行重載tcp
ipvsadm -S > file ipvsadm -R < file
爲模擬集羣環境,咱們準備了四臺虛擬機分別爲客戶端、LVS服務器、RealServer一、RealServer2
首先配置LVS,在yum安裝ipvsadm
後,此時系統尚未把ipvs模塊加載進系統,須要咱們執行ipvsadm命令纔會加載進去或者modprobe ip_vs。
在配置完規則後,能夠經過 ipvsadm -ln 查看已經生效的集羣規則,固然爲了重啓繼續使用目前配置的規則,能夠-S 進行保存。
因爲VIP須要綁定在LVS的網卡上並進行ARP廣播(對於外部來講,VIP對應設備就是LVS,對應的arp請求只能由LVS響應),咱們添加VIP 192.168.0.100/24 到 ens33:0上。
[root@LVS ~]# yum install ipvsadm -y [root@LVS ~]# lsmod | grep ip_vs [root@LVS ~]# //此時ipvsadm未啓用 [root@LVS ~]# ipvsadm -A -t 192.168.0.100:80 -s rr [root@LVS ~]# ipvsadm -a -t 192.168.0.100:80 -r 192.168.0.4 -g [root@LVS ~]# ipvsadm -a -t 192.168.0.100:80 -r 192.168.0.5 -g [root@LVS ~]# lsmod | grep ip_vs ip_vs_rr 12600 1 ip_vs 145497 3 ip_vs_rr nf_conntrack 133095 7 ip_vs,nf_nat,nf_nat_ipv4,nf_nat_ipv6,xt_conntrack,nf_conntrack_ipv4,nf_conntrack_ipv6 libcrc32c 12644 4 xfs,ip_vs,nf_nat,nf_conntrack //ipvsadm已啓用 [root@LVS ~]# 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.0.100:80 rr -> 192.168.0.4:80 Route 1 0 0 -> 192.168.0.5:80 Route 1 0 0 //ipvsadm規則生效 [root@LVS ~]# ifconfig ens33:0 192.168.0.100/32 up
首先部署好http服務,這邊是採用nginx。因爲接收數據包的目的IP爲VIP,須要在lo上添加VIP,由於RS的VIP不是用來通信,這裏必定要設置/32位掩碼!
[root@RealServer1 ~]# rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm [root@RealServer1 ~]# yum install nginx -y [root@RealServer1 ~]# nginx //啓動nginx [root@RealServer1 ~]# vi /usr/share/nginx/html/index.html //改成 RealServer1 192.168.0.4 [root@RealServer1 ~]# curl 127.0.0.1 RealServer1 192.168.0.4 //至此部署好了http服務 [root@RealServer1 ~]# ifconfig lo:0 192.168.0.100/32 up //將VIP添加到lo:0上,掩碼爲/32
到這裏,會誤覺得都已配置徹底、集羣能夠正常服務,但在Client實際測試的時候會發現ARP詢問VIP時,LVS、RS一、RS2都會進行應答,致使均衡負載未生效。
[root@Client ~]# arping -I ens33 192.168.0.100 ARPING 192.168.0.100 from 192.168.0.3 ens33 Unicast reply from 192.168.0.100 [00:0C:29:AF:6B:F7] 1.778ms Unicast reply from 192.168.0.100 [00:0C:29:AC:67:31] 1.852ms Unicast reply from 192.168.0.100 [00:0C:29:BD:38:DA] 1.860ms Unicast reply from 192.168.0.100 [00:0C:29:BD:38:DA] 1.860ms Unicast reply from 192.168.0.100 [00:0C:29:BD:38:DA] 1.860ms //會發現有三個設備響應ARP請求,最終爲 00:0C:29:BD:38:DA(RS1) [root@Client ~]# arping -I ens33 192.168.0.2 ARPING 192.168.0.2 from 192.168.0.3 ens33 Unicast reply from 192.168.0.2 [00:0C:29:AF:6B:F7] 1.500ms [root@Client ~]# arping -I ens33 192.168.0.4 ARPING 192.168.0.4 from 192.168.0.3 ens33 Unicast reply from 192.168.0.4 [00:0C:29:BD:38:DA] 1.609ms [root@Client ~]# arping -I ens33 192.168.0.5 ARPING 192.168.0.5 from 192.168.0.3 ens33 Unicast reply from 192.168.0.5 [00:0C:29:AC:67:31] 1.603ms //三臺設備分別爲LVS、RS一、RS2
由於RS的lo上已配置VIP,因爲arp_ignore
默認爲0,設備默會響應VIP對應的ARP請求。配置說明參考 Linux內核參數之arp_ignore和arp_announce
arp_ignore
arp_ignore
參數要求配置爲1。arp_announce
arp_announce
參數要求配置爲2。[root@RealServer1 ~]# echo "1">/proc/sys/net/ipv4/conf/all/arp_ignore [root@RealServer1 ~]# echo "1">/proc/sys/net/ipv4/conf/lo/arp_ignore [root@RealServer1 ~]# echo "2">/proc/sys/net/ipv4/conf/all/arp_announce [root@RealServer1 ~]# echo "2">/proc/sys/net/ipv4/conf/lo/arp_announce
配置完RealServer一、RealServer2的arp_ignore
、arp_announce
後,在Client上測試服務
[root@Client ~]# arping -I ens33 192.168.0.100 ARPING 192.168.0.100 from 192.168.0.3 ens33 Unicast reply from 192.168.0.100 [00:0C:29:AF:6B:F7] 1.301ms Unicast reply from 192.168.0.100 [00:0C:29:AF:6B:F7] 0.827ms Unicast reply from 192.168.0.100 [00:0C:29:AF:6B:F7] 0.887ms Unicast reply from 192.168.0.100 [00:0C:29:AF:6B:F7] 0.801ms //由LVS響應ARP請求 [root@Client ~]# curl 192.168.0.100 RealServer2 192.168.0.5 [root@Client ~]# curl 192.168.0.100 RealServer1 192.168.0.4 [root@Client ~]# curl 192.168.0.100 RealServer2 192.168.0.5 [root@Client ~]# curl 192.168.0.100 RealServer1 192.168.0.4 //由RealServer一、RealServer2 1:1 輪詢響應請求
至此咱們手動配置好了一個最基礎的DR-LVS集羣,但缺點也很明顯:
因此後續介紹keepalived-LVS集羣來解決上述問題
參考文章
LVS 官方文檔
ipvsadm命令詳解
LVS的調度算法
Linux內核參數之arp_ignore和arp_announce