linux下LVS的實現
在2.4.23之前的linux核心想要使用LVS需要重新編譯核心打補丁,之後的LVS直接做進了核心
使用grep -i -C 5 ipvs /boot/config-`uname -r`可以查看
ipvsadm工作在使用者空間/ipvs工作在核心空間,使用者使用ipvsadm進行設定並且傳遞到核心空間中的ipvs (ipvsadm工具在光碟片中的cluster中)
ipvsadm功能
定義一個叢集服務,定義REALSERVER,叢集服務的查看
-t 基於tcp的叢集服務
-u 基於udp的叢集服務
-f 基於防火牆標記的叢集服務
-A 添加一個服務
-E 修改一個服務
-s 調度演算法 預設WLC
-g LVS-DR直接路由模型
-i LVS-TUN隧道模型
-m LVS-NAT模型
-C 清空規則
-R 從一個檔案中恢複規則
-S 儲存對著到檔案中
-L/l -n 查看
定義叢集服務
添加或修改叢集服務:ipvsadm -A|E -t|u|f VIP:port -s 調度演算法
刪除一個叢集服務: ipvsadm -D -t|u|f VIP:port
realserver
添加或者修改REALSERVER:ipvsadm -a|e -t|u|f VIP:port -r REALSERVER[:port] -g|-i|-m [-w 權重]
刪除一個REALSERVER: ipvsadm -d -t|u|f VIP:port -r REALSERVER[:port]
##########################################################################
配置LVS-NAT
這裡以HTTP服務為例,前端伺服器配置VIP向外響應來自客戶的請求,後端兩台REALSERVER運行WEB服務,首先在後端的兩台web上面配置相同的網頁,設定網關都指向前端伺服器的DIP
在director上面的配置
echo 1 >proc/sys/net/ipv4/ip_forward 開啟路由轉寄
ipvsadm -A -t 192.168.0.1:80 -s rr 定義一個叢集服務,這個VIP在實際應用中應該是外網地址
ipvsadm -a -t 192.168.0.1:80 -r 192.168.1.2 -m
ipvsadm -a -t 192.168.0.1:80 -r 192.168.1.3 -m 添加兩台REALSERVER
查看ipvsadm -L -n
ipvsadm -E -t 192.168.0.1:80 -s wlc 設定演算法為wlc
ipvsadm -e -t 192.168.0.1:80 -r 192.168.1.2 -m -w 4 設定權重為4,即1.2伺服器的效能是1.3伺服器的4倍
ab -c -n 10000 http://192.168.0.1/index.html 用ab命令做測試
watch -n 1 'ipvsadm -L -n' 每秒重新整理一次來查看狀態變化,可以看到1.2伺服器的響應數基本上為1.3伺服器的4倍
##########################################################################
配置LVS-DR
在如的VS/DR或VS/TUN應用的一種模型中(所有機器都在同一個物理網路),所有機器(包括Director和RealServer)都使用了一個額外的IP地址,即VIP。
當一個用戶端向VIP發出一個串連請求時,此請求必須要串連至Director的VIP,而不能是RealServer的。因為,LVS的主要目標就是要Director負責調度這些串連請求至RealServer的。因此,在Client發出至VIP的串連請求後,只能由Director將其MAC地址響應給用戶端(也可能是直接與Director串連的路由裝置),而Director則會相應的更新其ipvsadm table以追蹤此串連,而後將其轉寄至後端的RealServer之一。
如果Client在請求建立至VIP的串連時由某RealServer響應了其請求,則Client會在其MAC table中建立起一個VIP至RealServer的對就關係,並以至進行後面的通訊。此時,在Client看來只有一個RealServer而無法意識到其它伺服器的存在。
為瞭解決此問題,可以通過在路由器上設定其轉寄規則來實現(靜態MAC-IP綁定)。當然,如果沒有許可權訪問路由器並做出相應的設定,則只能通過傳統的本地方式來解決此問題了。
這些方法包括:
1、禁止RealServer響應對VIP的ARP請求;
2、在RealServer上隱藏VIP,以使得它們無法獲知網路上的ARP請求;
3、基於“透明代理(Transparent Proxy)”或者“fwmark (firewall mark)”;
4、禁止ARP請求發往RealServers;
傳統認為,解決ARP問題可以基於網路介面,也可以基於主機來實現。Linux採用了基於主機的方式,因為其可以在大多情境中工作良好,但LVS卻並不屬於這些情境之一,因此,過去實現此功能相當麻煩。現在可以通過設定arp_ignore,arp_announce,這變得相對簡單的多了。
Linux 2.2和2.4(2.4.26之前的版本)的核心解決“ARP問題”的方法各不相同,且比較麻煩。幸運的是,2.4.26和2.6的核心中引入了兩個新的調整ARP棧的標誌
(device flags):arp_announce和arp_ignore。基於此,在DR/TUN的環境中,所有IPVS相關的設定均可使用arp_announce=2和arp_ignore=1/2/3來解決“ARP問題”了。以下是官方說明:
arp_annouce: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.
2 - Always use the best local address for this target.
arp_ignore: Define different modes for sending replies in response to received ARP requests that resolve local target IP address.
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 address configured with scope host,only resolutions for golbal and link addresses are replied.
4-7 - reserved
8 - do not reply for all local addresses
arp_announce:定義了網卡在向外宣告自己的MAC-IP時候的限制層級
有三個值:
0:預設值,不管哪塊網卡接收到了ARP請求,只要發現本機有這個MAC都給與響應
1:盡量避免響應ARP請求中MAC不是本網卡的,一個主機有多塊網卡,其中一塊網卡接收到了ARP請求,發現所請求的MAC是本機另一塊網卡的,這個時候接收到ARP請求的這塊網卡就盡量避免響應
2:總是使用最合適的網卡來響應,一個主機有多塊網卡,其中一塊網卡接收到了ARP請求,發現所請求的MAC是本機另一塊網卡的,這個時候接收到ARP請求的這塊網卡就一定不響應,只有發現請求的MAC是自己的才給與響應
arp_ignore:定義了網卡在響應外部ARP請求時候的響應層級
這裡有8個值,但我們只使用了2個
0:預設值,不管哪塊網卡接收到了ARP請求,只要發現本機有這個MAC都給與響應
1:總是使用最合適的網卡來響應,一個主機有多塊網卡,其中一塊網卡接收到了ARP請求,發現所請求的MAC是本機另一塊網卡的,這個時候接收到ARP請求的這塊網卡就一定不響應,只有發現請求的MAC是自己的才給與響應
在RealServers上,VIP配置在本地迴環介面lo上。如果回應給Client的資料包路由到了eth0介面上,則arp通告或請應該通過eth0實現,因此,需要在sysctl.conf檔案中定義如下配置:
vim /etc/sysctl.conf
net.ipv4.conf.eth0.arp_ignore = 1
net.ipv4.conf.eth0.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
以上選項需要在啟用VIP之前進行,否則,則需要在Drector上清空arp表才能正常使用LVS。
到達Director的資料包首先會經過PREROUTING,而後經過路由發現其目標地址為本地某介面的地址,因此,接著就會將資料包發往INPUT(LOCAL_IN HOOK)。此時,正在運
行核心中的ipvs(始終監控著LOCAL_IN HOOK)進程會發現此資料包請求的是一個叢集服務,因為其目標地址是VIP。於是,此資料包的本來到達本機(Director)目標行程被改變為經由POSTROUTING HOOK發往RealServer。這種改變資料包正常行程的過程是根據IPVS表(由管理員通過ipvsadm定義)來實現的。
如果有多台Realserver,在某些應用情境中,Director還需要基於“串連追蹤”實現將由同一個客戶機的請求始終發往其第一次被分配至的Realserver,以保證其請求的完整性等。其串連追蹤的功能由Hash table實現。Hash table的大小等屬性可通過下面的命令查看:
# ipvsadm -lcn
為了保證其時效性,Hash table中“串連追蹤”資訊被定義了“存留時間”。LVS為記錄“連線逾時”定義了三個計時器:
1、空閑TCP會話;
2、用戶端正常中斷連線後的TCP會話;
3、不需連線的UDP資料包(記錄其兩次發送資料包的時間間隔);
上面三個計時器的預設值可以由類似下面的命令修改,其後面的值依次對應於上述的三個計時器:
# ipvsadm --set 28800 30 600
資料包在由Direcotr發往Realserver時,只有目標MAC地址發生了改變(變成了Realserver的MAC地址)。Realserver在接收到資料包後會根據本地路由表將資料包路由至本地迴環裝置,接著,監聽於本地迴環裝置VIP上的服務則對進來的資料庫進行相應的處理,而後將處理結果回應至RIP,但資料包的原地址依然是VIP。
配置拓撲如:
1.DIP要配置在介面上,VIP要配置在介面別名上
在前端伺服器上的配置(配置VIP)
ifconfig eth0:0 $192.168.0.1 broadcast $192.168.0.1 netmask 255.255.255.255 up
route add -host $192.168.0.1 dev eth0:0
route add -host $192.168.1.1 dev eth0
echo 1 >/proc/sys/net/ipv4/ip_forward
2.在REALSERVER上面的配置
RIP要配置在介面上,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
配置VIP
ifconfig lo:0 $192.168.0.1 broadcast $192.168.0.1 netmask 255.255.255.255 up
route add -host 192.168.0.1 dev lo:0 確保如果請求的目標IP是$VIP,那麼讓出去的資料包的源地址也顯示為$VIP
3.在前端伺服器配置並啟動服務
ipvsadm -A -t 192.168.0.1:80 -s wlc
ipvsadm -a -t 192.168.0.1:80 -r 192.168.1.2 -g -w 4
ipvsadm -a -t 192.168.0.1:80 -r 192.168.1.3 -g -w 2
ipvsadm -L -n
ab -c -n 10000 http://192.168.0.1/index.html
watch -n 1 'ipvsadm -L -n'
作者 “成長全記錄”