LVS架构中,不管是NAT模式还是DR模式,当后端的RS宕掉后,调度器依然会把请求转发到宕掉的RS上,这样的结果并不是我们想要的。其实,keepalived就可以解决问题,它不仅仅有高可用的功能,还有负载均衡。也就是说keepalived已经嵌入了LVS功能,完整的keepalived+LVS架构需要有两台调度器实现高可用,提供调度器的只需要一台,另外一台作为备用。这里指演示主keepalived,备用的暂时就省略掉了。
- 主keepalived(调度器):192.168.25.141 (keepalived和ipvsadm)
- 真实服务器rs1:192.168.25.133 (nginx)
- 真实服务器rs2:192.168.25.134 (nginx)
- VIP:192.168.25.100
#安装keepalived
yum install -y keepalived
#安装ipvsadm,这是实现LVS的核心工具
yum install -y ipvsadm
编辑keepalived的配置文件vi /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
#备用服务器上为 BACKUP
state MASTER
#绑定vip的网卡为ens33,根据自己的服务器来设置
interface ens33
virtual_router_id 51
#备用服务器上为90
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.25.110
}
}
virtual_server 192.168.25.110 80 {
#(每隔10秒查询realserver状态)
delay_loop 10
#(lvs 算法)
lb_algo rr
#(DR模式)
lb_kind DR
#(同一IP的连接60秒内被分配到同一台realserver)
persistence_timeout 60
#(用TCP协议检查realserver状态)
protocol TCP
real_server 192.168.25.133 80 {
#(权重)
weight 100
TCP_CHECK {
#(10秒无响应超时)
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 192.168.25.134 80 {
weight 100
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
这里在keepalived的配置文件中定义的LVS模式为DR模式,还需要在两台rs上执行lvs_dr_rs.sh脚本
vi /usr/local/sbin/lvs_dr_rs.sh
#/bin/bash
vip=192.168.25.110
#把vip绑定在lo上,是为了实现rs直接把结果返回给客户端
ifconfig lo:0 $vip broadcast $vip netmask 255.255.255.255 up
route add -host $vip lo:0
#以下操作为更改arp内核参数,目的是为了让rs顺利发送mac地址给客户端
#参考文档www.cnblogs.com/lgfeng/archive/2012/10/16/2726308.html
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
然后执行
sh /usr/local/sbin/lvs_dr_rs.sh
在两台真实服务器上执行完脚本后,执行ip addr可以看到两台服务器的lo上都绑定好了虚拟ip
在lvs的DR模式下,用户的访问请求到达真实服务器后,是直接返回给用户的,而不再经过前端的Director Server,因此,就需要在每个Real server节点上增加虚拟的VIP地址,这样数据才能直接返回给用户。
[root@134 sbin]# 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
inet 192.168.25.110/32 brd 192.168.25.110 scope global lo:0
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
注意:服务器重启之后绑定的这个虚拟ip就没有了,需要再执行一下脚本,所以可以把对这个脚本的执行放到开机自启中。
vi /etc/rc.d/rc.local
sh /usr/local/sbin/lvs_dr_rs.sh
然后添加执行权限chmod +x rc.local。
做完准备工作后,在141上启动keepalived服务systemctl start keepalived
然后执行ip addr,可以看到在ens33上绑定的虚拟ip
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 00:0c:29:4e:c9:44 brd ff:ff:ff:ff:ff:ff
inet 192.168.25.141/24 brd 192.168.25.255 scope global ens33
valid_lft forever preferred_lft forever
inet 192.168.25.110/32 scope global ens33
valid_lft forever preferred_lft forever
inet6 fe80::3579:33c0:e4b7:791d/64 scope link
valid_lft forever preferred_lft forever
检验是否成功,需要在浏览器直接访问vip192.168.25.110,我在前面配的是rr算法,轮询调度(Round-Robin)就是按顺序把请求依次发送给后端的服务器。按道理来说应该是这样,比如我第一次访问vip,给分配到了133服务器,那第二次访问就会分配到134服务器。但并不会这样,你会发现你访问了很多次依然是133服务器。这涉及到lvs调度算法的设计。当访问量变大,访问ip变多的时候就不会有这样的情况了,会平均分配到两台服务器上。
可以这样做实验,我在电脑上访问vip,显示的是133,然后我再开一台虚拟机输入
curl 192.168.25.110
可能就会发现访问到134服务器了,但也不一定。
也可以在调度器141上执行命令ipvsadm -ln查看连接数
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.25.110:80 rr persistent 1
-> 192.168.25.133:80 Route 100 2 0
-> 192.168.25.134:80 Route 100 0 0
可以发现有两台rs。
当我把133的nginx停掉的话,再执行ipvsadm -ln,会发现rs只有一台了
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.25.110:80 rr persistent 1
-> 192.168.25.134:80 Route 100 0 0
遇到的问题:记得要把SELinux关闭掉。还有就是把防火墙关掉。
有时候发现vip无法访问了,首先要检查141上的ens33上是否还绑定着vip,没有的话重启一下keepalived,再检查两台rs上的lo上是否绑定着vip,没有的话重新执行一下脚本。