首页 > 代码库 > lvs+keepalived实现负载均衡

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.安装内核开发包

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

2.装载ip_vs模块到内核

[root@slave02 ~]# lsmod |grep ip_vs
[root@slave02 ~]# modprobe ip_vs
[root@slave02 ~]# 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转发

[root@slave02 ~]# ifconfig eth0:0 192.168.3.177/24 up
[root@slave02 ~]# route add -host 192.168.3.177 dev eth0
[root@slave02 ~]# 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

[root@slave02 ~]# ipvsadm -C # clear the whole tables 
[root@slave02 ~]# ipvsadm --set 30 5 60    # set tcp tcpfin udp

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

[root@slave02 ~]# 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

 

删除方法:

[root@slave02 ~]# ipvsadm -D -t 192.168.3.177:80

此时访问http://192.168.3.177/不出意外是无法访问的

rs01操作:

[root@master ~]# ifconfig lo:0 192.168.3.177/32 up
[root@master ~]# route add -host 192.168.3.177 dev lo
[root@master ~]# 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操作:

[root@slave01 ~]# ifconfig lo:0 192.168.3.177/32 up
[root@slave01 ~]# route add -host 192.168.3.177 dev lo
[root@slave01 ~]# 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脚本:
[root@slave02 ~]# 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 {
root@chinasoft.com
}
notification_email_from haproxy-ha@chinasoft.com
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 {
root@chinasoft.com
}
notification_email_from haproxy-ha@chinasoft.com
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上

[root@slave02 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.双实例配置方法:

[root@slave02 keepalived]# cat keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
root@chinasoft.com
}
notification_email_from haproxy-ha@chinasoft.com
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
}

}

 

互备的实例配置:

[root@manager keepalived]# cat keepalived.conf
! Configuration File for keepalived
global_defs {
notification_email {
root@chinasoft.com
}
notification_email_from haproxy-ha@chinasoft.com
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 {  
         edisonchou@hotmail.com  
   }  
   notification_email_from sns-lvs@gmail.com  
   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 {  
         edisonchou@hotmail.com  
   }  
   notification_email_from sns-lvs@gmail.com  
   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实现负载均衡