用LVS+Keepalived实现高可用负载均衡,简单来说就是由LVS提供负载均衡,keepalived通过对rs进行健康检查、对主备机(director)进行故障自动切换,实现高可用。

(本文永久地址:http://woymk.blog.51cto.com/10000269/1927034)

1. LVS NAT模式配置
准备三台服务器,一台director, 两台real server
dr1: 外网ip 192.168.75.130,内网ip 10.1.1.10

两台real server
rs1: 内网ip 10.1.1.11
rs2: 内网ip 10.1.1.12

两台real server的内网网关设置为dr1的内网ip 10.1.1.10

两个real server上都安装apache或者nginx(详细安装方法请参考之前的LAMP环境搭建)

dr1上安装ipvsadm

yum install -y  ipvsadm
vi /usr/local/sbin/lvs_nat.sh
增加
#! /bin/bash
# director 服务器上开启路由转发功能:
echo 1 > /proc/sys/net/ipv4/ip_forward
# 关闭icmp的重定向
echo 0 > /proc/sys/net/ipv4/conf/all/send_redirects
echo 0 > /proc/sys/net/ipv4/conf/default/send_redirects
echo 0 > /proc/sys/net/ipv4/conf/eth0/send_redirects
echo 0 > /proc/sys/net/ipv4/conf/eth1/send_redirects

# director 设置nat防火墙
iptables -t nat -F
iptables -t nat -X
iptables -t nat -A POSTROUTING -s 10.1.1.0/24  -j MASQUERADE
# director设置ipvsadm
IPVSADM='/sbin/ipvsadm'
$IPVSADM -C
$IPVSADM -A -t 192.168.75.130:80 -s wrr
$IPVSADM -a -t 192.168.75.130:80 -r 10.1.1.11:80 -m -w 1
$IPVSADM -a -t 192.168.75.130:80 -r 10.1.1.12:80 -m -w 1


运行脚本
/bin/bash /usr/local/sbin/lvs_nat.sh


通过浏览器测试两台机器上的web内容,为了区分开,我们可以把apache的默认页修改一下:
rs1上: echo "

This is web1!

" > /usr/local/apache2/htdocs/index.html
rs2上: echo "

This is web2!

" > /usr/local/apache2/htdocs/index.html


找一台电脑测试:

[root@local ~]# curl 192.168.75.130

This is web1!


[root@local ~]# curl 192.168.75.130

This is web2!


[root@local ~]# curl 192.168.75.130

This is web1!


[root@local ~]# curl 192.168.75.130

This is web2!


在dr1上查看当前连接情况

[root@dr1 ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.75.130:80 wrr
  -> 10.1.1.11:80                 Masq    1      0          2
  -> 10.1.1.12:80                 Masq    1      0          2


2. LVS DR模式配置
准备三台服务器:
dr1

eth0 192.168.75.130

vip eth0:0: 192.168.75.100
rs1

eth0 rip: 192.168.75.131

vip lo:0: 192.168.75.100

rs2

eth0 rip: 192.168.75.132

vip lo:0: 192.168.75.100


在dr1上操作
vi /usr/local/sbin/lvs_dr.sh
增加

#! /bin/bash
echo 1 > /proc/sys/net/ipv4/ip_forward
ipv=/sbin/ipvsadm
vip=192.168.75.100
rs1=192.168.75.131
rs2=192.168.31.132
ifconfig eth0:0 $vip broadcast $vip netmask 255.255.255.255 up
route add -host $vip dev eth0:0
$ipv -C
$ipv -A -t $vip:80 -s wrr
$ipv -a -t $vip:80 -r $rs1:80 -g -w 1
$ipv -a -t $vip:80 -r $rs2:80 -g -w 1


两台rs上:

vi /usr/local/sbin/lvs_dr_rs.sh

增加
#! /bin/bash
vip=192.168.75.100
ifconfig lo:0 $vip broadcast $vip netmask 255.255.255.255 up
route add -host $vip lo:0
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


然后dr1上执行

bash /usr/local/sbin/lvs_dr.sh

两台rs上执行

bash /usr/local/sbin/lvs_dr_rs.sh


找一台电脑测试:

[root@local ~]# curl 192.168.75.100

This is web2!


[root@local ~]# curl 192.168.75.100

This is web1!


[root@local ~]# curl 192.168.75.100

This is web2!


[root@local ~]# curl 192.168.75.100

This is web1!


在dr1上查看当前连接情况

[root@dr1 ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.75.100:80 wrr
  -> 192.168.75.131:80            Route   1      0          2
  -> 192.168.75.132:80            Route   1      0          2


3. LVS主要的调度算法
 
1:轮询算法(RR)就是按依次循环的方式将请求调度到不同的服务器上,该算法最大的特点就是实现简单。轮询算法假设所有的服务器处理请求的能力都是一样的,调度器会将所有的请求平均分配给每个真实服务器。


2:加权轮询算法(WRR)主要是对轮询算法的一种优化与补充,LVS会考虑每台服务器的性能,并给每台服务器添加一个权值,如果服务器A的权值为1,服务器B的权值为2,则调度到服务器B的请求会是服务器A的两倍。权值越高的服务器,处理的请求越多。


3:最小连接调度算法(LC)将把请求调度到连续数量最小的服务器上。


4:加权最小连接算法(WLC)则是给每台服务器一个权值,调度器会尽可能保持服务器连接数量与权值之间的平衡。


5:基于局部性的最少连接调度算法(lblc)是请求数据包的目标IP地址的一种调度算法,该算法先根据请求的目标IP地址寻找最近的该目标IP地址所有使用的服务器,如果这台服务器依然可用,并且用能力处理该请求,调度器会尽量选择相同的服务器,否则会继续选择其他可行的服务器。


6:带复杂的基于局部性最少的连接算法(lblcr)激励的不是一个目标IP与一台服务器之间的连接记录,他会维护一个目标IP到一组服务器之间的映射关系,防止单点服务器负责过高。


7:目标地址散列调度算法(DH)也是根据目标IP地址通过散列函数将目标IP与服务器建立映射关系,出现服务器不可用或负载过高的情况下,发往该目标IP的请求会固定发给该服务器。


8:源地址散列调度算法(SH)与目标地址散列调度算法类似,但它是根据源地址散列算法进行静态分配固定的服务器资源。


4. LVS + keepalived实现高可用负载均衡(DR模式)

前面lvs已经成功实现了负载均衡,如果某台real server发生故障该怎么办呢?

这时就用到了keepalived,它可以对后端服务器进行健康检查,保证了后端服务器的高可用;同时,keepalived还使用了VRRP协议保证了主备机(Director)之间的高可用。


下面我们就开始配置LVS+keepalived

在刚才“LVS DR模式配置”的基础上增加一台备用director(dr2)


清除之前的配置,在dr1上执行

ipvsadm -C
ifconfig eth0:0down

yum install -y keepalived
安装好后,编辑配置文件 
vi /etc/keepalived/keepalived.conf
清空原文,加入如下内容:
vrrp_instance VI_1 {
     state MASTER                 #备用服务器上为 BACKUP
     interface eth0
     virtual_router_id 51
     priority 100                 #备用服务器上为90
     advert_int 1
     authentication {
         auth_type PASS
         auth_pass 1234
     }
     virtual_ipaddress {
         192.168.75.100
     }
}
virtual_server 192.168.75.100 80 {
     delay_loop 6                 #(每隔10秒查询realserver状态)
     lb_algo wlc                  #(lvs 算法)
     lb_kind DR                   #(Direct Route)
     persistence_timeout 60       #(同一IP的连接60秒内被分配到同一台realserver)
     protocol TCP                 #(用TCP协议检查realserver状态)

     real_server 192.168.75.131 80 {
         weight 100               #(权重)
         TCP_CHECK {
         connect_timeout 10       #(10秒无响应超时)
         nb_get_retry 3
         delay_before_retry 3
         connect_port 80
         }
     }
     real_server 192.168.75.132 80 {
         weight 100
         TCP_CHECK {
         connect_timeout 10
         nb_get_retry 3
         delay_before_retry 3
         connect_port 80
         }
     }
}


在dr2上执行
yum install -y keepalived
yum install -y ipvsadm

把dr1上的配置文拷贝过来

scp 192.168.75.130:/etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf


vi /etc/keepalived/keepalived.conf

从director的配置文件只需要修改

state MASTER  -> state BACKUP
priority 100 -> priority 90


配置完keepalived后,需要开启端口转发(主从都要做):
echo 1 > /proc/sys/net/ipv4/ip_forward

然后,两个rs上执行 /usr/local/sbin/lvs_dr_rs.sh 脚本
最后,分别在两个director上启动keepalived服务,先主后从
/etc/init.d/keepalived start


注:启动keepalived服务会自动生成vip和ipvsadm规则,不需要再去执行上面提到的/usr/local/sbin/lvs_dr.sh 脚本。


测试

找一台电脑用crul测试:

[root@local ~]# curl 192.168.75.100

This is web2!


[root@local ~]# curl 192.168.75.100

This is web1!


[root@local ~]# curl 192.168.75.100

This is web2!


[root@local ~]# curl 192.168.75.100

This is web1!


模拟主director出现故障:

把主director上的keepalived服务停掉

[root@dr1 ~]# /etc/init.d/keepalived stop
停止 keepalived:                                          [确定]

在从director上查看日志

[root@dr2 ~]# tail -f /var/log/messages

May 18 12:10:56 dr2 Keepalived_vrrp[1641]: VRRP_Instance(VI_1) Transition to MASTER STATE
May 18 12:10:57 dr2 Keepalived_vrrp[1641]: VRRP_Instance(VI_1) Entering MASTER STATE
May 18 12:10:57 dr2 Keepalived_vrrp[1641]: VRRP_Instance(VI_1) setting protocol VIPs.
May 18 12:10:57 dr2 Keepalived_vrrp[1641]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.75.100
May 18 12:10:57 dr2 Keepalived_healthcheckers[1640]: Netlink reflector reports IP 192.168.75.100 added
May 18 12:11:02 dr2 Keepalived_vrrp[1641]: VRRP_Instance(VI_1) Sending gratuitous ARPs on eth0 for 192.168.75.100

已经成功切换到从节点上


模拟real server出现故障:

把rs2上的httpd服务停掉

[root@rs2 ~]# /etc/init.d/httpd stop


找一台电脑用crul测试

[root@local ~]# curl 192.168.75.100

This is web1!


[root@local ~]# curl 192.168.75.100

This is web1!


[root@local ~]# curl 192.168.75.100

This is web1!


[root@local ~]# curl 192.168.75.100

This is web1!


只有rs1可以访问到,rs2已被移除