一、LVS 负载均衡简介
LVS是Linux VirtualServer的简写,意为Linux虚拟服务器,是虚拟的服务器集群系统,可在UNIX/LINUX平台下实现负载均衡集群功能。LVS 简单工作原理为用户请求LVSVIP,LVS根据转发方式和算法,将请求转发给后端服务器,后端服务器接收到请求,返回给用户,对于用户来说,看不到Web后端具体的应用。
互联网主流可伸缩网络服务有很多结构,但是都有一个共同点,它们都需要一个前端的负载调度器(或者多个进行主从备份)。实现虚拟网络服务的主要技术指出IP负载均衡技术是在负载调度器的实现技术中效率最高的。
已有的IP负载均衡技术中,主要有通过网络地址转换(NAT)将一组服务器构成一个高性能的、高可用的虚拟服务器,通常称之为VS/NAT技术。
在分析VS/NAT的缺点和网络服务的非对称性的基础上,可以通过IP隧道实现虚拟服务器的方法VS/TUN和通过直接路由实现虚拟服务器的方法VS/DR,它们可以极大地提高系统的伸缩性。
总体来说,IP负载均衡技术分为VS/NAT、VS/TUN和VS/DR技术,它们是LVS集群中实现的三种IP负载均衡技术。
二、LVS 负载均衡工作原理
实现LVS负载均衡转发方式有三种,分别为NAT、DR、TUN模式,LVS均衡常见算法包括RR(round-robin)、LC(least_connection)、W(weight)RR、WLC模式等(RR为轮询模式,LC为最少连接模式)。
• LVS NAT原理:
用户请求LVS到达director,director将请求的报文的目标IP地址改为后端的realserverIP地址,同时将报文的目标端口也改成后端选定的realserver相应的端口,最后将报文发送到realserver,realserver将数据返给director,director再把数据发送给用户。因为两次请求都经过director,所以访问量大的话,director会成为瓶颈。
• LVS DR原理:
用户请求LVS到达director,director将请求的报文的目标MAC地址改成后端的realserverMAC地址,目标IP为VIP(不变),源IP为用户IP地址(不变),然后director将报文发送到realserver,realserver检测到目标为自已本地VIP,如果在同一个网段,然后将请求直接返给用户。如果用户跟realserver不在一个网络,则通过网关返回用户。
• LVS TUN原理:
用户请求LVS到达director,director通过IP-TUN加密技术将请求的报文的目标MAC地址改成后端的realserverMAC地址,目标IP为VIP(不变),源IP为用户IP地址(不变),然后director将报文发送到realserver,realserver基于IP-TUN解密,然后检测到目标为自己本地VIP,如果在同一个网段,然后将请求直接返给用户,如果用户跟realserver不在一个网段,则通过网关返给用户。
三、LVS 负载均衡配置
LVS负载均衡技术实现是基于Linux内核模块ipvs,与iptables一样是直接工作在内核中,互联网主流的Linux发行版默认都是已经集成了ipvs模块,只需安装管理工具ipvsadm,安装配置步骤如下:
1、YUM安装:
# yum install ipvsadm-y
2、源码包安装:
# wget http://www.linuxvirtualserver.org/software/kernel-2.6/ipvsadm-1.26.tar.gz
# tar xzvfipvsadm-1.26.tar.gz
# cd ipvsadm-1.26
# make
# make install
3、ipvsadm 配置:
软件安装后,需要进行配置,主要配置方法有三步:添加虚拟服务器IP、添加realserver后端服务及启动LVS服务器VIP地址。
# ipvsadm -A -t192.168.28.88:80 -s rr
# ipvsadm -a -t192.168.28.88:80 -r 192.168.28.134:80 -g -w 2
# ipvsadm -a -t192.168.28.88:80 -r 192.168.28.135:80 -g -w 2
4、可以使用shell脚本自动部署LVS相关软件及配置:
# vim/data/sh/auto_ipvsadm.sh
#!/bin/bash
SNS_VIP=$2
SNS_RIP1=$3
SNS_RIP2=$4
if [ "$1" =="stop" -a -z "$2" ];then
echo"------------------------------------------------------------"
echo-e "\033[32mPlease Enter $0 stop LVS_VIP\n\nEXample: $0 stop192.168.28.133\033[0m"
echo
exit
else
if [-z "$2" -a -z "$3" -a -z "$4" ];then
echo"----------------------------------------------------------"
echo-e "\033[32mPlease Enter Input $0 start VIP REALSERVER1REALSERVER2\n\nEXample: $0 start/stop 192.168.28.88 192.168.28.134192.168.28.135\033[0m"
echo
exit0
fi
fi
./ect/rc.d/init.d/functions
logger $0 called with$1
function IPVSADM(){
/usr/sbin/ipvsadm --set30 5 60
/usr/sbin/ifconfigeth0:0 $SNS_VIP broadcast $SNS_VIP netmask 255.255.255.255 broadcast $SNS_VIPup
/usr/sbin/route add-host $SNS_VIP dev eth0:0
/usr/sbin/ipvsadm -A -t$SNS_VIP:80 -s wlc -p 120
/usr/sbin/ipvsadm -a -t$SNS_VIP:80 -r $SNS_RIP1:80 -g -w 1
/usr/sbin/ipvsadm -a -t$SNS_VIP:80 -r $SNS_RIP2:80 -g -w 1
}
case "$1" in
start)
IPVSADM
echo"-----------------------------------------"
/usr/sbin/ipvsadm -Ln
touch/var/lock/subsys/ipvsadm>/dev/null 2>&1
;;
stop)
/usr/sbin/ipvsadm -C
/usr/sbin/ipvsadm -Z
ifconfig eth0:0 down>>/dev/null 2>&1
route del$SNS_VIP>>/dev/null 2>&1
rm -rf/var/lock/subsys/ipvsadm >/dev/null 2>&1
echo "ipvsadmstopped!"
;;
status)
if [ ! -e/var/lock/subsys/ipvsadm ]
then
echo "ipvsadmstopped!"
exit 1
else
echo "ipvsadmstarted!"
fi
;;
*)
echo "Usae: $0{start|stop|status}"
exit 1
;;
esac
exit 0
5、LVS服务器绑定VIP地址:
VIP=192.168.28.88
ifconfig eth0:0 $VIPnetmask 255.255.255.255 broadcast $SNS_VIP up
/usr/sbin/route add-host $VIP dev eth0:0
6、LVS ipvsadm 配置参数:
-A 增加一台虚拟服务器VIP地址
-t 虚拟服务器提供的是TCP服务
-s 使用的调度算法
-a 在虚拟服务器中增加一台后端真实服务器
-r 指定真实服务器地址
-w 后端真实服务器的权重
-m 设置当前转发方式为NAT模式
-g 模式为直接路由模式
-i 模式为隧道模式
7、查看LVS 转发列表命令为:
# ipvsadm -Ln:
IP Virtual Serverversion 1.2.1 (size=4096)
Prot LocalAddress:PortScheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.28.88:80 rr
-> 192.168.28.134:80 Route 1 0 0
-> 192.168.28.135:80 Route 1 0 0
8、查看LVS连接后端转发信息条目:
# ipvsadm -lnc
IPVS connection entries
pro expire state source virtual destination
TCP 01:43 FIN_WAIT 192.168.28.1:53984 192.168.28.88:80 192.168.28.134:80
TCP 00:37 SYN_RECV 192.168.28.1:53985 192.168.28.88:80 192.168.28.135:80
TCP 00:05 FIN_WAIT 192.168.28.1:53930 192.168.28.88:80 192.168.28.134:80
9、Nginx 客户端realserver 配置VIP脚本:
# vim/etc/init.d/lvsrs #编辑一个lvsrs脚本,并放到/etc/init.d/下
#!/bin/bash
#description : startrealserver
VIP=192.168.28.88
sh/etc/rc.d/init.d/functions
case "$1" in
start)
/usr/sbin/ifconfig lo:0$VIP broadcast $VIP netmask 255.255.255.255 up
/usr/sbin/route add-host $VIP dev 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
echo " start LVSof REALServer"
exit 0
;;
stop)
/usr/sbin/ifconfig lo:0down
/usr/sbin/route del$VIP >/dev/null 2>&1
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 "close LVSDirectorserver"
exit 1
;;
*)
echo "Usage: $0{start|stop}"
exit 1
;;
esac
# chmod 755/etc/init.d/lvsrs #给新增lvsrs脚本一个755权限
# service lvsrsstart #启动lvsrs服务,我环境启动时出错,给一个functions 755权限,按各自环境操作
# chmod 755/etc/rc.d/init.d/functions #给functions755权限
如果单台LVS发生突发情况,例如宕机、发生不可恢复的错误,会导致用户无法访问后端所有的应用程序,可以基于LVS+keepalived实现负载均衡及高可用功能。如果使用了keepalived.conf配置,就不需要执行ipvsadm-A 命令去添加均衡的realserver命令了,所有的配置都在keepalived.conf里面设置即可。
四、LVS + keepalived 配置
• 主MASTER的keepalived.conf配置:
! Configuration Filefor keepalived
global_defs {
notification_email {
ytwu@leqee.com
}
notification_email_from ytwu@leqee.com
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id LVS_DEVEL
vrrp_skip_check_adv_addr
# vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}
#VIP1
vrrp_instance VI_1 {
state MASTER
interface eth0
lvs_sync_daemon_inteface eth0
virtual_router_id 51
priority 110
advert_int 1
nopreempt
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.28.88/24
}
}
virtual_server192.168.28.88 80 {
delay_loop 6
lb_algo wrr
lb_kind DR
persistence_timeout 60
protocol TCP
real_server 192.168.28.134 80 {
weight 100
TCP_CHECK {
connect_port 80
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
}
}
real_server 192.168.28.135 80 {
weight 1
TCP_CHECK {
connect_port 80
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
}
}
}
• 备BACKUP的keepalived.conf配置:
state BACKUP
priority 90
Master keepalived配置state 状态为MASTER,priority设置为110,backup keepalived配置state状态为BACKUP,priority设置为90,转发方式为DR直连路由模式,算采用wrr模式,在LVSbackup服务器写入如上配置,需要注意客户端的配置修改优先级及状态。由于LVS采用LVS采用DR模式,根据DR模式转发原理,需在客户端realserver绑定VIP。
五、LVS DR客户端配置VIP
根据DR模式的工作原理,director与realserver位于同一个物理网络中,当director直接将请求转发给realserver时,如果realserver检测到该请求包目的IP是VIP而非自己,便会丢弃,不会响应,为了解决这个问题,需在所有realserver上都配置上VIP,保证数据包不丢弃,同时由于后端realserver都配置VIP会导致IP冲突,所以需将VIP配置在lo网卡上,这样限制了VIP不会在物理交换机上产生MAC地址表,从而避免IP冲突。可用脚本来启动后端服务器VIP配置:
# vim/etc/init.d/lvsrs #编辑一个lvsrs脚本,并放到/etc/init.d/下
#!/bin/bash
#description : startrealserver
VIP=192.168.28.88
sh/etc/rc.d/init.d/functions
case "$1" in
start)
/usr/sbin/ifconfig lo:0$VIP broadcast $VIP netmask 255.255.255.255 up
/usr/sbin/route add-host $VIP dev 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
echo " start LVSof REALServer"
exit 0
;;
stop)
/usr/sbin/ifconfig lo:0down
/usr/sbin/route del$VIP >/dev/null 2>&1
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 "close LVSDirectorserver"
exit 1
;;
*)
echo "Usage: $0{start|stop}"
;;
esac
# chmod 755/etc/init.d/lvsrs #给新增lvsrs脚本一个755权限
# service lvsrsstart #启动lvsrs服务,我环境启动时出错,给一个functions 755权限,按各自环境操作
# chmod 755/etc/rc.d/init.d/functions #给functions755权限
六、LVS 负载均衡排错
1)负载不均排查
生产环境中ipvsadm -L -n发现两台RS的负载均衡,一台有很多请求,一台没有并且没有请求的那台RS测试服务正常, lo:VIP也有,但是就是没有请求。
# ipvsadm -L -n
IP Virtual Serverversion 1.2.1 (size=4096)
Prot LocalAddress:PortScheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.28.88:80 rr
-> 192.168.28.134:80 Route 1 0 0
-> 192.168.28.135:80 Route 1 0 0
问题原因:
persistence_timeout 的原因,persistent会话保持,当clientA访问网络的时候,LVS把请求分发给了52,那么以后clientA 在点击的其他操作请求,也会发送给52这台机器。
解决办法:
到keepalived中注释掉 persistence_timeout 60 然后把/etc/init.d/keepalived reload 然后就可看到以后负载两边都均衡了。
导致负载均衡不均的原因可能有:
• LVS自身的会话保持参数设置(-p300,persistent 300)
优化:大公司尽量用cookies替代session
• LVS调度算法设置 例如: rr wrr wlc lc算法
• 后端RS节点的会话保持参数,例如:apache的keepalive参数
• 访问较少的情况,不均衡的现象更加明显、
• 用户发送的请求的时间长短,和请求资源的大小。
2)LVS故障拍错思路
• 调度器上LVS调度规则及IP的正确性
• RS节点上VIP绑定和arp抑制的检查
生产环境中:
• 对RS绑定的VIP做实时监控,出问题报警或者自动处理后报警
• 把RS绑定的vip 做成配置文件,例如:vi/etc/sysconfig/network-script/lo:0
3)ARP抑制的配置思路:
• 如果是单个VIP那么可以用stop传参设置0
• 如果rs端有多个vip绑定,此时,即使停止VIP绑定,也不一定不要配置0
if [ ${#VIP[@]} -lt 1];then
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
fi
• RS节点上自身提供服务的检查(DR不能端口转换)
• 辅助排除工具有tcpdump ping 等
• 负载均衡和反向代理集群的三角形排查理论:
haproxy 代理
- -
- -
- -
用户--------------webserver
Squid 代理
- -
- -
- -
用户--------------webserver
tcpdump命令:
#抓取访问游览器访问的数据包
# tcpdump -i eth0tcp port 80 -x -vv -X -s 1500
4)集群LVS高并发拓展方案
• LVS Cluster部署(OSPF + LVS)
http://my.oschina.net/lxcong/blog/143904
• DNS轮询(数据库–全国IP分配的运营商以及省市)
1)智能DNS
根据用户线路的位置
选项和用户最近的服务器线路相同的机房的地址
5)LVS集群下的代码发布方案详解
代码上线的基本流程:
发布代码:
开发人员本地测试---》办公室内部测试(开发人员,测试人员)---》(配置管理员)---》IDC机房环境测试(测试人员)---》正式服务器
1、例如:后台代码是PHP环境
一般上线方式分为:
测试好代码后,正式上线是把测试好的代码先推送到正式环境的目录(新建一个目录)下面
• 等待推送完成后,确认ok然后使用mv命令替换
• 等待推送完成后,使用ln命令做软连接
最大程度的保证用户体验
2、例如:后台代码是JAVA环境(上线服务需要重启)
一般上线方式分为:
利用lvs服务平滑上线
大概过程是:LVS下有6台webserver (分为两组)使用ipvsadm -d 剔除另外一组,然后挂到另外一组VIP上测试,测试好后利用ipvsadm-a在添加进来。然后在对另外一组同样的操作。
总结:
代码上线是一个多方协作配合的一个项目流程环节,除了技术方案本身其科学完整的上线方案也非常重要。在过程中按照完备的流程,与开发、测试的前期的沟通也是保证完成整个上线流程的必要前提保障。
实例:
企业网站LVS+keepalived+Nginx 架构中,突然发现网站部分用户访问巨慢,甚至无法访问:
• 客户端ping网站域名,通过ping返回域名对应的IP是否正常;
• 如果无法返回IP,或者响应比较慢,定位 DNS 或者网络延迟问题,可以通过tracert域名测试客户端到服务器的延迟;
• 登录 LVS 服务器,ipvsadm -L -n 查看当前后端Web连接信息。
通过LVS ipvsadm 信息,检查轮询方式与权重。无异常,猜测是某一台Web服务器无法访问或者访问巨慢导致。
查看keepaleved.conf 负载均衡健康检查配置,部分代码如下:
real_server 192.168.28.135 80 {
weight 1
TCP_CHECK {
connect_port 80
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
}
}
通过配置文件发现LVS默认使用的是默认的80端口,只要80端口能通,请求就会被转发到后端服务器,使用wget http://192.168.28.135/ 返回很慢,直到超时,另外几台realserver 返回正常。经检查发现192.168.28.135服务器ifconfig查看IP,但没有发现VIP地址绑定lo:0网卡上。配置VIP后恢复正常。
为防止上述突发问题,增加LVS对后端Nginx URL的检测,能访问则表示服务正常,对比之前的检测方式,从单纯的80端口到现在的URL检测,后端如果某台出现502超时错误,keepalived列表会自动踢出异常的realserver,等待后端realserver 恢复后自动添加到服务器正常列表。keepalived 基于URL检查代码如下:
real_server 192.168.28.135 80 {
weight 1
HTTP_GET {
url {
path /monitor/warn.jsp
status_code 200
}
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
}
}