LVS 詳解及使用


1,LVS介紹:

LVS是Linux Virtual Server的縮寫,翻譯過來的話,是linux 虛擬服務器,但是這個虛擬機沒什么關系,他是用作負載均衡,軟負載的解決方案之一,既然有"軟件方案",那么肯定有對應的"硬件方案",但是,硬件方案所需的成本比較高,我們需要購買特定的負載均衡硬件設備,以達到負載均衡的目的,比較知名的負載均衡硬件設備廠商有F5、Citrix等,但是硬件方案並不是此處討論的重點,我們了解即可。而能夠實現負載均衡之目的軟件也不只有LVS一種,我們也可以通過nginx、haproxy等軟件實現負載均衡的目的。

2,LVS 負載均衡模式

LVS 負載均衡有三種模式可供選擇,下面我們來了解一下這三個模式的原理:

1)NAT(網絡地址轉換)模式(生產環境幾乎不用):

NAT(Network Address Translation)是一種外網和內網地址映射的技術。每台Real Server的網關將是LVS服務器的地址,用戶請求的數據進出都要經過LVS(所以它容易成為瓶頸)。當LVS服務器收到用戶請求時會進行目標地址轉換(DNAT),將請求IP修改為后端Real Server的IP,此時客戶端IP不變,目標IP是VIP。Real Server響應用戶請求時,需要再讓LVS做源地址轉換(SNAT),將返回的數據包源地址改為VIP。此時目標IP是客戶端IP,而源IP是VIP,可以正常響應客戶端請求。而對客戶端來說仿佛是LVS進行的響應,無法感知到后端Real Server的存在。

 

 

 

 

如上圖所示,客戶端的請求會發往LVS主機,此時,客戶端請求報文的源IP為CIP,目標IP為LVS的VIP,當LVS收到客戶端的請求報文時,會將請求報文中的目標IP修改為后端某個RealServer的RIP,就以上圖為例,當LVS收到客戶端的請求報文時,會將報文中的VIP修改為RIP1或者RIP2,具體將VIP修改為哪個RealServer的RIP,取決於LVS使用的具體算法,最好理解的負載均衡算法就是輪詢算法了,用大白話說,輪詢算法就是如果這次將報文的目標IP修改為RIP1,那么下次就將目標IP修改為RIP2,再下次就再將目標IP修改為RIP1,以此類推,當然,除了輪詢算法,還有很多別的算法可供我們選擇,但是此處我們暫時先不考慮這么多,當客戶端請求報文的目標IP被修改為對應的RIP后,請求報文的源IP為CIP,目標IP已經改為RIP,那么報文自然會被LVS轉發到對應的RealServer中,當RealServer收到對應的請求報文時,會發現報文的目標IP就是自己的RIP,於是就會接收報文,處理后進行響應,因為RealServer收到請求報文時,源IP為CIP,目標IP為RIP,所以RealServer在進行響應時,響應報文的源IP則為RIP,目標IP則為CIP,但是CIP對於RealServer來說肯定不在一個網絡內,因為CIP是一個公網IP,所以,我們要將所有RealServer的網關指向DIP,當RealServer產生響應報文時,會將響應報文發往網關DIP,而DIP就是LVS的內網IP,當LVS收到對應的響應報文時,響應報文的源IP為RIP,目標IP為CIP,此時,LVS會將響應報文的源IP修改為VIP,修改后的響應報文的源IP為VIP,目標IP為CIP,於是響應報文被發往客戶端,客戶端則會收到響應報文,其實上述整個過程是一個DNAT的過程,所以,此種LVS模型被稱之為LVS-NAT模型。

NAT模式的集群節點需要跟director在同一網絡;RIP通常是私有地址,僅用於各集群節點間的通信;RealServer的網關應該指向DIP;支持端口映射(轉發);用戶發起的請求由調度器向Real Server提交,Real Server再把數據經過調度器傳給用戶。相比DR模式的話,這樣安全性高,但是效率低,瓶頸會出現在調度器上,生產環境幾乎不用。

 

2)DR(直接路由)模式(生產環境中使用最多的):

客戶端請求依然由LVS接受,但是最終數據包由Real Server傳輸給用戶,不再經過LVS轉發,避免了NAT模式的瓶頸問題。DR模式的工作過程比較復雜:

當用戶發起請求時,源地址是客戶端IP,目標地址是VIP;而LVS調度器將請求轉發給Real Server處理后再發送給用戶,這個時候源IP是RIP,目標地址是客戶端IP,但是客戶端一開始並沒有請求RIP,而用RIP去響應請求時CIP是不會接受的,所以就需要用VIP響應請求。在DR模式下LVS和Real server都需要配備一樣的VIP(VIP的MAC地址和物理網卡是一樣的)(Real Server通過將VIP綁定在loopback實現)。由於一個網段內多台服務器出現同樣IP地址會引起沖突,所以要在LVS服務器上設置一個VIP一個DIP,而每個Real Server也有一個RIP和一個VIP,並且將Real Server的VIP地址做了隱藏和ARP抑制,不會應答廣播,只在響應CIP時作為源地址使用。當產生請求時LVS將目標MAC地址修改為某台Real Server的MAC,該包就會被轉發到相應的Real Server處理,此時源IP和目標IP都沒變。Real Server收到LVS轉發來的包時發現MAC是自己的,IP也是自己的,於是這個包被合法地接受。當Real Server返回響應時,只要直接向CIP返回即可,不再經過LVS。 

 

 RealServer推薦使用公網IP;RealServer的網關地址不能指向DIP;RealServer和調度器需要在同個物理網絡(同個機房),DIP和RIP應該在同一網段;入站數據經過調度器轉發到RealServer,出站數據由RealServer直接發給客戶端,不再經過調度器;不能做端口轉發。

 

3)TUN隧道模式:

也叫作隧道模式,構建和DR模式一樣,相比DR模式服務器間可以不在同一個網絡,可以實現異地傳輸,但是RealServer需要支持隧道功能。

這個模式比較少用,所以暫時忽略,以后有用到了再加上。

3,LVS的安裝及常用操作:

1)安裝:

LVS由兩部分組成,ipvs與ipvsadm

ipvs是與netfilter結合在一起使用的,2.4.X版本以后的內核中,ipvs作為netfilter的模塊存在。

ipvsadm是ipvs的管理工具,相當於iptables 和 netfilter關系一樣。

既然上面講過ipvs已經作為linux內核的一部分,我們直接安裝管理工具即可對ipvs規則的操作,下面是安裝方式:

最簡單的方式就是yum 安裝:

直接運行下面的命令即可完成安裝:

yum install ipvsadm -y

完成后我們可以使用一下命令嘗試查看是否安裝成功和查看是否有規則已經存在:

ipvsadm -ln
[root@nginxhost ~]# 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.56.135:9999 rr
  -> 192.168.71.3:8601            Masq    1      0          0         
  -> 192.168.71.3:8602            Masq    1      0          0         
[root@nginxhost ~]# 

我這里已經有了 規則,但是你的里面不一定有。只要出現server version的字樣表名安裝成功可以使用了。

源碼安裝請參考:http://www.linuxe.cn/post-192.html

2)保存規則及恢復規則

添加完規則后,重啟服務器后,這些規則就會消失,怎么能讓他們永久存在呢,下面我們來介紹小保存規則的命令:

centos6使用下面的命令:

service ipvsadm save  # 此命令會將規則保存在/etc/sysconfig/ipvsadm文件中

重啟后可以使用下面命令重新加載使之重新生效:

service ipvsadm reload

除了使用上述方法,還能夠使用如下方法,將LVS規則保存於指定的文件中,比如保存LVS規則到 /testdir/lvsrules文件中。

ipvsadm -S > /testdir/lvsrules

重載:

ipvsadm -R < /testdir/lvsrules

centos7可以使用 -S -R 的辦法來保存規則和重載規則

3)命令選項解釋

-A:增加LVS的VIP記錄
-a:增加real server記錄
-E:修改LVS記錄
-e:修改real server列表信息
-D:刪除一條LVS記錄
-d:刪除real server列表信息
-R:恢復虛擬服務器規則
-S:保存虛擬服務器規則,或者server  ipvsadm  save,和iptables一樣
ipvsadm -Sn > /root/lvsrules.txt  #保存規則
cat /root/lvsrules.txt | ipvsadm -R  #恢復規則
-C:清除虛擬服務器列表所有記錄
-L:顯示列表信息,和iptables一樣
-t | u:指定LVS提供tcp或者是udp服務,后面常跟選項 real-server-ip:port或者virtual-server-ip:port
-s:指定LVS的負載調度算法,后面接詳細的調度算法,如-s  rr | wrr | lc | wlc,不指定的話默認是wlc
-p  [timeout]:指定一個服務持續時間,用於會話保持,當同個用戶重復請求時,給同一個real server處理,默認是300秒
-r:指定real server的ip地址
-i:LVS工作在隧道模式下
-m:LVS工作在NAT模式下
-g:LVS工作在DR模式下
-w:指定real server的權重
-n:不進行dns解析

 

4,調度算法:

大方向上分為動態和靜態兩種調度算法,靜態算法是當用戶連接進來后,按設置的算法進行處理,不會判斷后端服務器的繁忙情況,而動態算法則會判斷后端服務器繁忙狀態,然后酌情調度

1)、靜態算法詳細分類
輪詢調度(RR):輪流分配請求,不管服務器繁忙程度
加權輪詢(WRR):后端服務器配置越好,分配到的請求越多,權重設置比較敏感。如A、B兩台服務器,A的權重為1,B的為10,那么當B要處理了10個用戶請求后才會分配讓A處理一個
目標地址散列(DH):同一IP過來的請求永遠分配給同一個Real Server,這樣可以利用緩存加速

源地址散列(SH)

2)、動態算法詳細分類:
最小連接(LC):當客戶端發起請求時調度器會計算后端服務器的開銷,將請求轉發給開銷小的服務器。計算公式:活動鏈接數x256+非活動連接數
加權最小連接(WLC):默認算法,也是使用最多的算法,計算公式:(活動鏈接數x256)/權重+非活動連接數
還有其他的一些補充算法,如最短期望延遲(SED)、最小隊列調度(NQ)、基於局部的最小連接(LBLC)、帶復制的基於局域的最小連接(LBLCR),可以網上查詢具體含義。

5,地址類型說明

VIP:虛擬IP,並不是提供真實服務的IP,而是通過這個IP轉發到后方

DIP:LVS服務器本身的IP,通過這個IP和RIP連接,DIP通常和Real Server的IP在一個網段

RIP:真實服務器的IP地址

CIP:客戶端請求時用戶的IP

6,ipvs在netfilter中所處的位置

 

 當客戶端訪問服務時,會訪問VIP+端口,所以,客戶端的請求報文會發往調度器,請求報文會先經過PREROUTING鏈,然后進行路由判斷,由於此刻報文的目標IP為VIP,而VIP對於調度器來說,就是本身的IP,所以報文會經過INPUT鏈,此刻,如果IPVS發現報文訪問的VIP+端口與我們定義的LVS集群規則相符,ipvs則會根據定義好的規則與算法,將報文直接發往POSTROUTING鏈,然后報文則會發出,最后到達后端的RealServer中。

6,NAT和DR模式實驗:

NAT實驗:

實驗環境准備:

CIP 192.168.0.142

VIP 192.168.56.135

DIP 192.168.71.4

RIP 192.168.71.3

其VIP和DIP是在一台機器上的不同網卡,71.0 網段的都屬於內網,我這里沒有公網地址,所以就用兩個處於不同網段的機器扮演lvs server和real server, 其中lvs server 包含兩張網卡,地址分別是VIP 和 DIP,CIP是我的物理機的局域網ip地址,lvs server和 real server 都是vbox虛擬主機,並且都是host-only模式的 

路由配置:

lvs server 一開始就可以ping 通 real server, 所以這里不需要配置,

real server 一開始不能ping通 lvs 的192.168.56.135  這個IP地址,所以我們需要添加一個路由條目

route add -host 192.168.56.135 gw 192.168.71.4

這樣再次ping 192.168.56.135時就能ping通了,其中我們得提前關閉lvs server 和real server的防火牆 和開啟lvs  server 內核的地址轉發功能。

sysctl -w net.ipv4.ip_forward=1

現在准備工作已經做完了,開始添加lvs規則;

我在real server上起了兩個springboot 服務端口號分別是8601,8602

ipvsadm -A -t 192.168.56.135:9999 -s rr
ipvsadm -a -t 192.168.56.135:9999 -r 192.168.71.3:8601 -m
ipvsadm -a -t 192.168.56.135:9999 -r 192.168.71.3:8602 -m

添加完成后我們查看下:

[root@nginxhost conf]# 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.56.135:9999 rr
  -> 192.168.71.3:8601            Masq    1      0          0         
  -> 192.168.71.3:8602            Masq    1      0          0         
[root@nginxhost conf]# 

現在我們可以嘗試在lvs server上訪問http://192.168.56.135:9999試試

[root@nginxhost conf]# curl http://192.168.56.135:9999
i am 8601[root@nginxhost conf]# curl http://192.168.56.135:9999
i am 8602[root@nginxhost conf]# curl http://192.168.56.135:9999
i am 8601[root@nginxhost conf]# curl http://192.168.56.135:9999
i am 8602[root@nginxhost conf]# curl http://192.168.56.135:9999
i am 8601[root@nginxhost conf]# curl http://192.168.56.135:9999
i am 8602[root@nginxhost conf]# 

下面我們通過物理機的瀏覽器試試,

 

 這是發現不能訪問,目前我也不知道為什么不能訪問,有知道的朋友可以幫我看看,萬分感謝,這種辦法不行,我想到既然可以在lvs 正常訪問,我們是不是可以做lvs的反向代理來解決這個問題,下面是解決辦法:

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;


    server {
        listen       8999;
        server_name  192.168.56.135;

        location / {
            proxy_pass http://192.168.56.135:9999;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

    }
}

讓8999 端口代理192.168.56.135:9999,再次嘗試用物理主機的瀏覽器去嘗試訪問。

 

 可以訪問了

至此,我們可以看到lvs成功完成了負載均衡,雖然有些問題現在還不明白為什么,但是還是解決了正常訪問的問題,這就是NAT 模式

DR實驗:

先說說什么是arp抑制,在以太網通信 過程中我們實際上用的是mac地址來通信的,而我們在訪問某一主機是用的是ip地址,那網絡中怎么通過IP地址找到相應的mac地址呢,這就是arp廣播,ARP廣播會被所有局域網中的和通過路由器連接的不同局域網中的主機收到,然后回復自己的mac地址給需要的主機,而我們每台電腦都有一張ARP映射表,其中記錄了ip地址和mac地址的對應關系,可以通過arp -a命令查看,那什么是arp抑制呢,其實就是主機1在詢問主機2 的mac地址時,主機2 不做應答,上面的DR模式中已經介紹過,real server都會有vip並且將其綁定在lo網卡上,只會響應目標地址是vip的請求,下面我們來看看怎么配置arp抑制:

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

其中也可以配置在/etc/sysctl.conf中,來永久生效。

以下是響應級別解釋:

arp_ignore(接收到ARP請求后的響應級別):
0:本地所有網卡中,如果有對應的IP地址就會響應請求
1:只會響應目標IP為接收網卡所配置的IP地址的請求。以此實現后端服務器回環地址上的IP不去響應廣播

arp_announce(向外回應自己網絡地址):
0:本地所有網卡上的IP地址都可以向外響應
1:盡量使用與本地網卡所匹配的地址向外響應
2:只使用與本地接口匹配的網絡地址向外響應,效果和arp_ignore類似也實現了避免響應

lvs server 配置:

准備三台機器,host-only模式及可,連接同一虛擬網卡

1, lvs server 192.168.56.135

2, real server 192.168.56.4

3, real server 192.168.56.5

 分別關閉三台主機的防火牆,selinux,清空iptables

iptables -F
setenforce 0
systemctl stop firewalld

real server 192.168.56.4 配置

綁定vip到lo網卡,並設置到VIP的路由

ip a a 192.168.56.200/32 dev lo
route add -host 192.168.56.200 dev lo

 

修改/etc/sysctl.conf 文件,抑制ARP

內容如下:

net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.default.arp_ignore = 1
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2

啟動服務進程:

nohup java -jar nginxtest-0.0.1-SNAPSHOT.jar --server.port=9000 &

real server 192.168.56.5,參照192.168.56.4配置即可

lvs server 192.168.56.135 配置:

ip a a 192.168.56.200/24 dev enp0s3
ipvsadm -A -t 192.168.56.200:9000 -s rr
ipvsadm -a -t 192.168.56.200:9000 -r 192.168.56.4:9000 -g
ipvsadm -a -t 192.168.56.200:9000 -r 192.168.56.5:9000 -g

測試,進入宿主機,打開瀏覽器:輸入http://192.168.56.200:9000

 

 以上就是lvs的NAT和DR模式,其中ipvsadm 的命令其實不難,難點在於網絡部分,

 

 

 

 

 

 

 

 

 

 

 

 

參考文檔:

http://www.zsythink.net/archives/2185

http://www.linuxe.cn/post-178.html

https://www.cnblogs.com/lyqlyqlyq/p/11641875.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM