1. 程式人生 > >lvs+keepalived實現負載均衡

lvs+keepalived實現負載均衡

keepalive 裝載 announce log loopback -s scheduler sad apr

LVS簡介:

lvs是負載均衡較常用的軟件之一,lvs官方提供了一個命名的約定:

vip:虛擬ip地址,縮寫是vip,vip是負載均衡器對外提供服務的ip。

rip:真實ip地址,縮寫是rip,rip是集群下面節點上使用的ip地址。

dip:負載均衡器的真實ip,用於連接內外網絡的ip。

cip:客戶端的ip地址,訪問來源ip。

lvs的工作模式有如下幾種,直接路由(dr)模式、nat模式、tunnel模式、full nat模式。

DR模式-直接路由模式:

Virtual Server via Direct
VS/DR模式是通過改寫請求報文的目標MAC地址,將請求發給真實服務器的,而真 實服務器將響應後的處理結果直接返回給客戶端用戶。同VS/TUN技術一樣,VS/DR技術 可極大地提高集群系統的伸縮性。而且,這種DR模式沒有IP隧道的開銷,對集群中的真 實服務器也沒有必須支持IP隧道協議的要求,但是要求調度器LB與直實服努器RS都有一塊網卡連在同一物理網段上,即必須在同一個局域網環境。

當然也包括iptables防火墻的forward功能(DR和TUX模式不需要)

DR模式特點:

1、通過在調度器LB上修改數據包的目的MAC地址實現轉發。註意,源IP地址仍然是 CIP,目的IP地址仍然是VIP。

2、請求的報文經過調度器,而RS響應處理後的報文無需經過調度器LB,因此,並發訪問量大時使用效率很高(和NAT模式比)。

3、因DR模式是通過MAC地址的改寫機制實現的轉發,因此,所有RS節點和調度器LB 只能在一個局域網LAN中(小缺點)。

4、需要註意RS節點的VTP的綁定(lo:vip,lo1:vip)和ARP抑制問題。

5、RS節點的默認網關不需要是調度器LB的DIP,而直接是IDC機房分配的上 級路由器的IP (這是RS帶有外網IP地址的情況),理論上來說只要RS可以出網即可,不是必須要配置外網IP。

6、由於DR模式的調度器僅進行了目的MAC地址的改寫,因此,調度器LB無法改變請求的報文的目的端口(和NAT要區別)。 7、當前,調度器LB支持幾乎所有的UNIX,LINUX系統,但目前不支持WINDOWS系統。真實服務器RS節點可以是WINDOWS系統。 8、總的來說DR模式效率很高,但是配置也較麻煩,因此,訪問量不是特別大的公司可以 用haproxy/nginx取代之。這符合運維的原則:簡單、易用、高效。日2000W PV或並發請 求1萬以下都可以考慮用haproxy/nginx (LVS的NAT模式) 9、直接對外的訪問業務,例如:web服務做RS節點,RS最好用公網IP地址。如果不直 接對外的業務,例如:MySQL,存儲系統RS節點,最好只用內部IP地址。

NAT模式:

1、NAT技術將請求的報文(DNAT)和響應的報文(SNAT),通過調度器地址重寫然後 在轉發發給內部的服務器,報文返回時在改寫成原來的用戶請求的地址。

2、只需要在調度器LB上配置WAN公網IP即可,調度器也要有私有LAN IP和內部RS節點通信。

3、每臺內部RS節點的網關地址,必須要配置成調度器LB的私有LAN內物理網卡地址(LDIP),這樣才能確保數據報文返回時仍然經過調度器LB。

4、由於請求與響應的數據報文都經過調度器LB,因此,網站訪問量大時,調度器LB有較大瓶頸,一般要求最多10-20臺節點。

5、NAT模式支持對IP及端口的轉換,即用戶請求10.0.0.1:80,可以通過調度器轉換到 RS 節點的10.0.0.2:8080 (DR和TUN模式不具備的)

6、所有NAT內部RS節點只需配置私有LAN IP即可。

7、由於數據包來回都需要經過調度器,因此要開啟內核轉發net.ipv4.ip_forward = 1

當然也包括iptables防火墻的forward功能(DR和TUN模式不需要)。

其他模式的負載均衡不太常用,這裏不做詳細說明。tunnel模式主要是把ip前端包裝一個頭,適合用於跨機房的情況。fullnat則是淘寶使用的負載均衡模式。


關於LVS的調度算法:
固定調度算法:rr,wrr,dh;sh

動態調度算法:wlc,lc,lblc,lblcr,SED,NQ(後兩種官方站點沒提到,編譯LVS,make過 程可以看到 rr|wrr|lc|wlc|lblc|lblcrjdli|sli|sed|nq)

3常用種調度算法見如下:
rr 輪循調度(Round-Robin):
它將請求依次分配不同的RS節點,也就是在RS節點中 均攤請求。這種箅法簡單,但是只適合於RS節點處理性能相差不大的情況。

wrr:
加權輪循調度(Weighted Round-Robin),它將依據不同RS節點的權值分配任務。權值較高的RS將優先獲得任務,並且分配到的連接數將比權值較低的RS節點更多。 相同權值的RS得到相同數目的連接數。

Wlc加權最小連接數調度算法:
假設各臺RS的全職依次為Wi,當前tcp連接數依次為Ti,依次去Ti/Wi為最小的RS作為下一個分配的RS

一、lvs服務的配置方法
1.安裝內核開發包

[[email protected] ~]# yum install -y kernel-devel
[[email protected] ~]# ln -s /usr/src/kernels/3.10.0-514.16.1.el7.x86_64/ /usr/src/linux
[[email protected] ~]# yum install -y ipvsadm

2.裝載ip_vs模塊到內核

[[email protected] ~]# lsmod |grep ip_vs
[[email protected] ~]# modprobe ip_vs
[[email protected] ~]# lsmod |grep ip_vs
ip_vs 141092 0 
nf_conntrack 111302 6 ip_vs,nf_nat,nf_nat_ipv4,xt_conntrack,nf_nat_masquerade_ipv4,nf_conntrack_ipv4
libcrc32c 12644 3 xfs,ip_vs,dm_persistent_data

3.手工添加lvs轉發

[[email protected] ~]# ifconfig eth0:0 192.168.3.177/24 up
[[email protected] ~]# route add -host 192.168.3.177 dev eth0
[[email protected] ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.3.1 0.0.0.0 UG 100 0 0 eth0
172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0
192.168.3.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
192.168.3.177 0.0.0.0 255.255.255.255 UH 0 0 0 eth0

4.添加lvs服務並增加兩臺RS 192.168.3.12 和 192.168.3.13

[[email protected] ~]# ipvsadm -C # clear the whole tables 
[[email protected] ~]# ipvsadm --set 30 5 60    # set tcp tcpfin udp

[[email protected] ~]# ipvsadm -A -t 192.168.3.177:80 -s rr -p 20
[[email protected] ~]# ipvsadm -a -t 192.168.3.177:80 -r 192.168.3.12 -g -w 1
[[email protected] ~]# ipvsadm -a -t 192.168.3.177:80 -r 192.168.3.13 -g -w 1

[[email protected] ~]# ipvsadm -L -n
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.3.177:80 rr persistent 20
-> 192.168.3.12:80 Route 1 0 6 
-> 192.168.3.13:80 Route 1 0 1

刪除方法:

[[email protected] ~]# ipvsadm -D -t 192.168.3.177:80

此時訪問http://192.168.3.177/不出意外是無法訪問的

rs01操作:

[[email protected] ~]# ifconfig lo:0 192.168.3.177/32 up
[[email protected] ~]# route add -host 192.168.3.177 dev lo
[[email protected] ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.3.177 0.0.0.0 255.255.255.255 UH 0 0 0 lo
192.168.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0
0.0.0.0 192.168.3.1 0.0.0.0 UG 0 0 0 eth0

rs02操作:

[[email protected] ~]# ifconfig lo:0 192.168.3.177/32 up
[[email protected] ~]# route add -host 192.168.3.177 dev lo
[[email protected] ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.3.177 0.0.0.0 255.255.255.255 UH 0 0 0 lo
192.168.3.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0
0.0.0.0 192.168.3.1 0.0.0.0 UG 0 0 0 eth0

5.在RS端配置抑制ARP響應

echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore

lvs腳本:
[[email protected] ~]# cat ipvs.sh

#!/bin/bash

VIP=192.168.3.177
PORT=80
RIP=(
192.168.3.12
192.168.3.13
)
start(){
ipvsadm -C
ipvsadm --set 30 5 60
ipvsadm -A -t $VIP:$PORT -s rr -p20
for ((i=0;i<${#RIP[*]};i++))
do
ipvsadm -a -t $VIP:$PORT -r ${RIP[$i]} -g -w 1
done
}
stop(){
ipvsadm -C
}

main(){

case $1 in
start)
start
echo "ipvs is started"
;;
stop)
stop
echo "ipvs is stoped"
;;
restart)
stop
echo "ipvs is stoped"
start
echo "ipvs is started"
;;
*)
echo "USAGE:$0 {start|stop|restart}"
esac
}
main $1

二、keepalived的常用配置

1.在lvs節點上安裝keepalived軟件
# yum install -y keepalived

2.修改keepalived配置,並重啟keepalived軟件
# systemctl restart keepalived

主節點配置:

# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
[email protected]
}
notification_email_from haproxy-[email protected]
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id lvs_01
}

vrrp_instance VI_1 {
interface eth0
state MASTER
virtual_router_id 198
priority 150
advert_int 3
authentication {
auth_type PASS
auth_pass 1111
}

virtual_ipaddress {
192.168.3.177
}

}

backup節點配置:

# cat keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
[email protected]
}
notification_email_from haproxy-[email protected]
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id lvs_02
}

vrrp_instance VI_1 {
interface eth0
state BACKUP
virtual_router_id 198
priority 150
advert_int 3
authentication {
auth_type PASS
auth_pass 1111
}

virtual_ipaddress {
192.168.3.177
}

}

可以看到vip 192.168.3.177漂移到了master 192.168.3.198上

[[email protected] keepalived]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host 
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:50:56:3b:dc:7e brd ff:ff:ff:ff:ff:ff
inet 192.168.3.198/24 brd 192.168.3.255 scope global eth0
valid_lft forever preferred_lft forever
inet 192.168.3.177/32 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::250:56ff:fe3b:dc7e/64 scope link 
valid_lft forever preferred_lft forever

3.雙實例配置方法:

[[email protected] keepalived]# cat keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
[email protected]
}
notification_email_from haproxy-[email protected]
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id lvs_01
}

vrrp_instance VI_1 {
interface eth0
state MASTER
virtual_router_id 198
priority 150
advert_int 3
authentication {
auth_type PASS
auth_pass 1111
}

virtual_ipaddress {
192.168.3.177
}

}

vrrp_instance VI_2 {
interface eth0
state BACKUP
virtual_router_id 199
priority 100
advert_int 3
authentication {
auth_type PASS
auth_pass 1111
}

virtual_ipaddress {
192.168.3.188
}

}

互備的實例配置:

[[email protected] keepalived]# cat keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
[email protected]
}
notification_email_from haproxy-[email protected]
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id lvs_02
}

vrrp_instance VI_1 {
interface eth0
state BACKUP
virtual_router_id 198
priority 150
advert_int 3
authentication {
auth_type PASS
auth_pass 1111
}

virtual_ipaddress {
192.168.3.177
}

}

vrrp_instance VI_2 {
interface eth0
state MASTER
virtual_router_id 199
priority 150
advert_int 3
authentication {
auth_type PASS
auth_pass 1111
}

virtual_ipaddress {
192.168.3.188
}

}

三、構建實戰:LVS+Keepalived實現負載均衡

1.實驗結構總覽

技術分享

(1)本次基於centsos系統所構成的一個服務器集群,其中兩臺負載均衡服務器(一臺為主機,另一臺為備機),另外兩臺作為真實的Web服務器(向外部提供http服務,這裏僅僅使用了CentOS的nginx服務。

(2)本次實驗基於DR負載均衡模式,設置了一個VIP(Virtual IP)為192.168.3.177,用戶只需要訪問這個IP地址即可獲得網頁服務,在生產環境中一般將域名解析指向VIP地址。其中,負載均衡主機為192.168.3.198,備機為192.168.3.200。Web服務器A為192.168.3.12,Web服務器B為192.168.3.13。


2.編輯realserver腳本文件(主要是自動完成ARP抑制的設置)

# vim /etc/init.d/realserver

SNS_VIP=192.168.3.177
#source /etc/rc.d/init.d/functions
case "$1" in
start)
       echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
       echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
       echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
       echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
       sysctl -p >/dev/null 2>&1
       echo "RealServer Start OK"
       ;;
stop)
       echo "0" >/proc/sys/net/ipv4/conf/lo/arp_ignore
       echo "0" >/proc/sys/net/ipv4/conf/lo/arp_announce
       echo "0" >/proc/sys/net/ipv4/conf/all/arp_ignore
       echo "0" >/proc/sys/net/ipv4/conf/all/arp_announce
       echo "RealServer Stoped"
       ;;
*)
       echo "Usage: $0 {start|stop}"
       exit 1
esac


這裏我們設置虛擬IP為:192.168.3.177

③保存腳本文件後更改該文件權限:chmod 755 /etc/init.d/realserver

④開啟realserver服務:/etc/init.d/realserver start

3.配置主負載服務器

安裝Keepalived相關包

yum install -y keepalived

(2)編輯keepalived.conf配置文件

①進入keepalived.conf所在目錄:cd /etc/keepalived

②首先清除掉keepalived原有配置:> keepalived.conf

③重新編輯keepalived配置文件:vi keepalived.conf

global_defs {  
   notification_email {  
         [email protected]  
   }  
   notification_email_from sns-[email protected]  
   smtp_server 192.168.3.198 
   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 {  
        192.168.3.177  #定義虛擬IP(VIP)為192.168.2.33,可多設,每行一個
    }  
}  
# 定義對外提供服務的LVS的VIP以及port
virtual_server 192.168.3.177 80 {  
    delay_loop 6 # 設置健康檢查時間,單位是秒                    
    lb_algo rr # 設置負載調度的算法為wlc                   
    lb_kind DR # 設置LVS實現負載的機制,有NAT、TUN、DR三個模式   
    nat_mask 255.255.255.0                
    persistence_timeout 0
    protocol TCP                  
    real_server 192.168.3.12 80 {  # 指定real server1的IP地址
        weight 3   # 配置節點權值,數字越大權重越高              
        TCP_CHECK {  
        connect_timeout 10         
        nb_get_retry 3  
        delay_before_retry 3  
        connect_port 80  
        }  
    }  
    real_server 192.168.3.13 80 {  # 指定real server2的IP地址
        weight 3  # 配置節點權值,數字越大權重越高  
        TCP_CHECK {  
        connect_timeout 10  
        nb_get_retry 3  
        delay_before_retry 3  
        connect_port 80  
        }  
     }  
}

重新啟動keepalived服務
systemctl restart keepalived

4.配置從負載服務器

從負載服務器與主負載服務器大致相同,只是在keepalived的配置文件中需要改以下兩處:

(1)將state由MASTER改為BACKUP

(2)將priority由100改為99

global_defs {  
   notification_email {  
         [email protected]  
   }  
   notification_email_from sns-[email protected]  
   smtp_server 192.168.3.200
   smtp_connection_timeout 30
   router_id LVS_DEVEL  # 設置lvs的id,在一個網絡內應該是唯一的
}  
vrrp_instance VI_1 {  
    state BACKUP #指定Keepalived的角色,MASTER為主,BACKUP為備          
    interface eth0  #指定Keepalived的角色,MASTER為主,BACKUP為備
    virtual_router_id 51  #虛擬路由編號,主備要一致
    priority 99  #定義優先級,數字越大,優先級越高,主DR必須大於備用DR    
    advert_int 1  #檢查間隔,默認為1s
    authentication {  
        auth_type PASS  
        auth_pass 1111  
    }  
    virtual_ipaddress {  
        192.168.3.177  #定義虛擬IP(VIP)為192.168.2.33,可多設,每行一個
    }  
}  
# 定義對外提供服務的LVS的VIP以及port
virtual_server 192.168.3.177 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 192.168.3.12 80 {  # 指定real server1的IP地址
        weight 3   # 配置節點權值,數字越大權重越高              
        TCP_CHECK {  
        connect_timeout 10         
        nb_get_retry 3  
        delay_before_retry 3  
        connect_port 80  
        }  
    }  
    real_server 192.168.3.13 80 {  # 指定real server2的IP地址
        weight 3  # 配置節點權值,數字越大權重越高  
        TCP_CHECK {  
        connect_timeout 10  
        nb_get_retry 3  
        delay_before_retry 3  
        connect_port 80  
        }  
     }  
}

停掉主節點的keepalived服務vip就漂移到了備用節點上,再次啟動主節點VIP再次回到主節點上

lvs+keepalived實現負載均衡