LVS 負載均衡
最近在研究服務器負載均衡,閱讀了網上的一些資料,發現主要的軟件負載均衡方案有nginx(針對HTTP服務的負載均衡),LVS(針對IP層,MAC層的負載均衡)。LVS模式工作在網絡層,且由內核實現負載轉發,效率要比nginx高。
LVS負載均衡包含三種模式:
1. NAT模式(類似路由器,實現外網內網地址映射,負載均衡服務器修改請求包的源以及目的MAC地址和IP地址,發送給實際服務器;負載均衡服務器,修改響應包的源以及目的MAC地址和IP地址,發送給客戶端。請求和響應報文都需要經過負載均衡服務器)
2. TUN模式(IP隧道,負載均衡服務器將外網傳來的數據包封裝在IP隧道中,傳給實際服務器。實際服務器的響應直接發給客戶端,而不需要經過負載均衡服務器。)
3. DR模式(負載均衡服務器和后端的實際服務器擁有相同的虛擬IP地址,負載均衡服務器收到響應包后,修改目的MAC地址發給實際服務器,實際服務器將響應包直接發給客戶端,不需要經過負載均衡服務器)
搭建 LVS DR模式負載均衡服務
連接示意圖如下:

其中,負載均衡服務器的IP地址為 10.10.10.30/24 和 10.10.10.22/32(該IP地址是用戶訪問的IP地址), Real Server 1的IP地址為10.10.10.31/24, Real Server 2的IP地址為10.10.10.32/24,三者連接在同一個局域網中,且 RS1和 RS2的虛擬IP地址(可以在lo或者lo:0上設置該IP地址,即本地環回,這樣該虛擬IP只對該機器本身可見,不會暴露在外部造成IP沖突)都設為負載均衡服務器的IP地址 dev-1.
這樣外部訪問10.10.10.22時,會訪問到負載均衡服務器,而負載均衡服務器選擇某個實際服務器,比如RS1,然后將包的目的MAC地址修改為RS1的MAC地址,在將包送到局域網上。此時對於請求數據包來說,目的MAC地址為RS1的MAC地址,因此RS1會收到,RS1發現包的目的MAC為自身,且目的IP地址為10.10.10.22,也是自身的一個IP,於是就認為數據包是發到自己的,就開始進行處理。
一、安裝http服務
1. 在RS1和RS2上分別安裝httpd服務
2. 修改/etc/httpd/conf/httpd.conf 文件,進行相應的配置。
3. 啟動httpd服務,並設置防火牆開放80端口
二、在負載均衡服務器上安裝並配置ipvsadm
1. yum -y install ipvsadm
2. 設置實際ip和虛擬IP
ifconfig eth0 10.10.10.30/24 ifconfig eth0:0 10.10.10.22 netmask 255.255.255.255 #虛擬IP,暴露給外部
3. 設置負載轉發
方式一,通過ipvsadm
systemctl start ipvsadm ipvsadm -C ipvsadm --set 30 5 60 #vip on load balancer ipvsadm -A -t 10.10.10.22:80 -s wrr -p 20 #接受轉發協議 ipvsadm -a -t 10.10.10.22:80 -r 10.10.10.31:80 -g -w 1 #增加轉發目的地 ipvsadm -a -t 10.10.10.22:80 -r 10.10.10.32:80 -g -w 1 #增加轉發目的地 ipvsadm -L -n
vim /etc/keepalived/keepalived.conf 修改配置文件如下 global_defs { notification_email { skc361@163.com } notification_email_from sns-lvs@gmail.com smtp_server 192.168.80.1 smtp_connection_timeout 30 router_id LVS_DEVEL # 設置lvs的id,在一個網絡內應該是唯一的 } vrrp_instance VI_1 { state MASTER #指定Keepalived的角色,MASTER為主,BACKUP為備 interface eth0 #指定Keepalived的角色,MASTER為主,BACKUP為備 virtual_router_id 51 #虛擬路由編號,主備要一致 priority 100 #定義優先級,數字越大,優先級越高,主DR必須大於備用DR advert_int 1 #檢查間隔,默認為1s authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 10.10.10.22 #定義虛擬IP(VIP)為10.10.10.22,可多設,每行一個 } } # 定義對外提供服務的LVS的VIP以及port virtual_server 10.10.10.22 80 { delay_loop 6 # 設置健康檢查時間,單位是秒 lb_algo wrr # 設置負載調度的算法為wlc lb_kind DR # 設置LVS實現負載的機制,有NAT、TUN、DR三個模式 nat_mask 255.255.255.0 persistence_timeout 0 protocol TCP real_server 10.10.10.31 80 { # 指定real server1的IP地址 weight 3 # 配置節點權值,數字越大權重越高 TCP_CHECK { connect_timeout 10 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } real_server 10.10.10.32 80 { # 指定real server2的IP地址 weight 3 # 配置節點權值,數字越大權重越高 TCP_CHECK { connect_timeout 10 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } } 啟動keepalived服務 systemctl start keepalived
三、設置實際服務器的網卡
ifconfig lo:0 10.10.10.22 netmask 255.255.255.255 #即設置虛擬IP地址,該IP地址綁定在環回網卡上,不會對外暴露
四、設置實際服務器的內核參數
[root@dev-2 lvs]#vim /etc/sysctl.conf [root@dev-2 lvs]# sysctl -p net.ipv4.ip_forward = 1 #打開路由轉發 net.ipv4.conf.all.arp_ignore = 1 #只回答目的IP為本網口IP地址的arp包的請求 net.ipv4.conf.all.arp_announce = 2 #對查詢目標使用最適當的本機地址 net.ipv4.conf.lo.arp_ignore = 1 net.ipv4.conf.lo.arp_announce = 2
上面的 arp_ignore 和 arp_announce 參見 lvs arp設置
五、使用客戶端進行訪問
此時使用客戶端訪問 http://10.10.10.22, 請求會被轉發到RS1或者RS2上。
問題排查
在搭建的時候,可能出現 http://10.10.10.22 無法訪問,即HTTP請求沒有被轉發的情況。這種情況可以從以下情況中進行排查:
1. 負載均衡服務器 防火牆是否關閉,或者是否允許80端口的tcp連接
2. RS1 和 RS2 的http配置中是否設置 Listen 80(監聽本機上的所有地址,如果只監聽機器的網卡地址,而虛擬ip包就會被忽略)
3. 如果在負載均衡服務器上沒有設置VIP,只有一個IP地址 10.10.10.22/24,這樣也可以配置出來。但是此時,當負載均衡服務器要向 10.10.10.31和10.10.10.32轉發時,它需要知道它們的MAC地址,於是會發送ARP請求報文,當RS1或RS2收到ARP,它進行回復的時候發現請求報文的源IP為10.10.10.22 於是直接發到本機了,就不會回復給負載均衡服務器。於是負載均衡服務器就沒法動態獲知RS1和RS2的MAC地址。
此時,只能手動在負載均衡服務器上設置arp。 arp -s...
而且這樣做也會導致從負載均衡服務器上不能直接訪問RS1/RS2,同樣RS1/RS2也不能直接訪問負載均衡服務器。所以,還是需要在負載均衡服務器上配置一個eth0和一個虛擬IP eth0:0.