lvs+keepalived实现web集群高可用性
负载均衡集群的概念
负载均衡是设计分布式系统架构必须要考虑的因素之一,它指的是通过调度分发的方式尽可能将“请求”、“访问”的压力负载平均分摊到集群中的各个节点,避免有些节点负载太高导致访问延迟,而有些节点负载很小导致资源浪费。这样,每个节点都可以承担一定的访问请求负载压力,并且可以实现访问请求在各节点之间的动态分配,以实现负载均衡,从而为企业提供更高性能,更加稳定的系统架构解决方案。
高可用集群的概念
高可用是指以减少服务中断时间或者避免服务中断为目标的技术,它也是分布式系统架构中必须要考虑的因素之一。集群中节点之间进行心跳检查,可以实现对整个集群中的节点健康状态的检测,如果某个节点失效,它的备节点将在几秒钟的时间内接管它的工作。因此对于用户而言,服务总是可以访问的。
一点点概念
1,directory server 负载均衡器(DR)
2,real server 提供服务的真实服务器
3,VIP 虚拟IP
4,CIP 客户端的IP
5,DIP directory server的IP
6,RIP real server的IP
什么是lvs?
lvs全称是linux virtual server,基于IP负载均衡技术和基于内容请求分发技术。它通过一个资源调度器将请求均衡地分发到不同的服务器上,从而将一组服务器构成一个高性能的、高可用的虚拟服务器。
lvs有三种类型:
①lvs-nat模型:请求报文到达调度器(DR)的时候,DR将目的IP(VIP)转换成真正的服务器地址再根据调度算法,将请求转发给后端真实的服务器;真实服务器的响应报文通过调度器时,报文的源地址被转换成(RIP),再返回给客户端,完成整个负载调度过程。由于请求报文和回应报文都必须经过DR,所以DR会成为性能的瓶颈。这种模型的VIP和RIP可以在不同的网段,值得注意的是:真实服务器的网关必须指向DR。
②lvs-dr模型:DR模型是通过把请求报文的MAC地址改写成真实服务器的MAC地址直接把请求发送给真实服务器,而真实服务器将响应直接返回给客户端。对于DR模型,由于请求报文是通过广播的方式在LAN传输,所以VIP和RIP必须在同一个网段,否则广播后所有的请求报文都会丢失。
③lvs-tun模型:调度器会把请求报文通过IP隧道转发到真实服务器,而真实服务器将响应直接返回给客户端,所以调度器只处理请求报文,不处理响应报文。这种模型的lvs需要在所有的真实服务器上绑定VIP,VIP和RIP可以不在同一个网段。
keepalived又是什么?
keepalived是一款轻量级的高可用软件,它只能实现对IP资源的高可用。主要通过虚拟路由冗余协议(VRRP)实现高可用的功能。在非双主keepalived集群中,会依靠优先级选举出一个主节点,IP资源会优先绑定到主节点,其他节点成为备节点,主节点与备节点之间会通过检查心跳线来检测对方的存活,一旦主节点宕机,备用节点就抢占IP资源,当主节点恢复正常,备节点又会释放IP资源给主节点。
实验:lvs+keepalived
主机名 | 角色 | IP | ||
lvs-master | 主调度器 | 172.16.1.136/24 | ||
lvs-backup | 备调度器 | 172.16.1.133/24 | ||
web1 | 真实服务器 | 172.16.1.140/24 | ||
web2 | 真实服务器 | 172.16.1.137/24 |
||
client |
客户端 |
vip | 172.16.1.111/24 |
//所有的服务器都要同步时间
ntpdate time.nist.gov
crontab -l
*/10 * * * * ntpdate time.nist.gov
real server的配置
关闭防火墙和selinux
[root@web1 ~]#systemctl stop firewalld
[root@web1 ~]#systemctl disable firewalld
[root@web1 ~]#vim /etc/selinux/config
SELINUX=disabled
配置web服务
[root@web1 ~]#yum -y install httpd
[root@web1 ~]#echo web1 > /var/www/html/index.html
[root@web1 ~]#systemctl start httpd
----------------------web2同web1,略
lvs-master的配置
关闭防火墙还有selinux
[root@lvs-master~]# systemctl stop firewalld
[root@lvs-master~]# systemctl disable firewalld
[root@lvs-master~]# vim /etc/selinux/config
SELINUX=disabled
配置lvs
[root@lvs-master~]# yum -y install ipvsadm #下载工具
[root@lvs-master~]# vim lvs.sh #通过脚本配置lvs
#!/bin/bash
VIP=172.16.1.111
RIP1=172.16.1.140
RIP2=172.16.1.137
PORT=80
start() {
echo 1 > /proc/sys/net/ipv4/ip_forward
ipvsadm -A -t $VIP:$PORT -s rr
ipvsadm -a -t $VIP:$PORT -r $RIP1:$PORT -g
ipvsadm -a -t $VIP:$PORT -r $RIP2:$PORT -g
}
stop() {
ipvsadm -D -t $VIP:$PORT
echo 0 > /proc/sys/net/ipv4/ip_forward
}
case $1 in
start)
start;;
stop)
stop;;
*)
echo "/root/lvs.sh start|stop";;
esac
由于lvs不能对后端服务器进行健康检测,所以需要写一个检查后端服务健康状态的脚本
[root@lvs-master~]# vim lvs_healcheck.sh
#!/bin/bash
VIP=172.16.1.111
RIP1=172.16.1.140
RIP2=172.16.1.137
PORT=80
for i in $RIP1$RIP2
do
/usr/sbin/ipvsadm -a -t $VIP:$PORT -r $i:$PORT -g &> /dev/null
if ["$?" -ne "0" ];then
curl http://$i &> /dev/null
if [ "$?" == "0" ];then
echo "real server in `date +%F-%T`is ok" >> /tmp/healcheresult
else
/usr/sbin/ipvsadm -d -t $VIP:$PORT -r $i:$PORT
fi
else
curl http://$i &> /dev/null
if [ "$?" == "0" ];then
echo "real server in `date +%F-%T` comme on" >> /tmp/nok
else
/usr/sbin/ipvsadm -d -t $VIP:$PORT -r $i:$PORT
fi
fi
done
编写计划任务,每时每刻执行健康检查脚本
[root@lvs-master~]# crontab -l
* * * * */usr/bin/sh /root/lvs_healcheck.sh
配置keepalived
[root@lvs-master~]# yum -y install keepalived
[root@lvs-master~]# vim /etc/keepalived/keepalived.conf
! ConfigurationFile for keepalived
//全局配置
global_defs {
notification_email {
root@localhost #报警邮件的地址
}
notification_email_from keepalived@localhost #邮件的发送地址
smtp_server 127.0.0.1 #smtp服务器的地址
smtp_connect_timeout 30 #连接smtp服务器的超时时间
router_id LVS_M #keepalived服务器的一个标识
}
//实例配置
vrrp_instanceVI_1 {
state MASTER #指定keepalived的角色,MASTER|BACKUP
interface eno16777736 #实例绑定的网卡,配置VIP必须在已有的网卡添加
virtual_router_id 51 #相同的VRID为一组,决定多播的MAC地址
priority 100 #优先级
advert_int 3 #设定MASTER与BACKUP负载均衡器之间同步检查的时间间隔,单位是秒
authentication {
auth_type PASS #认证类型 PASS|AH
auth_pass redhat #验证密码,在同一个实例,MASTER与BACKUP的密码必须保持一致才可以正常通信
}
virtual_ipaddress {
172.16.1.111 #VIP
}
}
virtual_server 172.16.1.111 80 {
delay_loop 6 #运行情况检查时间,单位是秒
lb_algo rr #负载均衡算法,wlc为最小加权算法,rr为轮询
lb_kind DR #使用DR模式
net_mask 255.255.255.0
persistence_timeout 50
protocol TCP #使用TCP协议检查realserver状态,指定转发协议类型,有TCP和UDP两种
real_server172.16.1.140 80
{
weight 1 #节点权重值
TCP_CHECK #健康检查方式
{
connect_port 80 #连接端口
connect_timeout 5 #连接超时
nb_get_retry 3 #重试次数
delay_before_retry 3 #重试间隔
}
}
real_server172.16.1.137 80
{
weight 1
TCP_CHECK {
connect_port 80
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
}
}
}
重启服务,设置服务开机自动启动
[root@lvs-master~]# touch /etc/sysconfig/ipvsadm
[root@lvs-master~]# systemctl restart ipvsadm
[root@lvs-master~]# systemctl restart keepalived.service
[root@lvs-master~]# systemctl enable ipvsadm
[root@lvs-master~]# systemctl enable keepalived.service
验证是否有vip
[root@lvs-master~]# ip add show|grep 172.16.1.111
inet172.16.1.111/32 scope global eno16777736
lvs-backup的配置
关闭防火墙和selinux
[root@lvs-backup~]# systemctl stop firewalld
[root@lvs-backup~]# systemctl disable firewalld
[root@lvs-backup~]# vim /etc/selinux/config
SELINUX=disabled
配置lvs
[root@lvs-backup~]# yum -y install ipvsadm
[root@lvs-master~]# scp lvs.sh [email protected]:/root/
[root@lvs-master~]# scp lvs_healcheck.sh [email protected]:/root/
[root@lvs-backup~]# chmod +x lvs.sh
[root@lvs-backup~]# chmod +x lvs_healcheck.sh
[root@lvs-backup~]# crontab -l
* * * * */usr/bin/sh /root/lvs_healcheck.sh
配置keepalived
[root@lvs-backup~]# yum -y install keepalived
[root@lvs-master ~]# scp /etc/keepalived/[email protected]:/etc/keepalived/
[root@lvs-backup~]# vim /etc/keepalived/keepalived.conf
! ConfigurationFile for keepalived
global_defs {
notification_email {
root@localhost
}
notification_email_from keepalived@localhost
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_S #修改router_id
}
vrrp_instanceVI_1 {
state BACKUP #修改keepalived角色
interface eno16777736
virtual_router_id 51
priority 99 #修改优先级
advert_int 3
authentication {
auth_type PASS
auth_pass redhat
}
virtual_ipaddress {
172.16.1.111
}
}
virtual_server172.16.1.111 80 {
delay_loop 6
lb_algo rr
lb_kind DR
nat_mask 255.255.255.0
persistence_timeout 50
protocol TCP
real_server 172.16.1.140 80
{
weight 1
TCP_CHECK {
connect_port 80
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
}
real_server 172.16.1.137 80
{
weight 1
TCP_CHECK {
connect_port 80
connect_timeout 5
nb_get_retry 3
delay_before_retry 3
}
}
}
重启服务,设置服务开机自动启动
[root@lvs-backup~]# touch /etc/sysconfig/ipvsadm
[root@lvs-backup~]# systemctl restart ipvsadm
[root@lvs-backup~]# systemctl restart keepalived.service
[root@lvs-backup~]# systemctl enable ipvsadm
[root@lvs-backup~]# systemctl enable keepalived.service
在lvs-master和lvs-backup上创建集群服务
[root@lvs-master~]# ./lvs.sh start
[root@lvs-master~]# ipvsadm -L -n
IP VirtualServer version 1.2.1 (size=4096)
ProtLocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.1.111:80 rr
-> 172.16.1.137:80 Route 1 0 0
-> 172.16.1.140:80 Route 1 0 0
[root@lvs-backup~]# ./lvs.sh start
[root@lvs-backup~]# ipvsadm -L -n
IP VirtualServer version 1.2.1 (size=4096)
Prot LocalAddress:PortScheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.1.111:80 rr
-> 172.16.1.137:80 Route 1 0 0
-> 172.16.1.140:80 Route 1 0 0
验证
[root@client~]#curl http://172.16.1.111
web1
[root@client~]#curl http://172.16.1.111
web2
[root@lvs-master~]# ipvsadm -L -n
IP VirtualServer version 1.2.1 (size=4096)
ProtLocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.1.111:80 rr
-> 172.16.1.137:80 Route 1 1 0
-> 172.16.1.140:80 Route 1 1 0
#lvs-master上ActiveConn会一直增加,因为所有访问vip的连接都会经过lvs-master进行调度,转发到后端real server
[root@lvs-backup~]# ipvsadm -L -n
IP VirtualServer version 1.2.1 (size=4096)
ProtLocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.1.111:80 rr
-> 172.16.1.137:80 Route 1 0 0
-> 172.16.1.140:80 Route 1 0 0
#除非lvs-master宕机,lvs-backup上ActiveConn会一直为0,因为没有请求转发到lvs-backup进行调度
关闭lvs-master模仿宕机
[root@lvs-backup~]# ip add show | grep 172.16.1.111
inet 172.16.1.111/32 scope globaleno16777736
[root@client~]#curl http://172.16.1.111
web1
[root@client~]#curl http://172.16.1.111
web2
#由于此时lvs-backup仍然正常工作,所有访问vip的连接经过lvs-backup进行调度,转发到后端real server,所有还可以访问到后端的real server
再关闭lvs-backup模仿宕机
[root@client~]# curl http://172.16.1.111
curl: (7)Failed connect to 172.16.1.111:80; Connection timed out
#网络中没有可用的lvs负载均衡器,所有访问vip的连接无法被调度转发到real server
开启lvs-master模仿故障恢复
[root@client~]# curl http://172.16.1.111
web1
[root@client~]# curl http://172.16.1.111
web2
#lvs-master正常工作所有访问vip的连接都会经过lvs-master进行调度,转发到后端real server
如有纰漏,欢迎指正。