LVS 机制与调度算法(详细)

  1. 云栖社区>
  2. 博客>
  3. 正文

LVS 机制与调度算法(详细)

sktj 2018-05-15 09:07:00 浏览845
展开阅读全文

转载: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等。

不足:要求负载均衡器的网卡必须与物理网卡在一个物理段上

img_e558fe1fc3cebfe87c2cf5af4abecad7.jpe

LVS之二:负载均衡调度算法

前面的文章介绍了LVS的三种模式:NAT、TUN、DR,那这三种模式下,如果进行负载均衡调度计算呢?这就涉及到新的知识点:负载均衡调度算法

目前LVS主要有三种请求转发方式和10种调度算法。根据请求转发方式的不同,所构架集群的网络拓扑、安装方式、性能表现也各不相同。用LVS主要可以架构三种形式的集群,分别是LVS/NAT、LVS/TUN和LVS/DR,可以根据需要选择其中一种。在选定转发方式的情况下,采用哪种调度算法将决定整个负载均衡的性能表现,不同的算法适用于不同的应用场合,有时可能需要针对特殊场合,自行设计调度算法。LVS的算法是逐渐丰富起来的,最初LVS只提供4种调度算法,后来发展到以下10种。

一、静态调度算法:

1.1 轮叫调度(Round Robin,RR)

调度器通过“轮叫"调度算法将外部请求按顺序轮流分配到集群中的真实服务器上,它均等地对待每一台服务器,而不管服务器上实际的连接数和系统负载。

1.2 加权轮叫(Weighted Round Robin,WRR)

调度器通过“加权轮叫"调度算法根据真实服务器的不同处理能力来调度访问请求。这样可以保证处理能力强的服务器能处理更多的访问流量。调度器可以自动问询真实服务器的负载情况,并动态地调整其权值。

1.3 目标地址散列(Destination Hashing,DH)

“目标地址散列"调度算法根据请求的目标IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。主要用于缓存服务器的场景。

1.4 源地址散列(Source Hashing,SH)

“源地址散列"调度算法根据请求的源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即可。

查看内核是否已经集成ipvs:

[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

一、安装ipvsadm:

[root@lvs ~]# yum -y install ipvsadm

二、ipvsadm基本介绍:

2.1 集群服务管理类命令:

2.1.1 添加集群:

# 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

2.1.2 修改集群:

# ipvs -E -t|u|f service-address [-s scheduler]

示例:

[root@lvs ~]# ipvsadm -E -t 172.16.1.253:80-s wrr

2.1.3 删除集群:

# ipvsadm -D -t|u|f service-address

示例:

[root@lvs ~]# ipvsadm -D -t 172.16.1.253:80

2.2 管理集群中的RealServer:

2.2.1 添加RS:

# 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

2.2.2 修改RS:

# 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

2.2.3 删除RS:

# 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

2.3 查看类:

# ipvsadm -L|l [options]

常用选项[options]如下:

-n: 数字格式显示主机地址和端口

--stats:统计数据

--rate: 速率

--timeout: 显示tcp、tcpfin和udp的会话超时时长

-c: 显示当前的ipvs连接状况

2.4 其他管理类:

2.4.1 删除所有集群服务:

# ipvsadm -C

该命令与iptables的-F功能类似,执行后会清除所有规则。

2.4.2 保存规则

保存规则至默认配置文件:

# service ipvsadm save

保存规则至指定文件:

# ipvsadm -S > /path/to/somefile

示例:

[root@lvs ~]# service ipvsadm save

ipvsadm: Saving IPVS table to /etc/sysconfig/ipvsadm:      [确定]

2.4.3 载入保存在文件中的规则

# ipvsadm -R < /path/form/somefile

三、lvs的其他注意事项:

关于时间同步:各节点间的时间偏差不大于1s,建议使用统一的ntp服务器进行更新时间;

DR模型中的VIP的MAC广播问题:

在DR模型中,由于每个节点均要配置VIP,因此存在VIP的MAC广播问题,在现在的linux内核中,都提供了相应kernel 参数对MAC广播进行管理,具体如下:

arp_ignore: 定义接收到ARP请求时的响应级别;

0:只要本地配置的有相应地址,就给予响应;

    1:仅在请求的目标地址配置在到达的接口上的时候,才给予响应;DR模型使用

arp_announce:定义将自己地址向外通告时的通告级别;

0:将本地任何接口上的任何地址向外通告;

1:试图仅向目标网络通告与其网络匹配的地址;

    2:仅向与本地接口上地址匹配的网络进行通告;DR模型使用

LVS之四:DR模型实现

试验拓扑:

img_43e6e72b8743ed5f396f7f50d8c3e1d0.jpe

img_4638b405f63316c8d863206a37b2f93b.jpe

然后启动各虚拟机,按上述拓扑规划配置好IP地址。

1.2 配置路由器(linux):

使用iptables实现NAT配置较为简单,主要如下:

1.2.1 开启转发功能:

[root@router ~]# echo 1 >/proc/sys/net/ipv4/ip_forward

如果需永久修改,则需要修改sysctl.conf文件。并使用sysctl -p 使其立即生效。

1.2.2 配置iptables:

清除所有规则:

[root@router ~]# iptables –F

配置NAT功能:

[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

操作完成!

二、配置Director

2.1 启用转发:

[root@lvs ~]# echo 1 > /proc/sys/net/ipv4/ip_forward

如果想永久生效,则需要修改/etc/sysctl.conf文件。

2.2 配置VIP和路由:

配置路由:

[root@lvs ~]# route add -host 172.16.1.253 dev eth0:0

配置VIP:

[root@lvs ~]# ifconfig eth0:1 172.16.1.253 netmask 255.255.255.255 up

2.3 清除原有iptables和ipvs规则:

[root@lvs ~]# iptables -F

[root@lvs ~]# iptables -Z

[root@lvs ~]# ipvsadm -C

2.4 配置集群服务:

[root@lvs ~]# ipvsadm -A -t 172.16.1.253:80 -s wlc

2.5 添加RS至集群服务:

[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

三、配置RS:

3.1 配置ARP广播:

[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

3.2 配置VIP和路由:

[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

3.3 编写为脚本:

#!/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

3.4 在RS2上采用相同的配置即可

至此就全部完成了lvs的DR模型配置。

4 测试LVS集群

4.1 配置web服务器:

4.1.1 为rs1节点添加web主页:

[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

4.1.2 为rs2节点添加web主页:

[root@rs2 ~]# echo "This is RS2..." >/var/www/html/index.html

4.2 访问测试:

访问时观察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的下线和上线做日志记录。

二、web健康检查命令:

使用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模式的原理如下(借用别人的图):

img_bcbb38b0e792449b37f2087dd569ec47.png

说明:

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

三、安装LVS+Keepalived:

1、使用yum在线安装:

[root@lvs1 ~]# yum install ipvsadm  keepalived –y

2、检查安装结果:

[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

3、服务配置:

[root@lvs1 ~]# chkconfig keepalived on   ##设置为开机启动

[root@lvs1 ~]# service keepalived start   ##立即启动keepalived服务

四、配置LVS服务器:

1、  备份配置文件:

[root@lvs1 ~]# cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.bak

2、  修改配置文件,具体如下:

原始的配置文件包含了三种模式的配置,而这里我们只需要用到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即可,其他保持相同。

3、  分别在两台lvs服务器上重启服务:

[root@lvs1 ~]# service keepalived start

注:由于keepalived配置文件有语法错误也能启动,因此看到启动了lvs服务,不代表配置文件没有错误,如果遇到lvs不能正常转发,及时跟踪日志进行处理。

日志跟踪方法:

1、开两个ssh窗口连接到lvs服务器,第一个窗口运行如下命令:

[root@lvs1 ~]# tail -F /var/log/message

2、第二个窗口重新启动keepalived服务,同时观察窗口1中日志的变化,然后根据日志提示解决即可。

五、WEB服务器IP绑定配置:

在两台WEB服务器安装并配置(非本文重点,不做web安装配置讲解),建立测试网页,先使用实际IP进行访问测试,能正常访问后,进行如下操作:

在前面的文章中介绍DR模式时提到:负载均衡器也只是分发请求,应答包通过单独的路由方法返回给客户端。但实际上客户端访问时,IP都是指向的负载均衡器的ip(也就是LVS的VIP),如何能让真是服务器处理IP头为VIP的请求,这就需要做下面的操作,将VIP绑定到真实服务器的lo网口(回环),为了防止IP广播产生IP冲突,还需关闭IP广播,具体如下:

1、编辑开机启动脚本:

  [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:仅向与本地接口上地址匹配的网络进行通告;

2、  设置脚本开机启动并立即启动:

[root@web1 ~]# chkconfig realserver on

[root@web1 ~]# service realserver start

RealServer Start OK

3、  检测IP配置:

[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

4、  测试LVS:

在lvs master服务器上运行如下命令:

[root@lvs1 ~]# watch -n 1 ipvsadm -ln

在多台客户端通过浏览器访问VIP或域名(域名需解析到VIP),看能否获取到正确的页面,且同时观察上述窗口的变化。

img_08fd4d297e4ecde40974f9c26faa4a59.png


从上图(为了方便观察,使用了压力测试)可以看出,访问被正常的分担到了两台后端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

配置并启用lvs集群的持久连接:

基本语法:

ipvsadm -A|E ... -p timeout

timeout: 持久连接时长,默认300秒;单位是秒;

在使用《LVS之四:DR模型实现》中的lvs集群,每次刷新客户端时,都会在RS1和RS2上切换。如下图:

img_56ecb1f00e18feae2a453f59cc910910.jpe

我们启用持久连接:

[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

网友评论

登录后评论
0/500
评论
sktj
+ 关注