上节课我们一起学习了LVS+Nginx负载均衡DR模式的环境搭建,这节我们一起学习下LVS四层+Nginx七层负载均衡环境的搭建和LVS高可用环境搭建。
LVS四层+Nginx七层负载均衡环境的搭建
需求:lvs采用DR模式基本上没有性能瓶颈,用户请求输入至lvs经过负载转发到后台服务上,通过后台服务输出响应给用户。nginx的负载性能远没有lvs好,lvs四层+nginx七层负载的好处是最前端是lvs接收请求进行负载转发,由多个nginx共同完成七层负载,这样nginx的负载性能就可以线性扩展。
环境准备,如下所示,可以看到,与上节课相比多了两台tomcat服务器。
vip:192.168.156.110
lvs-director:192.168.156.35
nginx1:192.168.156.36 安装nginx
nginx2:192.168.156.37 安装nginx
tomcat1:192.168.156.38 安装tomcat
tomcat2:192.168.156.39 安装tomcat
lvs-director服务器的搭建与上节课一样,我们用上节课那个lvs-director就可以了,lvs-nginx1和lvs-nginx2与上节课的唯一不同之处是在nginx.conf配置文件中添加了对tomcat的负载均衡设置,如下图所示。(lvs-nginx1和lvs-nginx2的nginx.conf文件都做如下图所示修改)
上图修改的内容如下
upstream tomcat_server_pool{
server 192.168.156.38:8080;
server 192.168.156.39:8080;
}
location / {
proxy_pass http://tomcat_server_pool;
index index.html index.htm;
}
由于修改了nginx.conf文件,因此要重启nginx服务
[root@lvs-nginx1 conf]# /usr/local/nginx/sbin/nginx -s reload
[root@lvs-nginx2 conf]# /usr/local/nginx/sbin/nginx -s reload
下面我们便新建两台虚拟机,IP分别设置成192.168.156.38和192.168.156.39,关于如何新建虚拟机在上节说过了,这里不啰嗦,要安装tomcat,要有JDK环境,关于如何安装JDK及tomcat,大家可以参考http://blog.csdn.net/u012453843/article/details/72599478这篇博客进行学习。为了区分不同的tomcat首页,我们修改下Tomcat的欢迎页内容,大家可以参考http://blog.csdn.net/u012453843/article/details/72599478这篇博客进行修改。
安装完Tomcat之后,我们访问地址http://192.168.156.110,可以看到我们访问到的tomcat欢迎页出现的规律是两次"lvs-tomcat1"之后是两次"lvs-tomcat2"然后在两次"lvs-tomcat1"如此循环往复,之所以会出现这种请款是因为我们有两个nginx,两个nginx都对两个tomcat进行了负载均衡,两套负载均衡综合在一起便会出现这种现象。如果停止任意一台nginx或停止任意一台tomcat不影响访问。
这样,LVS四层+Nginx七层负载均衡环境便搭建好了!
LVS高可用环境搭建
1.什么是高可用?
lvs作为负载均衡器,所有请求都先到达lvs,可见lvs处于非常重要的位置,如果lvs服务器宕机后端web服务将无法提供服务,影响严重。
为了屏蔽负载均衡服务器的宕机,需要建立一个备份机。主服务器和备份机上都运行高可用(High Availability)监控程序,通过传送诸如“I am alive”这样的信息来监控对方的运行状况。当备份机不能在一定的时间内收到这样的信息时,它就接管主服务器的服务IP并继续提供负载均衡服务;当备份管理器又从主管理器收到“I am alive”这样的信息时,它就释放服务IP地址,这样的主服务器就开始再次提供负载均衡服务。
2.keepalived+lvs实现主备
2.1 什么是keepalived?
keepalived是集群管理中保证集群高可用的一个服务软件,用来防止单点故障。
Keepalived的作用是检测web服务器的状态,如果有一台web服务器死机,或工作出现故障,Keepalived将检测到,并将有故障的web服务器从系统中剔除,当web服务器工作正常后Keepalived自动将web服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的web服务器。
2.2 keepalived工作原理
keepalived是以VRRP协议为实现基础的,VRRP全称Virtual Router Redundancy Protocol,即虚拟路由冗余协议。
虚拟路由冗余协议,可以认为是实现路由器高可用的协议,即将N台提供相同功能的路由器组成一个路由器组,这个组里面有一个master和多个backup,master上面有一个对外提供服务的vip(该路由器所在局域网内其他机器的默认路由为该vip),master会发组播,当backup收不到VRRP包时就认为master宕掉了,这时就需要根据VRRP的优先级来选举一个backup当master。这样的话就可以保证路由器的高可用了。
keepalived主要有三个模块,分别是core、check和VRRP。core模块为keepalived的核心,负责主进程的启动、维护以及全局配置文件的加载和解析。check负责健康检查,包括常见的各种检查方式。VRRP模块是来实现VRRP协议的。
2.3 keepalived+lvs实现主备过程
2.3.1 集群初始状态
2.3.2 主机宕机
2.3.3 主机恢复
2.4 环境准备
vip:192.168.156.110
lvs-director:192.168.156.35 主lvs
lvs-director:192.168.156.40 备lvs
nginx1:192.168.156.36 安装nginx
nginx2:192.168.156.37 安装nginx
tomcat1:192.168.1.200 安装tomcat(实际的服务器,如果没有实际服务器就用虚拟机代替)
tomcat2:192.168.1.201 安装tomcat(实际的服务器,如果没有实际服务器就用虚拟机代替)
tomcat3:114.55.254.239 安装tomcat(实际的服务器,如果没有实际服务器就用虚拟机代替)
2.5 安装keepalived
分别在主备lvs上安装keepalived,关于keepalived的安装,大家可以参考http://blog.csdn.net/u012453843/article/details/72808459这篇博客进行学习。
2.6 配置keepalived
2.6.1 修改主lvs下/etc/keepalived/keepalived.conf文件
! Configuration File for keepalived
global_defs {
notification_email {
1204507593@qq.com #发生故障时发送的邮箱
}
notification_email_from m13633801872@163.com #使用哪个邮箱发送
smtp_server smtp.163.com #发件服务器
smtp_connect_timeout 30 #连接smtp连接超时时间
router_id LVS_DR #机器标识,通常为hostname,但不一定非得是hostname。故障发生时,邮件通知会用到
}
vrrp_script chk_lvs {
script "/etc/keepalived/lvs_check.sh" #监测lvs是否健康的脚本
interval 2 #每隔两秒检查一次
weight -20 #每执行成功一次权重减20
}
vrrp_instance VI_1 {
state MASTER #标示为主lvs
interface eth0 #HA检测端口
virtual_router_id 51 #主备的virtual_router_id 必须相同
priority 100 #优先级,备lvs要比主lvs稍小
advert_int 1 #VRRP Multicast广播周期秒数
authentication { #定义认证
auth_type PASS #认证方式为口令认证
auth_pass 1111 #定义口令
}
track_script {
chk_lvs #与上面vrrp_script chk_lvs的名称要一致
}
virtual_ipaddress { #定义VIP
192.168.156.110 #多个VIP可换行添加
}
}
virtual_server 192.168.156.110 80 {
delay_loop 6 #每隔6秒查看realserver状态
lb_algo wlc #调度算法为加权最小连接数
lb_kind DR #lvs工作模式为DR(直接路由)模式
nat_mask 255.255.255.0
persistence_timeout 50 #同一IP的连接50秒内被分配到同一台realserver(测试时建议改为0)
protocol TCP #用TCP监测realserver的状态
real_server 192.168.156.35 80 { #定义realserver
weight 3 #定义权重
TCP_CHECK { #注意TCP_CHECK和{之间的空格,如果没有的话只会添加第一个realserver
connect_timeout 3 #连接超时时间为3秒
nb_get_retry 3 #重连次数3
delay_before_retry 3 #每次尝试间隔3秒
connect_port 80 #连接端口号 80
}
}
real_server 192.168.156.40 80 { #定义realserver
weight 3 #定义权重
TCP_CHECK { #注意TCP_CHECK和{之间的空格,如果没有的话只会添加第一个realserver
connect_timeout 3 #连接超时时间为3秒
nb_get_retry 3 #重连次数3
delay_before_retry 3 #每次尝试间隔3秒
connect_port 80 #连接端口号 80
}
}
}
2.6.2 修改备lvs下/etc/keepalived/keepalived.conf文件
配置备lvs时需要注意:需要修改state为BACKUP , priority比MASTER低,virtual_router_id和master的值一致
! Configuration File for keepalived
global_defs {
notification_email {
1204507593@qq.com #发生故障时发送的邮箱
}
notification_email_from m13633801872@163.com #使用哪个邮箱发送
smtp_server smtp.163.com #发件服务器
smtp_connect_timeout 30 #连接smtp连接超时时间
router_id LVS_DR_BACK #机器标识,通常为hostname,但不一定非得是hostname。故障发生时,邮件通知会用到
}
vrrp_script chk_lvs {
script "/etc/keepalived/lvs_check.sh" #监测lvs是否健康的脚本
interval 2 #每隔两秒检查一次
weight -20 #每执行成功一次权重减20
}
vrrp_instance VI_1 {
state BACKUP #标示为备份lvs
interface eth0 #HA检测端口
virtual_router_id 51 #主备的virtual_router_id 必须相同
priority 99 #优先级,备lvs要比主lvs稍小
advert_int 1 #VRRP Multicast广播周期秒数
authentication { #定义认证
auth_type PASS #认证方式为口令认证
auth_pass 1111 #定义口令
}
track_script {
chk_lvs #与上面vrrp_script chk_lvs的名称要一致
}
virtual_ipaddress { #定义VIP
192.168.156.110 #多个VIP可换行添加
}
}
virtual_server 192.168.156.110 80 {
delay_loop 6 #每隔6秒查看realserver状态
lb_algo wlc #调度算法为加权最小连接数
lb_kind DR #lvs工作模式为DR(直接路由)模式
nat_mask 255.255.255.0
persistence_timeout 50 #同一IP的连接50秒内被分配到同一台realserver(测试时建议改为0)
protocol TCP #用TCP监测realserver的状态
real_server 192.168.156.35 80 { #定义realserver
weight 3 #定义权重
TCP_CHECK { #注意TCP_CHECK和{之间的空格,如果没有的话只会添加第一个realserver
connect_timeout 3 #连接超时时间为3秒
nb_get_retry 3 #重连次数3
delay_before_retry 3 #每次尝试间隔3秒
connect_port 80 #连接端口号 80
}
}
real_server 192.168.156.40 80 { #定义realserver
weight 3 #定义权重
TCP_CHECK { #注意TCP_CHECK和{之间的空格,如果没有的话只会添加第一个realserver
connect_timeout 3 #连接超时时间为3秒
nb_get_retry 3 #重连次数3
delay_before_retry 3 #每次尝试间隔3秒
connect_port 80 #连接端口号 80
}
}
}
在/etc/keepalived目录下我们新建上面提到的lvs_check.sh脚本,为方便编辑我们还是使用NodePad++来操作,脚本内容如下:
#!/bin/sh
aa=`ipvsadm -ln`
str="Route"
bb=`echo $aa|grep $str|wc -l`
if [ $bb = 0 ];then
service lvsdr start
sleep 3
aa=`ipvsadm -ln`
bb=`echo $aa|grep $str|wc -l`
if [ $bb = 0 ];then
killall keepalived
fi
fi
下面我来解释下上面脚本的意思,其中aa=`ipvsadm -ln`用于查看lvs是否处于启动状态
当lvs没有启动时,回显信息如下
[root@lvs-dr keepalived]# 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.156.110:80 wlc persistent 50
[root@lvs-dr keepalived]#
当lvs处于启动状态时,回显信息如下:可以看到,与上面的信息相比,多了两行(192.168.156.36:80 Route 1 0 0和192.168.156.37:80 Route 1 0 0)。
[root@lvs-dr keepalived]# 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.156.110:80 rr
-> 192.168.156.36:80 Route 1 0 0
-> 192.168.156.37:80 Route 1 0 0
[root@lvs-dr keepalived]#
脚本中str="Route"的意思是,如果lvs启动了,那么多出的两行信息中包含"Route"字符串,而没有启动lvs时是没有"Route"信息的,因此"Route"成了判断条件。
脚本中bb=`echo $aa|grep $str|wc -l`这句代码的意思是判断"ipvsadm -ln"命令的回显信息中包含"Route"的个数。如果是0就代表lvs没有启动,如果大于0就代表lvs已经启动了。
下面两行代码的意思就是如果lvs没有启动,那么就启动lvs服务
if [ $bb = 0 ];then
service lvsdr start
下面几行代码的意思是,我们启动lvs服务后停3秒后再次判断"ipvsadm -ln"的回显信息中是否包含"Route",要判断当前是否包含就必须重新获取回显信息并且重新获取包含数量,如果还是没有包含的话,说明lvs没有正常启动,这时便杀掉主设备的keepalived进程,让备份keepalived进行工作。
sleep 3
aa=`ipvsadm -ln`
bb=`echo $aa|grep $str|wc -l`
if [ $bb = 0 ];then
killall keepalived
fi
写完脚本我们要确保该脚本的格式为unix格式,关于如何做,前面已经说过了,这里不再啰嗦。
我们还需要给该脚本添加执行权限:
[root@lvs-dr keepalived]# chmod +x lvs_check.sh
添加完权限后,可以看到脚本的颜色变深绿色了。
注意:在两台lvs服务器的/etc/keepalived目录下都添加lvs_check.sh脚本。
2.7 测试
先确保没有启动keepalived和lvs,然后使用命令service keepalived start来启动主备keepalived服务,启动完之后,我们使用命令"ipvsadm -ln"来查看lvs的启动状态,发现正常启动了。
[root@lvs-dr keepalived]# 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.156.110:80 rr
-> 192.168.156.36:80 Route 1 1 0
-> 192.168.156.37:80 Route 1 1 0
[root@lvs-dr keepalived]#
这时我们使用ip a来查看下虚拟IP,先来看主lvs设备的虚拟IP信息,如下图所示,发现是有虚拟IP(192.168.156.110)的。
接着,我们再来看下备份lvs设备的虚拟IP信息,如下图所示,发现在eth0这个接口上并没有虚拟IP,在eth0:0上有这个虚拟IP。
出现这种情况似乎与我们想象的不太一样,为了与我们想象的结果一样,我们可以先把主lvs设备的keepalived服务关闭,然后关掉备份lvs设备的keepalived服务之后重启备份lvs设备的keepalived服务。为了让虚拟IP回到主lvs设备上,这时我们再启动主lvs设备的keepalived服务。这时我们再看备份lvs设备,就与我们想象的一致了。
下面我们来测试访问tomcat首页,我们需要在lvs-nginx1和lvs-nginx2两台设备上修改nginx的配置文件,两台设备修改的内容一样,如下图所示。
修改的内容如下
upstream loadbalance {
server 192.168.1.200:8086;
server 192.168.1.201:8086;
server 114.55.254.239:8086;
}
location / {
proxy_pass http://loadbalance;
index index.html index.htm;
}
由于nginx修改了配置文件,因此我们需要重启lvs-nginx1和lvs-nginx2两台服务器
[root@lvs-nginx1 ~]# /usr/local/nginx/sbin/nginx -s reload
[root@lvs-nginx2 ~]# /usr/local/nginx/sbin/nginx -s reload
为了区分三台不同的设备上的tomcat首页,我对tomcat首页进行了标记,这个前面也说过了,这里不啰嗦了。
现在我们便来访问虚拟IP192.168.156.110,刷新它,就会发现我们在tomcat1、tomcat2、tomcat3之间均匀切换,说明负载是起作用的。
为了测试高可用性,我们可以杀掉主keepalived服务,如下
[root@lvs-dr keepalived]# service keepalived stop
停止 keepalived: [确定]
[root@lvs-dr keepalived]#
我们继续访问虚拟IP,发现是没有问题的,我们再重新启动主lvs设备的服务,发现虚拟IP就又回到了主服务器。与我们所画的图是一致的。