lvs+keepalived實現負載均衡
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實現負載均衡