Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1481394
  • 博文数量: 463
  • 博客积分: 10540
  • 博客等级: 上将
  • 技术积分: 5450
  • 用 户 组: 普通用户
  • 注册时间: 2006-11-12 08:30
文章分类

全部博文(463)

文章存档

2014年(2)

2012年(14)

2011年(42)

2010年(18)

2009年(78)

2008年(35)

2007年(182)

2006年(92)

我的朋友

分类: LINUX

2012-07-25 10:58:46

VS/DR或VS/TUN应用的一种模型中(所有机器都在同一个物理网络),所有机器(包括Director和RealServer)都使用了一个额外的IP地址,即VIP。当一个客户端向VIP发出一个连接请求时,此请求必须要连接至Director的VIP,而不能是RealServer的。因为,LVS的主要目标就是要Director负责调度这些连接请求至RealServer的。

因此,在Client发出至VIP的连接请求后,只能由Director将其MAC地址响应给客户端(也可能是直接与Director连接的路由设备),而Director则会相应的更新其ipvsadm table以追踪此连接,而后将其转发至后端的RealServer之一。

如果Client在请求建立至VIP的连接时由某RealServer响应了其请求,则Client会在其MAC table中建立起一个VIP至RealServer的对就关系,并以至进行后面的通信。此时,在Client看来只有一个RealServer而无法意识到其它服务器的存在。

为了解决此问题,可以通过在路由器上设置其转发规则来实现。当然,如果没有权限访问路由器并做出相应的设置,则只能通过传统的本地方式来解决此问题了。这些方法包括:

1、禁止RealServer响应对VIP的ARP请求;

2、在RealServer上隐藏VIP,以使得它们无法获知网络上的ARP请求;

3、基于“透明代理(Transparent Proxy)”或者“fwmark (firewall mark)”;

4、禁止ARP请求发往RealServers;

传统认为,解决ARP问题可以基于网络接口,也可以基于主机来实现。Linux采用了基于主机的方式,因为其可以在大多场景中工作良好,但LVS却并不属于这些场景之一,因此,过去实现此功能相当麻烦。现在可以通过设置arp_ignore和arp_announce,这变得相对简单的多了。

Linux 2.2和2.4(2.4.26之前的版本)的内核解决“ARP问题”的方法各不相同,且比较麻烦。幸运的是,2.4.26和2.6的内核中引入了两个新的调整ARP栈的标志(device flags):arp_announce和arp_ignore。基于此,在DR/TUN的环境中,所有IPVS相关的设定均可使用arp_announce=2和arp_ignore=1/2/3来解决“ARP问题”了。

arp_annouce:Define different restriction levels for announcing the local source IP address from IP packets in ARP requests sent on interface;

0 - (default) Use any local address, configured on any interface.

1 - Try to avoid local addresses that are not in the target's subnet for this interface.

2 - Always use the best local address for this target.

arp_ignore: Define different modes for sending replies in response to received ARP requests that resolve local target IP address.

0 - (default): reply for any local target IP address, configured on any interface.

1 - reply only if the target IP address is local address configured on the incoming interface.

2 - reply only if the target IP address is local address configured on the incoming interface and both with the sender's IP address are part from same subnet on this interface.

3 - do not reply for local address configured with scope host, only resolutions for golbal and link addresses are replied.

4-7 - reserved

8 - do not reply for all local addresses

在RealServers上,VIP配置在本地回环接口lo上。如果回应给Client的数据包路由到了eth0接口上,则arp通告或请应该通过eth0实现,因此,需要在sysctl.conf文件中定义如下配置:

#vim /etc/sysctl.conf

net.ipv4.conf.eth0.arp_ignore = 1

net.ipv4.conf.eth0.arp_announce = 2

net.ipv4.conf.all.arp_ignore = 1

net.ipv4.conf.all.arp_announce = 2

以上选项需要在启用VIP之前进行,否则,则需要在Drector上清空arp表才能正常使用LVS。

到达Director的数据包首先会经过PREROUTING,而后经过路由发现其目标地址为本地某接口的地址,因此,接着就会将数据包发往INPUT(LOCAL_IN HOOK)。此时,正在运行内核中的ipvs(始终监控着LOCAL_IN HOOK)进程会发现此数据包请求的是一个集群服务,因为其目标地址是VIP。于是,此数据包的本来到达本机(Director)目标行程被改变为经由POSTROUTING HOOK发往RealServer。这种改变数据包正常行程的过程是根据IPVS表(由管理员通过ipvsadm定义)来实现的。

如果有多台Realserver,在某些应用场景中,Director还需要基于“连接追踪”实现将由同一个客户机的请求始终发往其第一次被分配至的Realserver,以保证其请求的完整性等。其连接追踪的功能由Hash table实现。Hash table的大小等属性可通过下面的命令查看:

# ipvsadm -lcn

为了保证其时效性,Hash table中“连接追踪”信息被定义了“生存时间”。LVS为记录“连接超时”定义了三个计时器

1、空闲TCP会话;

2、客户端正常断开连接后的TCP会话;

3、无连接的UDP数据包(记录其两次发送数据包的时间间隔);

上面三个计时器的默认值可以由类似下面的命令修改,其后面的值依次对应于上述的三个计时器:

# ipvsadm --set 28800 30 600

数据包在由Direcotr发往Realserver时,只有目标MAC地址发生了改变(变成了Realserver的MAC地址)。Realserver在接收到数据包后会根据本地路由表将数据包路由至本地回环设备,接着,监听于本地回环设备VIP上的服务则对进来的数据库进行相应的处理,而后将处理结果回应至RIP,但数据包的原地址依然是VIP。

ipvs的持久连接:

无论基于什么样的算法,只要期望源于同一个客户端的请求都由同一台Realserver响应时,就需要用到持久连接。比如,某一用户连续打开了三个telnet连接请求时,根据RR算法,其请求很可能会被分配至不同的Realserver,这通常不符合使用要求。

1、持久客户端连接(pcc)

2、持久端口连接(ppc)

3、持久防火墙标记连接

4、FTP持久连接

#######################|lvs/DR脚本#############################

###############################################################

Director脚本:

################################################################

#!/bin/bash

#

# LVS script for VS/DR

#

. /etc/rc.d/init.d/functions

#

VIP=192.168.0.210

RIP1=192.168.0.221

RIP2=192.168.0.222

PORT=80

#

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 1

/sbin/ipvsadm -a -t $VIP:80 -r $RIP2 -g -w 2

/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:1 down

/sbin/route del $VIP

/bin/rm -f /var/lock/subsys/ipvsadm

echo "ipvs stopped..."

;;

status)

if [ ! -e /var/lock/subsys/ipvsadm ]; then

echo "ipvsadm stopped ..."

else

echo "ipvs is running ..."

ipvsadm -L -n

fi

;;

*)

echo "Usage: $0 {start|stop|status}"

;;

esac

#############################################################

RealServer脚本:

##############################################################

#!/bin/bash

#

# Script to start LVS DR real server.

# description: LVS DR real server

#

. /etc/rc.d/init.d/functions

VIP=192.168.0.219

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

阅读(645) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~