LVS的三種模式區別詳解

1. DR模式:(Direct Routing)直接路由模式前端

DR模式的網絡拓撲:linux

VS-DRouting

1) 工做過程: 當一個client發送一個WEB請求到VIP,LVS服務器根據VIP選擇對應的real-server的Pool,根據算法,在Pool中選擇一臺Real-server,LVS在hash表中記錄該次鏈接,而後將client的請求包發給選擇的Real-server,最後選擇的Real-server把應答包直接傳給client;當client繼續發包過來時,LVS根據更才記錄的hash表的信息,將屬於這次鏈接的請求直接發到剛纔選擇的Real-server上;當鏈接停止或者超時,hash表中的記錄將被刪除。算法

2) DR模式的幾個細節:
1> LVS和Real-server必須在相同的網段:(相同的廣播域內)
DR模式在轉發client的包時,只修改了包目的MAC地址爲選定的Real-server的mac地址,因此若是LVS和Real-server在不通的廣播域內,那麼Real-server就沒辦法接收到轉發的包。下面是mac地址的修改過程:shell

VS-DR-flow

2> LVS不須要開啓路由轉發:
LVS的DR模式不須要開啓路由轉發功能,就能夠正常的工做,出於安全考慮,若是不須要轉發功能,最好關閉。後端

3> ARP問題
一般,DR模式須要在Real-server上配置VIP,配置的方式爲:緩存

/sbin/ifconfig lo:0 inet VIP netmask 255.255.255.255安全

i) 緣由在於,當LVS把client的包轉發給Real-server時,由於包的目的IP地址是VIP,那麼若是Real-server收到這個包後,發現包的目的IP不是本身的系統IP,那麼就會認爲這個包不是發給本身的,就會丟棄這個包,因此須要將這個IP地址綁到網卡上;當發送應答包給client時,Real-server就會把包的源和目的地址調換,直接回復給client。服務器

ii) 關於ARP廣播:
* 上面綁定VIP的掩碼是」255.255.255.255″,說明廣播地址是其自己,那麼他就不會將ARP發送到實際的本身該屬於的廣播域了,這樣防止與LVS上VIP衝突,而致使IP衝突。
* 另外在Linux的Real-server上,須要設置ARP的sysctl選項:(下面是舉例說明設置項的)網絡

假設服務器上ip地址以下所示:架構

System Interface MAC Address IP Address
HN eth0 00:0c:29:b3:a2:54 192.168.18.10
HN eth3 00:0c:29:b3:a2:68 192.168.18.11
HN eth4 00:0c:29:b3:a2:5e 192.168.18.12
client eth0 00:0c:29:d2:c7:aa 192.168.18.129

當我從192.168.18.129 ping 192.168.18.10時,tcpdump抓包發現:

 
 

00:0c:29:d2:c7:aa > ff:ff:ff:ff:ff:ff, ARP, length 60: arp who-has 192.168.18.10 tell 192.168.18.129
00:0c:29:b3:a2:5e > 00:0c:29:d2:c7:aa, ARP, length 60: arp reply 192.168.18.10 is-at 00:0c:29:b3:a2:5e
00:0c:29:b3:a2:54 > 00:0c:29:d2:c7:aa, ARP, length 60: arp reply 192.168.18.10 is-at 00:0c:29:b3:a2:54
00:0c:29:b3:a2:68 > 00:0c:29:d2:c7:aa, ARP, length 60: arp reply 192.168.18.10 is-at 00:0c:29:b3:a2:68
00:0c:29:d2:c7:aa > 00:0c:29:b3:a2:5e, IPv4, length 98: 192.168.18.129 > 192.168.18.10: ICMP echo request, id 32313, seq 1, length 64
00:0c:29:b3:a2:54 > 00:0c:29:d2:c7:aa, IPv4, length 98: 192.168.18.10 > 192.168.18.129: ICMP echo reply, id 32313, seq 1, length 64
00:0c:29:d2:c7:aa > 00:0c:29:b3:a2:5e, IPv4, length 98: 192.168.18.129 > 192.168.18.10: ICMP echo request, id 32313, seq 2, length 64
00:0c:29:b3:a2:54 > 00:0c:29:d2:c7:aa, IPv4, length 98: 192.168.18.10 > 192.168.18.129: ICMP echo reply, id 32313, seq 2, length 64
00:0c:29:b3:a2:54 > 00:0c:29:d2:c7:aa, ARP, length 60: arp who-has 192.168.18.129 tell 192.168.18.10
00:0c:29:d2:c7:aa > 00:0c:29:b3:a2:54, ARP, length 60: arp reply 192.168.18.129 is-at 00:0c:29:d2:c7:aa

三個端口都發送了arp的reply包,可是192.168.18.129使用的第一個迴應的eth4的mac地址做爲ping請求的端口,因爲192.168.18.10是icmp包中的目的地址,那麼ping的應答包,會從eth0端口發出。

若是Real-server有個多個網卡,每一個網卡在不一樣的網段,那麼能夠過濾掉非本網卡ARP請求的迴應;可是若是多個網卡的ip在一個網段,那麼就不行了。

sysctl -w net.ipv4.conf.all.arp_filter=1

對於多個接口在相同網段能夠設置下面的來防止:

sysctl -w net.ipv4.conf.all.arp_ignore=1
sysctl -w net.ipv4.conf.all.arp_announce=2

仍是從192.168.18.129 ping 192.168.18.10時,tcpdump抓包發現:

 
 

00:0c:29:d2:c7:aa > ff:ff:ff:ff:ff:ff, ARP, length 60: arp who-has 192.168.18.10 tell 192.168.18.129
00:0c:29:b3:a2:54 > 00:0c:29:d2:c7:aa, ARP, length 60: arp reply 192.168.18.10 is-at 00:0c:29:b3:a2:54
00:0c:29:d2:c7:aa > 00:0c:29:b3:a2:54, IPv4, length 98: 192.168.18.129 > 192.168.18.10: ICMP echo request, id 32066, seq 1, length 64
00:0c:29:b3:a2:54 > 00:0c:29:d2:c7:aa, IPv4, length 98: 192.168.18.10 > 192.168.18.129: ICMP echo reply, id 32066, seq 1, length 64
00:0c:29:d2:c7:aa > 00:0c:29:b3:a2:54, IPv4, length 98: 192.168.18.129 > 192.168.18.10: ICMP echo request, id 32066, seq 2, length 64
00:0c:29:b3:a2:54 > 00:0c:29:d2:c7:aa, IPv4, length 98: 192.168.18.10 > 192.168.18.129: ICMP echo reply, id 32066, seq 2, length 64
00:0c:29:b3:a2:54 > 00:0c:29:d2:c7:aa, ARP, length 60: arp who-has 192.168.18.129 tell 192.168.18.10
00:0c:29:d2:c7:aa > 00:0c:29:b3:a2:54, ARP, length 60: arp reply 192.168.18.129 is-at 00:0c:29:d2:c7:aa

看到了麼,如今只有eth0會迴應arp請求了。

arp報文格式:

arp

請求報文:MAC地址字段是空的。
應答報文:全部字段都又內容。

The arp_announce/arp_ignore reference:

 
 

arp_announce – INTEGER
Define different restriction levels for announcing the local
source IP address from IP packets in ARP requests sent on
interface:
0 – (default) Use any local address, configured on any interface
1 – Try to avoid local addresses that are not in the target’s
subnet for this interface. This mode is useful when target
hosts reachable via this interface require the source IP
address in ARP requests to be part of their logical network
configured on the receiving interface. When we generate the
request we will check all our subnets that include the
target IP and will preserve the source address if it is from
such subnet. If there is no such subnet we select source
address according to the rules for level 2.
2 – Always use the best local address for this target.
In this mode we ignore the source address in the IP packet
and try to select local address that we prefer for talks with
the target host. Such local address is selected by looking
for primary IP addresses on all our subnets on the outgoing
interface that include the target IP address. If no suitable
local address is found we select the first local address
we have on the outgoing interface or on all other interfaces,
with the hope we will receive reply for our request and
even sometimes no matter the source IP address we announce.

The max value from conf/{all,interface}/arp_announce is used.

Increasing the restriction level gives more chance for
receiving answer from the resolved target while decreasing
the level announces more valid sender’s information.

arp_announce用來限制,是否使用發送的端口的ip地址來設置ARP的源地址:
* 「0″表明是用ip包的源地址來設置ARP請求的源地址。
* 「1″表明不使用ip包的源地址來設置ARP請求的源地址,若是ip包的源地址是和該端口的IP地址相同的子網,那麼用ip包的源地址,來設置ARP請求的源地址,不然使用」2″的設置。
* 「2″表明不使用ip包的源地址來設置ARP請求的源地址,而由系統來選擇最好的接口來發送。

當內網的機器要發送一個到外部的ip包,那麼它就會請求路由器的Mac地址,發送一個arp請求,這個arp請求裏面包括了本身的ip地址和Mac地址,而linux默認是使用ip的源ip地址做爲arp裏面的源ip地址,而不是使用發送設備上面的 ,這樣在lvs這樣的架構下,全部發送包都是同一個VIP地址,那麼arp請求就會包括VIP地址和設備 Mac,而路由器收到這個arp請求就會更新本身的arp緩存,這樣就會形成ip欺騙了,VIP被搶奪,因此就會有問題。

如今假設一個場景來解釋arp_announce:
Real-server的ip地址: 202.106.1.100(public local address),172.16.1.100(private local address),202.106.1.254(VIP)

若是發送到client的ip包產生的arp請求的源地址是202.106.1.254(VIP),那麼LVS上的VIP就會被沖掉,由於交換機上如今的arp對應關係是Real-server上的VIP對應本身的一個MAC,那麼LVS上的VIP就失效了。

arp_ignore – INTEGER
Define different modes for sending replies in response to
received ARP requests that resolve local target IP addresses:
0 – (default): reply for any local target IP address, configured
on any interface
1 – reply only if the target IP address is local address
configured on the incoming interface
2 – reply only if the target IP address is local address
configured on the incoming interface and both with the
sender’s IP address are part from same subnet on this interface
3 – do not reply for local addresses configured with scope host,
only resolutions for global and link addresses are replied
4-7 – reserved
8 – do not reply for all local addresses

The max value from conf/{all,interface}/arp_ignore is used
when ARP request is received on the {interface}
「0″,表明對於arp請求,任何配置在本地的目的ip地址都會迴應,無論該arp請求的目的地址是否是接口的ip;若是有多個網卡,而且網卡的ip都是一個子網,那麼從一個端口進來的arp請求,別的端口也會發送回應。

「1″,表明若是arp請求的目的地址,不是該arp請求包進入的接口的ip地址,那麼不迴應。
「2″,要求的更苛刻,除了」1″的條件外,還必需要求arp發送者的ip地址和arp請求進入的接口的ip地址是一個網段的。
(後面略)

2.IP Tunneling模式:
IP Tunneliing的拓撲圖

VS-IPTunneling

1) 工做過程:
1> client 發送request包到LVS服務器的VIP上。

2> VIP按照算法選擇後端的一個Real-server,並將記錄一條消息到hash表中,而後將client的request包封裝到一個新的IP包裏,新IP包的目的IP是Real-server的IP,而後轉發給Real-server。

3> Real-server收到包後,解封裝,取出client的request包,發現他的目的地址是VIP,而Real-server發如今本身的lo:0口上有這個IP地址,因而處理client的請求,而後將relpy這個request包直接發給client。

4> 該client的後面的request包,LVS直接按照hash表中的記錄直接轉發給Real-server,當傳輸完畢或者鏈接超時,那麼將刪除hash表中的記錄。

2) 幾個細節問題:
1> IP封包的過程:(如圖)

VS-TUN-flow

2> LVS和Real-server不須要在一個網段:
因爲經過IP Tunneling 封裝後,封裝後的IP包的目的地址爲Real-server的IP地址,那麼只要Real-server的地址能路由可達,Real-server在什麼網絡裏均可以,這樣能夠減小對於公網IP地址的消耗,可是由於要處理IP Tunneling封裝和解封裝的開銷,那麼效率不如DR模式。

3> Real-server的系統設置:(因爲須要Real-server支持IP Tunneling,因此設置與DR模式不太同樣,LVS不須要設置tunl設備,LVS自己能夠進行封裝)
i) 須要配置VIP在tunl設備上:(VIP:172.16.1.254)

shell> ifconfig tunl0 172.16.1.254 netmask 255.255.255.255
shell> ifconfig tunl0
tunl0 Link encap:IPIP Tunnel HWaddr
inet addr:172.16.1.254 Mask:255.255.255.255
UP RUNNING NOARP MTU:1480 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)

當添加tunl0設備時,自動載入須要的模塊:

shell> lsmod |grep ipip
ipip 7516 0
tunnel4 2700 1 ipip

其中,ipip依賴於tunnel4,假如如今刪除tunnel4的話:

shell> rmmod tunnel4
ERROR: Module tunnel4 is in use by ipip

若是添加tunl0失敗,那麼多是內核沒有開啓tunneling功能,默認是以模塊形式,加載到內核裏的:

tunneling_mod

3) ARP問題:
若是LVS和Real-server不在一個網絡內,不須要處理ARP問題,若是在相同網絡,那麼處理方法和DR模式同樣,可是若是同樣,我就不知道選擇tun模式有什麼好理由了,DR彷佛效率更高些吧。

4) 內核的包轉發:
IP Tunneling模式不須要開啓ip_forward功能。

3. NAT模式:
NAT模式的拓撲圖

VS-NAT

1) 工做過程:

RunningExample

client:202.100.1.2
VIP:202.103.106.5
Real-server:172.16.0.2 和 172.16.0.3(提供http和ftp服務)

1> client發送request到LVS的VIP上,VIP選擇一個Real-server,並記錄鏈接信息到hash表中,而後修改client的request的目的IP地址爲Real-server的地址,將請求發給Real-server;

2> Real-server收到request包後,發現目的IP是本身的IP,因而處理請求,而後發送reply給LVS;

3> LVS收到reply包後,修改reply包的的源地址爲VIP,發送給client;

4> 從client來的屬於本次鏈接的包,查hash表,而後發給對應的Real-server。

5> 當client發送完畢,這次鏈接結束或者鏈接超時,那麼LVS自動從hash表中刪除此條記錄。

下面是地址轉換的過程:

Screenshot

2) 幾個細節問題:
1> NAT模式的Bugs:(都已經修復,具體的信息看LVS的howto)
i) 在Linux的2.6版本,LVS-NAT不能作防火牆,在只有一個網關的狀況下,沒有任何問題。
ii) 防火牆不兼容:LVS的架構中,LVS的前端不能設置防火牆,修復的補丁」NFCT」 patch。
iii) 源路由問題

2> ICMP重定向問題:
i) 對於路由器來講,只有當以下條件同時知足的時候,才進行重定向:
a) 數據包的入接口和路由後的指定的出接口是同一個接口。
b) 數據包的源IP地址和該包應走的下一跳IP地址屬於同一個網段。
c) 數據報非源路由的(這種狀況應該比較少見了,源路由多見於Token Ring)。
d) 系統開啓重定向功能。
例如:
兩個路由器都開啓了IP重定向功能。HostA 的默認網關爲1.1.1.1。當HostA要和不在同一網段中的HostB通訊的時候,會把數據報遞交給默認網關RT1。然而RT1通過查找發現到達3.3.3.3的路徑下一跳偏偏是經由本身的E0/1口的RT2接口1.1.1.2。知足上述條件,將會發生重定向。

ii) LVS爲何會產生ICMP重定向問題:
* 在LVS-NAT模式下,若是LVS的各個成員,client,LVS,Real-server在同一個網段(好比:192.168.1.*/24);

* 當Real-server將Reply發送回LVS時,Reply包是 RIP -> CIP的,LVS看到RIP-> CIP實際上根本不必通過LVS,直接到網關就好了,由於你們在一個網段,因此產生ICMP重定向發送給Real-server;

* Real-server收到ICMP重定向包後,若是Real-server的ICMP重定向開啓了,Real-server就會處理ICMP重定向包,直接將Reply包發給網關,這時Reply包頭並無被LVS重寫,因此LVS負載出現了問題。

注意:這種狀況只會出如今全部的LVS的成員都在一個網段的狀況下。

重定向的處理辦法(Real-server的配置):
1> 關閉Real-server的重定向,忽略LVS發來的重定向包
2> 刪除到網段的路由:

Screenshot1

執行:

realserver:/etc/lvs#route del -net 192.168.1.0 netmask 255.255.255.0 dev eth0

路由已經被刪除了:

Screenshot-1

3> LVS-NAT模式支持四層的端口重寫:
LVS-DR,LVS-TUN不能修改client發來的請求的目的端口,可是LVS-NAT能夠,參考命令:

shell> ipvsadm -a -t VIP:PORT -r RIP:NEWPORT -m -w 1

相關文章
相關標籤/搜索