转载:https://blog.csdn.net/moonpure/article/details/52839132
LVS之一:三种工作模式的优缺点比较(NAT/TUN/DR)
一、Virtual server via NAT(VS-NAT)
优点:集群中的物理服务器可以使用任何支持TCP/IP操作系统,物理服务器可以分配Internet的保留私有地址,只有负载均衡器需要一个合法的IP地址。
缺点:扩展性有限。当服务器节点(普通PC服务器)数据增长到20个或更多时,负载均衡器将成为整个系统的瓶颈,因为所有的请求包和应答包都需要经过负载均衡器再生。假使TCP包的平均长度是536字节的话,平均包再生延迟时间大约为60us(在Pentium处理器上计算的,采用更快的处理器将使得这个延迟时间变短),负载均衡器的最大容许能力为8.93M/s,假定每台物理服务器的平台容许能力为400K/s来计算,负责均衡器能为22台物理服务器计算。
解决办法:即使是是负载均衡器成为整个系统的瓶颈,如果是这样也有两种方法来解决它。一种是混合处理,另一种是采用Virtual Server via IP tunneling或Virtual Server via direct routing。如果采用混合处理的方法,将需要许多同属单一的RR DNS域。你采用Virtual Server via IP tunneling或Virtual Server via direct routing以获得更好的可扩展性。也可以嵌套使用负载均衡器,在最前端的是VS-Tunneling或VS-Drouting的负载均衡器,然后后面采用VS-NAT的负载均衡器。
二、Virtual server via IP tunneling(VS-TUN)
我们发现,许多Internet服务(例如WEB服务器)的请求包很短小,而应答包通常很大。
优点:负载均衡器只负责将请求包分发给物理服务器,而物理服务器将应答包直接发给用户。所以,负载均衡器能处理很巨大的请求量,这种方式,一台负载均衡能为超过100台的物理服务器服务,负载均衡器不再是系统的瓶颈。使用VS-TUN方式,如果你的负载均衡器拥有100M的全双工网卡的话,就能使得整个Virtual Server能达到1G的吞吐量。
不足:但是,这种方式需要所有的服务器支持"IP Tunneling"(IP Encapsulation)协议,我仅在Linux系统上实现了这个,如果你能让其它操作系统支持,还在探索之中。
三、Virtual Server via Direct Routing(VS-DR)
优点:和VS-TUN一样,负载均衡器也只是分发请求,应答包通过单独的路由方法返回给客户端。与VS-TUN相比,VS-DR这种实现方式不需要隧道结构,因此可以使用大多数操作系统做为物理服务器,其中包括:Linux 2.0.36、2.2.9、2.2.10、2.2.12;Solaris 2.5.1、2.6、2.7;FreeBSD 3.1、3.2、3.3;NT4.0无需打补丁;IRIX 6.5;HPUX11等。
不足:要求负载均衡器的网卡必须与物理网卡在一个物理段上
LVS之二:负载均衡调度算法
前面的文章介绍了LVS的三种模式:NAT、TUN、DR,那这三种模式下,如果进行负载均衡调度计算呢?这就涉及到新的知识点:负载均衡调度算法
目前LVS主要有三种请求转发方式和10种调度算法。根据请求转发方式的不同,所构架集群的网络拓扑、安装方式、性能表现也各不相同。用LVS主要可以架构三种形式的集群,分别是LVS/NAT、LVS/TUN和LVS/DR,可以根据需要选择其中一种。在选定转发方式的情况下,采用哪种调度算法将决定整个负载均衡的性能表现,不同的算法适用于不同的应用场合,有时可能需要针对特殊场合,自行设计调度算法。LVS的算法是逐渐丰富起来的,最初LVS只提供4种调度算法,后来发展到以下10种。
调度器通过“轮叫"调度算法将外部请求按顺序轮流分配到集群中的真实服务器上,它均等地对待每一台服务器,而不管服务器上实际的连接数和系统负载。
1.2 加权轮叫(Weighted Round Robin,WRR)
调度器通过“加权轮叫"调度算法根据真实服务器的不同处理能力来调度访问请求。这样可以保证处理能力强的服务器能处理更多的访问流量。调度器可以自动问询真实服务器的负载情况,并动态地调整其权值。
1.3 目标地址散列(Destination Hashing,DH)
“目标地址散列"调度算法根据请求的目标IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。主要用于缓存服务器的场景。
“源地址散列"调度算法根据请求的源IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。在没有使用session共享的又需要保存session的环境下(如电子商务网站),建议使用此算法。
2.1 最少链接(Least Connections,LC)
调度器通过“最少连接"调度算法动态地将网络请求调度到已建立的链接数最少的服务器上。如果集群系统的真实服务器具有相近的系统性能,采用“最小连接"调度算法可以较好地均衡负载。其具体算法为:
active*256+inactive
然后挑选服务器中上述值最小者分配新连接。
2.2 加权最少链接(Weighted Least Connections,WLC)
在集群系统中的服务器性能差异较大的情况下,调度器采用“加权最少链接"调度算法优化负载均衡性能,具有较高权值的服务器将承受较大比例的活动连接负载。调度器可以自动问询真实服务器的负载情况,并动态地调整其权值。WLC为LVS的默认调度算法。其具体算法为:
(active*256+inactive)/weight
然后挑选服务器根据上述方法计算数字最小者分配新连接。
2.3 基于局部性的最少链接(Locality-Based Least Connections,LBLC)
“基于局部性的最少链接"调度算法是针对目标IP地址的负载均衡,目前主要用于Cache集群系统。该算法根据请求的目标IP地址找出该目标IP地址最近使用的服务器,若该服务器是可用的且没有超载,将请求发送到该服务器;若服务器不存在,或者该服务器超载且有服务器处于一半的工作负载,则用“最少链接"的原则选出一个可用的服务器,将请求发送到该服务器。
类似于DH算法,不同的是,其结合了DH算法和LC算法的优势。
2.4 带复制的基于局部性最少链接(Locality-Based Least Connections with Replication,LBLCR)
“带复制的基于局部性最少链接"调度算法也是针对目标IP地址的负载均衡,目前主要用于Cache集群系统。它与LBLC算法的不同之处是它要维护从一个目标IP地址到一组服务器的映射,而LBLC算法维护从一个目标IP地址到一台服务器的映射。该算法根据请求的目标IP地址找出该目标IP地址对应的服务器组,按“最小连接"原则从服务器组中选出一台服务器,若服务器没有超载,将请求发送到该服务器;若服务器超载,则按“最小连接"原则从这个集群中选出一台服务器,将该服务器加入到服务器组中,将请求发送到该服务器。同时,当该服务器组有一段时间没有被修改,将最忙的服务器从服务器组中删除,以降低复制的程度。
2.5 最短的期望的延迟(Shortest Expected Delay Scheduling,SED)
“最短的期望的延迟”是基于WLC算法的,只是其计算方法不同。具体算法如下:
(active+1)*256/weight
2.6 最少队列(Never Queue Scheduling,NQ)
无需队列。如果有台 realserver的连接数=0就直接分配过去,不需要在进行SED运算。如果没有服务器连接数为空闲,则使用SED算法。
了解这些算法原理能够在特定的应用场合选择最适合的调度算法,从而尽可能地保持Real Server的最佳利用性。
LVS之三:ipvsadm常用管理命令介绍
LVS全称为Linux Virtual Server,工作在ISO模型中的第四层,由于其工作在第四层,因此与iptables类似,必须工作在内核空间上。因此lvs与iptables一样,是直接工作在内核中的,叫ipvs,主流的linux发行版默认都已经集成了ipvs,因此用户只需安装一个管理工具ipvsadm即可。
[root@lvs ~]# grep -i "ip_vs" /boot/config-2.6.32-358.18.1.el6.x86_64
CONFIG_IP_VS=m
CONFIG_IP_VS_IPV6=y
# CONFIG_IP_VS_DEBUG is not set
CONFIG_IP_VS_TAB_BITS=12
CONFIG_IP_VS_PROTO_TCP=y
CONFIG_IP_VS_PROTO_UDP=y
CONFIG_IP_VS_PROTO_AH_ESP=y
CONFIG_IP_VS_PROTO_ESP=y
CONFIG_IP_VS_PROTO_AH=y
CONFIG_IP_VS_PROTO_SCTP=y
CONFIG_IP_VS_RR=m
CONFIG_IP_VS_WRR=m
CONFIG_IP_VS_LC=m
CONFIG_IP_VS_WLC=m
CONFIG_IP_VS_LBLC=m
CONFIG_IP_VS_LBLCR=m
CONFIG_IP_VS_DH=m
CONFIG_IP_VS_SH=m
CONFIG_IP_VS_SED=m
CONFIG_IP_VS_NQ=m
CONFIG_IP_VS_FTP=m
[root@lvs ~]# yum -y install ipvsadm
# ipvs -A -t|u|f service-address [-s scheduler]
-t: TCP协议的集群
-u: UDP协议的集群
service-address: IP:PORT
-f: FWM: 防火墙标记
service-address: Mark Number
[root@lvs ~]# ipvsadm -A -t 172.16.1.253:80 -s wlc
# ipvs -E -t|u|f service-address [-s scheduler]
[root@lvs ~]# ipvsadm -E -t 172.16.1.253:80-s wrr
# ipvsadm -D -t|u|f service-address
[root@lvs ~]# ipvsadm -D -t 172.16.1.253:80
# ipvsadm -a -t|u|f service-address -r server-address [-g|i|m] [-w weight]
-t|u|f service-address:事先定义好的某集群服务
-r server-address: 某RS的地址,在NAT模型中,可使用IP:PORT实现端口映射;
[-g|i|m]: LVS类型
-g: DR
-i: TUN
-m: NAT
[-w weight]: 定义服务器权重
[root@lvs ~]# ipvsadm -a -t 172.16.1.253:80 -r 172.16.1.101 –g -w 5
[root@lvs ~]# ipvsadm -a -t 172.16.1.253:80 -r 172.16.1.102 –g -w 10
# ipvsadm -e -t|u|f service-address -r server-address [-g|i|m] [-w weight]
[root@lvs ~]# ipvsadm-e-t 172.16.1.253:80 -r 172.16.1.101 –g -w3
# ipvsadm -d -t|u|f service-address -r server-address
[root@lvs ~]# ipvsadm -d -t 172.16.1.253:80 -r 172.16.1.101
# ipvsadm -L|l [options]
-n: 数字格式显示主机地址和端口
--stats:统计数据
--rate: 速率
--timeout: 显示tcp、tcpfin和udp的会话超时时长
-c: 显示当前的ipvs连接状况
# ipvsadm -C
该命令与iptables的-F功能类似,执行后会清除所有规则。
# service ipvsadm save
# ipvsadm -S > /path/to/somefile
[root@lvs ~]# service ipvsadm save
ipvsadm: Saving IPVS table to /etc/sysconfig/ipvsadm: [确定]
# ipvsadm -R < /path/form/somefile
关于时间同步:各节点间的时间偏差不大于1s,建议使用统一的ntp服务器进行更新时间;
DR模型中的VIP的MAC广播问题:
在DR模型中,由于每个节点均要配置VIP,因此存在VIP的MAC广播问题,在现在的linux内核中,都提供了相应kernel 参数对MAC广播进行管理,具体如下:
0:只要本地配置的有相应地址,就给予响应;
1:仅在请求的目标地址配置在到达的接口上的时候,才给予响应;DR模型使用
arp_announce:定义将自己地址向外通告时的通告级别;
0:将本地任何接口上的任何地址向外通告;
1:试图仅向目标网络通告与其网络匹配的地址;
2:仅向与本地接口上地址匹配的网络进行通告;DR模型使用
LVS之四:DR模型实现
使用iptables实现NAT配置较为简单,主要如下:
[root@router ~]# echo 1 >/proc/sys/net/ipv4/ip_forward
如果需永久修改,则需要修改sysctl.conf文件。并使用sysctl -p 使其立即生效。
[root@router ~]# iptables –F
[root@router ~]# iptables -t nat -A POSTROUTING -o eth0 -s 172.16.1.0/24 -j SNAT --to 192.168.8.254
[root@router ~]# iptables -t nat -A PREROUTING -d 192.168.8.254 -p tcp --dport 80 -j DNAT --to-destination 172.16.1.253:80
##为了方便使用ssh客户端连接,我还将lvs集群中各服务器的22端口映射到了不同端口,具体如下:
[root@router ~]# iptables -t nat -A PREROUTING -d 192.168.8.254 -p tcp --dport2022-j DNAT --to-destination172.16.1.252:22
[root@router ~]# iptables -t nat -A PREROUTING -d 192.168.8.254 -p tcp --dport2122-j DNAT --to-destination172.16.1.101:22
[root@router ~]# iptables -t nat -A PREROUTING -d 192.168.8.254 -p tcp --dport2222-j DNAT --to-destination172.16.1.102:22
[root@router ~]# iptables -A FORWARD -p ip -j ACCEPT
[root@router ~]# service iptables save
此时,Director和RealServer都已可以正常访问外网。
1.3 配置本地windows,添加路由使其能访问lvs集群:
由于试验中物理主机(windows)和试验用路由器(linux)的默认网关指向的是真实的路由器,因此物理主机(windows)是无法访问lvs集群网络的,为了能让物理机(windows)访问到集群网络方便后面测试,因此需要添加路由,命令如下:
C:\windows\system32>route add 172.16.1.0/24 192.168.8.254
操作完成!
[root@lvs ~]# echo 1 > /proc/sys/net/ipv4/ip_forward
如果想永久生效,则需要修改/etc/sysctl.conf文件。
[root@lvs ~]# route add -host 172.16.1.253 dev eth0:0
[root@lvs ~]# ifconfig eth0:1 172.16.1.253 netmask 255.255.255.255 up
[root@lvs ~]# iptables -F
[root@lvs ~]# iptables -Z
[root@lvs ~]# ipvsadm -C
[root@lvs ~]# ipvsadm -A -t 172.16.1.253:80 -s wlc
[root@lvs ~]# ipvsadm -a -t 172.16.1.253:80 -r 172.16.1.101 -g
[root@lvs ~]# ipvsadm -a -t 172.16.1.253:80 -r 172.16.1.102 -g
2.6 将上述过程编写为一个服务脚本,直接在Director上实现开机启动:
#!/bin/bash
#
# LVS script for VS/DR
# chkconfig: - 90 10
#
. /etc/rc.d/init.d/functions
#
VIP=172.16.1.253
DIP=172.16.1.252
RIP1=172.16.1.101
RIP2=172.16.1.102
PORT=80
RSWEIGHT1=5
RSWEIGHT2=5
#
case "$1" in
start)
/sbin/ifconfig eth0:1 $VIP broadcast $VIP netmask 255.255.255.255 up
/sbin/route add -host $VIP dev eth0:1
# Since this is the Director we must be able to forward packets
echo 1 > /proc/sys/net/ipv4/ip_forward
# Clear all iptables rules.
/sbin/iptables -F
# Reset iptables counters.
/sbin/iptables -Z
# Clear all ipvsadm rules/services.
/sbin/ipvsadm -C
# Add an IP virtual service for VIP 192.168.0.219 port 80
# In this recipe, we will use the round-robin scheduling method.
# In production, however, you should use a weighted, dynamic scheduling method.
/sbin/ipvsadm -A -t $VIP:80 -s wlc
# Now direct packets for this VIP to
# the real server IP (RIP) inside the cluster
/sbin/ipvsadm -a -t $VIP:80 -r $RIP1 -g -w $RSWEIGHT1
/sbin/ipvsadm -a -t $VIP:80 -r $RIP2 -g -w $RSWEIGHT2
/bin/touch /var/lock/subsys/ipvsadm &> /dev/null
;;
stop)
# Stop forwarding packets
echo 0 > /proc/sys/net/ipv4/ip_forward
# Reset ipvsadm
/sbin/ipvsadm -C
# Bring down the VIP interface
/sbin/ifconfig eth0:0 down
/sbin/route del $VIP
/bin/rm -f /var/lock/subsys/ipvsadm
echo "ipvs is stopped..."
;;
status)
if [ ! -e /var/lock/subsys/ipvsadm ]; then
echo "ipvsadm is stopped ..."
else
echo "ipvs is running ..."
ipvsadm -L -n
fi
;;
*)
echo "Usage: $0 {start|stop|status}"
;;
esac
将上述内容保存在/etc/init.d/lvs-director文件中,然后添加到服务:
[root@lvs ~]# chmod +x /etc/init.d/lvs-director
[root@lvs ~]# chkconfig --add lvs-director
[root@lvs ~]# chkconfig lvs-director on
[root@lvs ~]# /etc/init.d/lvs-director start
[root@lvs ~]# /etc/init.d/lvs-director status
ipvs is running ...
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.1.253:80 wlc
-> 172.16.1.101:80 Route 5 0 0
-> 172.16.1.102:80 Route 5 0 0
[root@rs1 ~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@rs1 ~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
[root@rs1 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@rs1 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
[root@rs1 ~]# ifconfig lo:0 172.16.1.253 netmask 255.255.255.255 up
[root@rs1 ~]# route add -host 172.16.1.253 dev lo:0
#!/bin/bash
#
# Script to start LVS DR real server.
# chkconfig: - 90 10
# description: LVS DR real server
#
. /etc/rc.d/init.d/functions
VIP=172.16.1.253
host=`/bin/hostname`
case "$1" in
start)
# Start LVS-DR real server on this machine.
/sbin/ifconfig lo down
/sbin/ifconfig lo up
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
/sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 255.255.255.255 up
/sbin/route add -host $VIP dev lo:0
;;
stop)
# Stop LVS-DR real server loopback device(s).
/sbin/ifconfig lo:0 down
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
;;
status)
# Status of LVS-DR real server.
islothere=`/sbin/ifconfig lo:0 | grep $VIP`
isrothere=`netstat -rn | grep "lo:0" | grep $VIP`
if [ ! "$islothere" -o ! "isrothere" ];then
# Either the route or the lo:0 device
# not found.
echo "LVS-DR real server Stopped."
else
echo "LVS-DR real server Running."
fi
;;
*)
# Invalid entry.
echo "$0: Usage: $0 {start|status|stop}"
exit 1
;;
esac
保存至/etc/init.d/lvs-rs,并赋予执行权限,然后添加为开机启动:
[root@rs1~]# chmod +x /etc/init.d/lvs-rs
[root@rs1 ~]# chkconfig --add lvs-rs
[root@rs1 ~]# chkconfig lvs-rs on
[root@rs1 ~]# /etc/init.d/lvs-rs start
至此就全部完成了lvs的DR模型配置。
[root@rs1 ~]# service httpd start
正在启动 httpd:httpd: apr_sockaddr_info_get() failed for rs1
httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName
[确定]
[root@rs1 ~]# echo "This is RS1..." >/var/www/html/index.html
[root@rs2 ~]# echo "This is RS2..." >/var/www/html/index.html
访问时观察ipvs状态:
Every 1.0s: ipvsadm -L -n Tue Oct 8 19:58:42 2013
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.1.253:80 wlc
-> 172.16.1.101:80 Route 5 2 8
-> 172.16.1.102:80 Route 5 1 8
LVS之五:使用脚本实现RealServer的健康检查
上文部署的DR模型中,当一台RS宕机时,ipvs是不会自动踢出该RS服务器的,我这里使用一个脚本实现对RS的监控检查。
脚本要能判断RS运行情况;
当RS的web服务不能访问时,将其从lvs集群中踢出;而当RS重新上线时,再将其加入lvs集群;
定时检查(死循环或cron计划任务);
对RS的下线和上线做日志记录。
使用curl能简单的实现对web应用可用性进行监控:
curl命令选项:
--cacert CA证书 (SSL)
--capath CA目录 (made using c_rehash) to verify peer against (SSL)
--compressed 要求返回是压缩的形势 (using deflate or gzip)
--connect-timeout 设置最大请求时间
-H/--header 自定义头信息传递给服务器
-i/--include 输出时包括protocol头信息
-I/--head 只显示文档信息
--interface 使用指定网络接口/地址
-s/--silent静音模式。不输出任何东西
-u/--user 设置服务器的用户和密码
-p/--proxytunnel 使用HTTP代理
#!/bin/bash
#
VIP=192.168.8.254
CPORT=80
##使用数组RS定义所有RS服务器
RS=("172.16.1.101" "172.16.1.102")
#定义RS状态,后面引用
declare -a RSSTATUS
#定义权重
RW=("5" "5")
RPORT=80
#集群类型为DR
TYPE=g
CHKLOOP=3
#监控日志
LOG=/var/log/ipvsmonitor.log
#
#addrs函数在RS重新上线时将其添加到集群
addrs() {
ipvsadm -a -t $VIP:$CPORT -r $1:$RPORT -$TYPE -w $2
[ $? -eq 0 ] && return 0 || return 1
}
#delrs函数在RS下线时将其从集群中删除
delrs() {
ipvsadm -d -t $VIP:$CPORT -r $1:$RPORT
[ $? -eq 0 ] && return 0 || return 1
}
#checkrs检查RS状态,如果上次均为离线状态,则判定其为离线
checkrs() {
local I=1
while [ $I -le $CHKLOOP ]; do
if curl --connect-timeout 1http://$1&> /dev/null; then
return 0
fi
let I++
done
return 1
}
#初始化RS状态函数
initstatus() {
local I
local COUNT=0;
for I in ${RS[*]}; do
if ipvsadm -L -n | grep "$I:$RPORT" && > /dev/null ; then
RSSTATUS[$COUNT]=1
else
RSSTATUS[$COUNT]=0
fi
let COUNT++
done
}
#执行初始化RS状态检查函数
initstatus
#死循环
while :; do
let COUNT=0
for I in ${RS[*]}; do
if checkrs $I; then
if [ ${RSSTATUS[$COUNT]} -eq 0 ]; then
addrs $I ${RW[$COUNT]}
[ $? -eq 0 ] && RSSTATUS[$COUNT]=1 && echo "`date +'%F %H:%M:%S'`, $I is back." >> $LOG
fi
else
if [ ${RSSTATUS[$COUNT]} -eq 1 ]; then
delrs $I
[ $? -eq 0 ] && RSSTATUS[$COUNT]=0 && echo "`date +'%F %H:%M:%S'`, $I is gone." >> $LOG
fi
fi
let COUNT++
done
sleep 5
done
LVS之六:使用keepalived实现LVS的DR模式热备
在《LVS之一:三种工作模式的优缺点比较(NAT/TUN/DR)》文章讲述了LVS的三种转发模式对比,我们先就用LVS的DR模式来实现Web应用的负载均衡。为了防止LVS服务器自身的单点故障导致整个Web应用无法提供服务,因此还得利用Keepalived实现lvs的高可用性,keepalived主要使用VRRP协议来保存链路的高可用性。而VRRP(Virtual Router Redundancy Protocol)协议本身是用于实现路由器冗余的协议。
LVS-DR模式的原理如下(借用别人的图):
1、 LVS服务器和WEB服务器必须在同一网段;
2、 多台Web服务器间使用NFS服务器等共享存储存放用户上传附件,以保障数据的一致性(如上传图片)。下文讨论
IP地址规划:
VIP 192.168.18.60
LVS-MASTER 192.168.18.51
LVS-BACKUP 192.168.18.52
NFS Server 192.168.18.20
MySQL 192.168.18.18
WEB1 192.168.18.61
WEB2 192.168.18.62
[root@lvs1 ~]# yum install ipvsadm keepalived –y
[root@lvs1 ~]# rpm -qa |grep ipvsadm
ipvsadm-1.25-10.el6.x86_64
[root@lvs1 ~]# rpm -qa |grep keepalived
keepalived-1.2.7-3.el6.x86_64
[root@lvs1 ~]# chkconfig keepalived on ##设置为开机启动
[root@lvs1 ~]# service keepalived start ##立即启动keepalived服务
[root@lvs1 ~]# cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.bak
原始的配置文件包含了三种模式的配置,而这里我们只需要用到DR模式,因此最终保留配置如下:
[root@lvs1 ~]# vim /etc/keepalived/keepalived.conf
global_defs { ##全局配置部分
# notification_email { ##下面几行均为全局通知配置,可以实现出现问题后报警,但功能有限,因此注释掉,并采用Nagios监视lvs运行情况
# admin@toxingwang.com
# }
# notification_email_from master@toxingwang.com
# smtp_server smtp.exmail.qq.com
# smtp_connect_timeout 30
router_id LVS_MASTER ##设置lvs的id,在一个网络内应该是唯一的
}
vrrp_instance VI_1 { ##设置vrrp组,唯一且同一LVS服务器组要相同
stateMASTER ##备份LVS服务器设置为BACKUP
interface eth0 # #设置对外服务的接口
virtual_router_id 51 ##设置虚拟路由标识
priority 100 #设置优先级,数值越大,优先级越高,backup设置为99,这样就能实现当master宕机后自动将backup变为master,而当原master恢复正常时,则现在的master再次变为backup。
advert_int 1 ##设置同步时间间隔
authentication { ##设置验证类型和密码,master和buckup一定要设置一样
auth_type PASS
auth_pass 1111
}
virtual_ipaddress { ##设置VIP,可以多个,每个占一行
192.168.18.60
}
}
virtual_server 192.168.18.60 80 {
delay_loop 6 ##健康检查时间间隔,单位s
lb_algo wrr ##负载均衡调度算法设置为加权轮叫
lb_kind DR ##负载均衡转发规则
nat_mask 255.255.255.0 ##网络掩码,DR模式要保障真是服务器和lvs在同一网段
persistence_timeout 50 ##会话保持时间,单位s
protocol TCP ##协议
real_server 192.168.18.61 80 { ##真实服务器配置,80表示端口
weight 3 ##权重
TCP_CHECK { ##服务器检测方式设置
connect_timeout 5 ##连接超时时间
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
real_server 192.168.18.62 80 {
weight 3
TCP_CHECK {
connect_timeout 10
nb_get_retry 3
delay_before_retry 3
connect_port 80
}
}
}
作为高可用的备份lvs服务器配置只需在上述配置中的master修改backup即可,其他保持相同。
[root@lvs1 ~]# service keepalived start
注:由于keepalived配置文件有语法错误也能启动,因此看到启动了lvs服务,不代表配置文件没有错误,如果遇到lvs不能正常转发,及时跟踪日志进行处理。
日志跟踪方法:
1、开两个ssh窗口连接到lvs服务器,第一个窗口运行如下命令:
[root@lvs1 ~]# tail -F /var/log/message
2、第二个窗口重新启动keepalived服务,同时观察窗口1中日志的变化,然后根据日志提示解决即可。
在两台WEB服务器安装并配置(非本文重点,不做web安装配置讲解),建立测试网页,先使用实际IP进行访问测试,能正常访问后,进行如下操作:
在前面的文章中介绍DR模式时提到:负载均衡器也只是分发请求,应答包通过单独的路由方法返回给客户端。但实际上客户端访问时,IP都是指向的负载均衡器的ip(也就是LVS的VIP),如何能让真是服务器处理IP头为VIP的请求,这就需要做下面的操作,将VIP绑定到真实服务器的lo网口(回环),为了防止IP广播产生IP冲突,还需关闭IP广播,具体如下:
[root@web1 ~]# vim /etc/init.d/realserver
#!/bin/bash
#chkconfig: 2345 79 20
#description:realserver
SNS_VIP=192.168.18.60
. /etc/rc.d/init.d/functions
case "$1" in
start)
ifconfig lo:0 $SNS_VIP netmask 255.255.255.255 broadcast $SNS_VIP
/sbin/route add -host $SNS_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
sysctl -p >/dev/null 2>&1
echo "RealServer Start OK"
;;
stop)
ifconfig lo:0 down
route del $SNS_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 "RealServer Stoped"
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
esac
exit 0
arp_ignore: 定义接收到ARP请求时的响应级别;
0:只要本地配置的有相应地址,就给予响应;默认;
1:仅在请求的目标地址配置在到达的接口上的时候,才给予响应;
arp_announce:定义将自己地址向外通告时的通告级别;
0:将本地任何接口上的任何地址向外通告;默认;
1:试图仅向目标网络通告与其网络匹配的地址;
2:仅向与本地接口上地址匹配的网络进行通告;
[root@web1 ~]# chkconfig realserver on
[root@web1 ~]# service realserver start
RealServer Start OK
[root@web1 ~]# ifconfig
eth0 Link encap:Ethernet HWaddr 00:50:56:B3:54:5A
inet addr:192.168.18.61 Bcast:192.168.18.255 Mask:255.255.255.0
inet6 addr: fe80::250:56ff:feb3:545a/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:98940 errors:4 dropped:4 overruns:0 frame:0
TX packets:82037 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:23077218 (22.0 MiB) TX bytes:16043349 (15.3 MiB)
Interrupt:18 Base address:0x2000
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:300 errors:0 dropped:0 overruns:0 frame:0
TX packets:300 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:528420 (516.0 KiB) TX bytes:528420 (516.0 KiB)
lo:0 Link encap:Local Loopback
inet addr:192.168.18.60 Mask:255.255.255.255
UP LOOPBACK RUNNING MTU:16436 Metric:1
在lvs master服务器上运行如下命令:
[root@lvs1 ~]# watch -n 1 ipvsadm -ln
在多台客户端通过浏览器访问VIP或域名(域名需解析到VIP),看能否获取到正确的页面,且同时观察上述窗口的变化。
从上图(为了方便观察,使用了压力测试)可以看出,访问被正常的分担到了两台后端web服务器 。
1、用户新上传的附件存放问题;目前我们采用的是NFS方式解决,但存在单点故障,需要配合其他方式解决。NFS的基本用法请参考《NFS的配置和使用》
2、后端数据库高可用性;
3、会话共享和保持问题(Session共享);算法调整为SH可解决,但有RealServer宕机时,其上的session也会丢失。后期将调整为实现共享session。
LVS之七:使用持久连接解决session问题
前面在讨论LVS算法中,SH算法可以实现将同一客户端的请求总是发送给第一次指定的RS,除非该RS出现故障不能再提供服务。其实在LVS集群中,持久连接功能也能在一定时间内,将来自同一个客户端请求派发至此前选定的RS,而且是无关算法的。
在基于SSL的加密https协议中,特别需要用到持久连接,因为客户端需要与服务器进行交换证书并协商加密算法等。
如果一个集群中提供了两种服务,持久连接会将同一客户端的所有请求都同步到同一RS。持久连接分三种:
PPC(持久端口连接):将来自于同一个客户端对同一个集群服务的请求,始终定向至此前选定的RS;
PCC(持久客户端连接):将来自于同一个客户端对所有端口的请求,始终定向至此前选定的RS;PCC是把所有端口统统定义为集群服务,一律向RS转发;
PNMPP:持久防火墙标记连接。使用iptables的标记功能,可以实现给多个服务(端口)打上相同的标记,然后在ipvsadm使用-f选项,并使用上述防火墙标记即可将多个服务放到一个LVS集群中。实现过程如下:
# iptables -t mangle -A PREROUTING -d 192.168.8.253 -p tcp --dport 80 -i $INCARD -j MARK --set-mark10
# iptables -t mangle -A PREROUTING -d 192.168.8.253 -p tcp --dport 443 -i $INCARD -j MARK --set-mark10
# ipvsadm -A -f10-s wlc –p 600
LVS的持久连接又集群的持久连接模板(一个内存缓冲区)提供;该持久连接模板保存着每一个客户端及分配给它的RS的映射关系。使用如下命令可以查看该模板:
[root@lvs ~]#ipvsadm -L -c
IPVS connection entries
pro expire state source virtual destination
TCP 01:56 FIN_WAIT 192.168.8.12:51822 172.16.1.253:http 172.16.1.102:http
TCP 01:57 FIN_WAIT 192.168.8.12:51825 172.16.1.253:http 172.16.1.101:http
TCP 01:56 FIN_WAIT 192.168.8.12:51821 172.16.1.253:http 172.16.1.101:http
TCP 01:42 FIN_WAIT 192.168.8.12:51814 172.16.1.253:http 172.16.1.102:http
TCP 01:57 FIN_WAIT 192.168.8.12:51826 172.16.1.253:http 172.16.1.102:http
TCP 01:57 FIN_WAIT 192.168.8.12:51824 172.16.1.253:http 172.16.1.102:http
TCP 01:56 FIN_WAIT 192.168.8.12:51820 172.16.1.253:http 172.16.1.102:http
TCP 14:58 ESTABLISHED 192.168.8.12:51828 172.16.1.253:http 172.16.1.102:http
TCP 01:55 FIN_WAIT 192.168.8.12:51815 172.16.1.253:http 172.16.1.101:http
TCP 01:56 FIN_WAIT 192.168.8.12:51823 172.16.1.253:http 172.16.1.101:http
TCP 01:57 FIN_WAIT 192.168.8.12:51827 172.16.1.253:http 172.16.1.101:http
ipvsadm -A|E ... -p timeout
timeout: 持久连接时长,默认300秒;单位是秒;
在使用《LVS之四:DR模型实现》中的lvs集群,每次刷新客户端时,都会在RS1和RS2上切换。如下图:
[root@lvs ~]# ipvsadm -L -n
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.1.253:80 wlc
-> 172.16.1.101:80 Route 5 0 1
-> 172.16.1.102:80 Route 5 0 2
[root@lvs ~]# ipvsadm -E -t 172.16.1.253:80 -p 600
[root@lvs ~]# ipvsadm -L -n
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.1.253:80 wlc persistent 600
-> 172.16.1.101:80 Route 5 0 0
-> 172.16.1.102:80 Route 5 0 1
此时再次刷新客户端,会发现已经不会再改变RS。
[root@lvs ~]# ipvsadm -L --persistent-conn
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Weight PersistConn ActiveConn InActConn
-> RemoteAddress:Port
TCP 172.16.1.253:http wlc persistent 600
-> 172.16.1.101:http 5 0 0 0
->172.16.1.102:http 5 1 0 14