LVS系列文章:http://www.cnblogs.com/f-ck-need-u/p/7576137.html
1.實現VS/NAT模式的負載均衡
實驗環境如下:
其中:
CIP:172.16.10.22
VIP:172.16.10.21
DIP:192.168.100.17
RIP1:192.168.100.39
RIP2:192.168.100.23
在開始操作前,先回顧下VS/NAT模式的相關內容:
請求過程:CIP-->VIP--ip_forward-->DIP-->RIP
響應過程:RIP-->DIP--ip_forward-->VIP-->CIP
由於director接收到CIP發送的數據包后,需要轉發給Real Server進行處理,但Real Server的RIP和DIP是同一網段的,因此Director必須將VIP接口上收到的數據包轉發給DIP,也就是說Director需要開啟ip_forward功能。
當RS處理完成后,響應數據需要先轉發給Director,但因為響應數據的目標地址為CIP,因此需要將RS的網關指向Director的DIP,這樣CIP目的的數據包才能保證交給director進行處理並返回給客戶端。
因此,如下操作Director:假設該實驗中的VS/NAT采用wrr調度算法。
echo 1 >/proc/sys/net/ipv4/ip_forward
ipvsadm -A -t 172.16.10.21:80 -s wrr
ipvsadm -a -t 172.16.10.21:80 -r 192.168.100.39 -m -w 2
ipvsadm -a -t 172.16.10.21:80 -r 192.168.100.23 -m -w 3
如下操作各RS:
yum -y install httpd echo "from RS1:192.168.100.39" >/var/www/html/index.html # 在RS1上操作 echo "from RS2:192.168.100.23" >/var/www/html/index.html # 在RS2上操作 service httpd start route add default gw 192.168.100.17
然后在客戶端Win2003上的瀏覽器上輸入http://172.16.10.21
進行測試,同時測試調度算法的比例。可以使用下面的命令查看統計數據:
[root@xuexi ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.10.21:80 wrr
-> 192.168.100.23:80 Masq 3 0 0
-> 192.168.100.39:80 Masq 2 0 0
[root@xuexi ~]# ipvsadm -ln --stats
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Conns InPkts OutPkts InBytes OutBytes
-> RemoteAddress:Port
TCP 172.16.10.21:80 25 113 95 10293 8913
-> 192.168.100.23:80 15 67 55 6059 4921
-> 192.168.100.39:80 10 46 40 4234 3992
注意點:
(1).建議不要使用win7/win8/win10作為客戶端進行測試,而是使用win server類系統或直接使用unix系統測試。
(2).調度算法是對連接進行調度,而不是對數據包、字節等調度,因此查看統計數據時,應該比較的是Conns列的比例。另外,如果連接數大致滿足比例,但數據包或者字節數卻遠不符合比例(高的多或低的多),那么可能對應的那台RS主機性能比其它RS的性能要好或差。
實驗完成后,刪除Director上的virtual service,並重新設置RS上的默認路由。
ipvsadm -C
route del default gw 192.168.100.17 # 在RS1和RS2上操作
2.VS/DR模式的數據包流向分析
如圖:
在分析數據包流向前,需要厘清一個容易產生疑惑的要點:在VS/DR模式下,TCP連接是客戶端和RS之間建立的,Director只是負責改造、轉發建立TCP連接時的數據包給后端RealServer;當TCP連接建立完成后,就有了客戶端和服務端(RS)的概念,這時客戶端將直接和RS進行數據通信,而Director已經退出舞台,不再負責改造、轉發請求數據包,直到關閉連接時。也就是說,Director改造、轉發的數據包只有客戶端發送的和tcp連接建立、關閉相關的syn、ack和fin包,其它數據包和它無關(網絡狀況良好的情況下,共轉發syn+ack、fin+ack共4個包)。可以想象,這樣的Director相比NAT模式,性能高的不是一點點。
- (1).當客戶端發起
http://VIP
的請求時,數據包的源和目標地址為CIP-->VIP
。這個數據包最終會到達Director。 - (2).當Director收到請求數據包后,將根據調度算法選擇一台后端RealServer作為調度的目標。於是修改數據包的目標MAC地址為該RealServer的RIP所在MAC地址。數據包將轉發給該RS,此時數據包的源和目標IP地址仍然為
CIP-->VIP
,但源和目標MAC地址為DIP_MAC-->RIP_MAC
。- 需要注意的是,Director雖然要將數據包交給RS,但交出去的這個數據包是修改過目標MAC地址的數據包。也就是說,交給RIP的數據包不是原包,因此在Director上不會經過ip_forward轉發,而是修改MAC后根據路由決策直接路由到RIP。因此,VS/DR模式下,Director無需開啟ip_forward功能,這一點很容易出現誤解,其實如果搭建過keepalived+lvs的DR,就可以發現keepalived管理ipvs的時候,並沒有開啟ip_forward。
- (3).被調度到的RS收到Director轉發的數據包后,發現目標IP地址已經配置在自身內核,因此會收下該數據包。之后會處理請求,並構建響應數據。
- (4).RS將響應數據響應給客戶端,該響應數據包的源和目標IP地址為
VIP-->CIP
。- 由於RS上的VIP一般配置在lo的別名接口上,它無法和外界直接通信,因此數據包最終會從普通網卡上流出,如RIP所在接口。根據TCP/IP協議,響應數據包的源MAC地址也將是普通網卡(如RIP所在接口)的MAC地址。這一細節在后面配置CIP、VIP、RIP不同網段時會引出一種特殊問題,詳情見后文。
3.實現VS/DR模式的負載均衡(CIP、VIP、RIP同網段)
CIP、VIP和RIP同網段時,配置非常簡單,幾乎無需考慮額外的路由問題,也都無需分析數據包流向問題。
實驗環境如下:
其中:
CIP:192.168.100.46
VIP:192.168.100.11
DIP:192.168.100.17(由於VIP和RIP同網段,因此它是多余的)
RIP1:192.168.100.47
RIP2:192.168.100.23
配置過程:
如下操作各RS:
# (1).提供web服務和測試頁面
yum -y install httpd
echo "from RS1:192.168.100.47" >/var/www/html/index.html # 在RS1上操作
echo "from RS2:192.168.100.23" >/var/www/html/index.html # 在RS2上操作
service httpd start
# (2).設置arp參數
echo 1 >/proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 >/proc/sys/net/ipv4/conf/all/arp_announce
# (3).設置VIP
ifconfig lo:0 192.168.100.11/32 up
route add -host 192.168.100.11 dev lo:0
如下操作Director:
ipvsadm -C
ipvsadm -A -t 192.168.100.11:80 -s wrr
ipvsadm -a -t 192.168.100.11:80 -r 192.168.100.47:80 -g -w 2
ipvsadm -a -t 192.168.100.11:80 -r 192.168.100.23:80 -g -w 1
測試時,建議不要使用win7/win8/win10作為客戶端,而是使用win server類系統或直接使用unix系統測試。
4.實現VS/DR模式的負載均衡(CIP、VIP、RIP不同網段)
4.1 CIP、RIP不同網段時為何特殊?
考慮實際的生產環境,由於公網地址有限,一般只給web server的負載均衡系統分配一個公網地址。這個公網地址可能直接分配給VIP,這樣CIP、VIP、RIP兩兩都處於不同網段;還可能分配給路由器或防火牆,然后VIP和RIP都是用私網地址,這樣VIP/RIP同網段,但它們和CIP不同網段。
不管公網地址分配給誰,CIP、RIP總是不同網段的。這時需要考慮以下幾個問題:
- RS將響應數據響應給客戶端,該響應數據包的源和目標IP地址為
VIP-->CIP
,但因為是從RIP所在網卡流出的,這個響應數據包的源MAC地址為MAC_RIP; - 由於RIP和CIP不同網段,因此RS需要借助某個路由設備來轉發這個數據包;
- 由於RS上的VIP被隱藏,DIP/RIP所在網段的所有主機(包括這個路由設備)上緩存的關於VIP的arp記錄都是Director上的(即
VIP<-->MAC_V
),即使重新發起arp請求,也只能獲取到這樣的對應關系。因此,響應數據包的源IP、源MAC的對應關系和路由設備arp緩存中記錄不一致,這個響應數據包是"非法"數據包。就像同宿舍的人都知道你和你的身份證號碼,但如果有一個人拿着你的身份證去找你的舍友辦事,他肯定知道這個人是冒充的; - 這個路由設備發現數據包的源MAC地址、源IP和它arp緩存中的記錄不一致,它會丟棄這個數據包嗎?分兩種情況:
- (1).如果這個數據包被路由到普通的路由設備上,路由設備默認不會檢查源地址是否合法。這種檢查稱為"reverse path filter"(反向路徑過濾)功能。默認Linux主機會做反向檢查,Linux上控制該功能的參數為rp_filter。
- (2).如果這個數據包被路由到Director所在主機(Linux)上,默認會丟棄這個數據包,因為源IP地址正好在本機上。但可以為內核打上forward_shared補丁,以便使用forward_shared和rp_filter參數來開啟轉發源IP地址為自身地址數據包的功能。轉發時,需要設置轉發接口為VIP所在接口,這樣數據包的源MAC地址和VIP相互對應,之后的路由過程會一路順暢。
根據第四點的兩種情況,RS上的路由表可以按需設置成兩種情況。第一種情況設置很簡單,但Linux充當路由設備關閉源IP地址檢查功能后,將更容易受到DDos攻擊。第二種情況可以忽略,不僅要重新編譯內核,更重要的是VS/DR模式的優點本就在於讓Director專注於調度工作來實現高性能,而不應該讓其幫助轉發。
因此,本文將以第一種情況來做實驗測試。第二種情況可參考網上一篇博文:LVS-DR VIP和RIP不同網段的配置方法。
4.2 反向路徑過濾rp_filter參數的作用
以下是Linux內核文檔中關於rp_filter變量的描述:
rp_filter - INTEGER
0 - No source validation.
1 - Strict mode as defined in RFC3704 Strict Reverse Path
Each incoming packet is tested against the FIB and if the interface
is not the best reverse path the packet check will fail. By default failed packets are discarded. 2 - Loose mode as defined in RFC3704 Loose Reverse Path Each incoming packet's source address is also tested against the FIB and if the source address is not reachable via any interface the packet check will fail. Current recommended practice in RFC3704 is to enable strict mode to prevent IP spoofing from DDos attacks. If using asymmetric routing or other complicated routing, then loose mode is recommended. The max value from conf/{all,interface}/rp_filter is used when doing source validation on the {interface}. Default value is 0. Note that some distributions enable it in startup scripts.
大致說明下:rp_filter參數有三個值,0、1、2,Linux上默認為1。
- 0:不開啟源地址校驗。
- 1:開啟嚴格的反向路徑校驗。對每個進來的數據包,校驗其反向路徑是否是最佳路徑(通過特定接口)。如果反向路徑不是最佳路徑,則直接丟棄該數據包。
- 2:開啟松散的反向路徑校驗。對每個進來的數據包,校驗其源地址是否可達,即反向路徑是否能通(通過任意接口),如果反向路徑不通,則直接丟棄該數據包。這個值是只是為了防止轉發無效或冒充的源IP地址,如192.16.10這樣的不完整IP。
- 取/proc/sys/net/ipv4/conf/{all,interface}/rp_filter中的最大值生效。注意,對lo接口設置該參數是無意義的。
Linux充當RS、Client中間的路由設備時,接收到的數據包源IP為VIP,源MAC地址為RIP_MAC。假設該路由主機上路由表部分信息有如下兩種情形:
### 情形1:RIP和VIP不同網段
Dst Gateway Interface
RIP 0.0.0.0 eth0
VIP 0.0.0.0 eth1
### 情形2:RIP和VIP同網段
Dst Gateway Interface
VIP/RIP 0.0.0.0 eth0
- 如果設置rp_filter=1(默認),會反向檢查源IP(VIP)是否是最佳路徑。最佳路徑的意思是:要求檢查VIP時流出的數據包必須要從收到RS數據包的接口出去。也就是說,上面的第一種情形中,收到RS數據包的接口為eth0,檢查VIP時出去的接口為eth1,它們不相同,因此不是最佳路徑,於是收自RS的數據包會被丟棄;而第二種情形中,檢查VIP時出去的接口也是eth0,因此是最佳路徑,於是收自RS的數據包被保留,進而轉發給Client。
- 如果設置rp_filter=2,只要Router反向檢查時能和VIP能互相通信就能滿足檢查條件,即使盡管檢查的接口和接收RS數據包的接口不同也無所謂。換句話說,當設置為該值時,無論RIP、VIP是否同網段,數據包都會保留並轉發給Client。
- 如果設置rp_filter=0,則完全不檢查源地址,直接轉發。
一般情況下,保持默認值比較安全,這樣可以防止DDos攻擊。如果有修改該參數的需要,則應該將其設置為2。無可奈何的情況下才設置為0。對於LVS的集群環境而言,如果使用了Linux Router,當VIP和RIP不同網段時,需要設置rp_filter=2或0,如果VIP和RIP同網段,則無需設置該參數。
4.3 實現VS/DR模式的負載均衡(CIP、VIP不同網段)
實驗環境如下:之所以Client-->Router-->Director
給出了虛線,是因為這里CIP和VIP同網段,它會直接和Director通信,而不會經過Router,但這並不影響結果。
為了測試的便利性,將Director自身也設置為一個RS,其RIP設置為127.0.0.1。
因此:
CIP:172.16.10.22
Route IP1:172.16.10.23
Route IP2:192.168.100.32
VIP:172.16.10.21
DIP:192.168.100.17
RIP1:192.168.100.47
RIP2:192.168.100.23
RIP3:127.0.0.1(在Director上的RIP)
配置過程:
如下操作各RS:不包括Director上的本地RS
# (1).提供web服務和測試頁面
yum -y install httpd
echo "from RS1:192.168.100.47" >/var/www/html/index.html # 在RS1上操作
echo "from RS2:192.168.100.23" >/var/www/html/index.html # 在RS2上操作
service httpd start
# (2).設置arp參數
echo 1 >/proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 >/proc/sys/net/ipv4/conf/all/arp_announce
# (3).設置VIP
ifconfig lo:0 172.16.10.21/32 up
route add -host 172.16.10.21 dev lo:0
# (4).修改RS數據包流出的網關為Router,以保證能和外界客戶端通信
route del default
route add default gw 192.168.100.32
如下操作Router:開啟轉發功能,但暫時不設置rp_filter,以查看實驗結果
echo 1 > /proc/sys/net/ipv4/ip_forward
最后如下操作Director:
ipvsadm -C
ipvsadm -A -t 172.16.10.21:80 -s wrr
ipvsadm -a -t 172.16.10.21:80 -r 192.168.100.47:80 -g -w 1
ipvsadm -a -t 172.16.10.21:80 -r 192.168.100.23:80 -g -w 1
ipvsadm -a -t 172.16.10.21:80 -r 127.0.0.1:80 -g -w 1
# 提供本地RS
yum -y install httpd
echo "from RS3:127.0.0.1" >/var/www/html/index.html
service httpd start
# 添加目標地址為CIP的路由,以便調度到本地RS時,數據包能經過Router轉發,而非Director直接返回給Client
route add -host 172.16.10.22 gw 172.16.10.23
測試時,只有當調度到RS3時,才能得到正確的響應結果,而調度器調度到RS1和RS2時,將無法得到正確的響應。實際上是客戶端和RS1、RS2無法建立TCP連接。
查看Director上的狀態。
[root@xuexi ~]# ipvsadm -ln -c
IPVS connection entries
pro expire state source virtual destination
TCP 14:58 ESTABLISHED 172.16.10.22:1683 172.16.10.21:80 127.0.0.1:80
TCP 00:57 SYN_RECV 172.16.10.22:1679 172.16.10.21:80 192.168.100.23:80
TCP 00:55 SYN_RECV 172.16.10.22:1681 172.16.10.21:80 192.168.100.47:80
注意,這里顯示的狀態是RS上的TCP連接狀態,不是Director的。SYN_RECV表示RS1/RS2發送的syn+ack得不到客戶端的回應。如果在Router和Client機器上抓包分析的話,會發現syn+ack數據包到Router上就斷了,Client根本就沒收到syn+ack。
正如前面的分析,只有調度到RS3時,響應數據包的源MAC地址、源IP地址和Router上的arp緩存記錄是對應的。默認rp_filter=1反向檢查時,這正好是最佳路徑。而調度到RS1和RS2時,Router反向檢查時由於VIP和RIP不同網段,因此不是最佳路徑,數據包會被丟棄。
現在,將Router上和RS通信的接口rp_filter設置為2。
echo 2 >/proc/sys/net/ipv4/conf/eth0/rp_filter
再測試時,發現無論是RS1、RS2、RS3都能正確響應結果。