LVS-DR工作原理
我们都知道LVS有LVS-DR,LVS-NAT,LVS-TUN三种模式,其中DR模式意为Direct Routing(直接路由)。对于LVS-DR,你到底了解到什么程度?本文通过一个实例场景,详细介绍了其每个执行步骤的工作原理,希望对大家有所帮助。
【51CTO独家特稿】LVS如今早已不再新鲜,在生产环境中的应用非常广泛。它的原理相信运维的同行们多少都知道。但是你到底了解到什么程度呢?
我们都知道LVS有LVS-DR,LVS-NAT,LVS-TUN三种模式,其中DR模式意为Direct Routing(直接路由),是调度器与实际服务器都有一块网卡连在同一物理网段上的情况。本文主要对LVS/DR模式原理进行了阐述,另外还有一篇FAQs,给有相关疑问的朋友们做个参考。
LVS-DR工作原理详解
为了阐述方便,我根据官方原理图另外制作了一幅图,如下图所示:VS/DR的体系结构:
我将结合这幅原理图及具体的实例来讲解一下LVS-DR的原理,包括数据包、数据帧的走向和转换过程。
官方的原理说明:Director接收用户的请求,然后根据负载均衡算法选取一台realserver,将包转发过去,最后由realserver直接回复给用户。
实例场景设备清单:
说明:我这里为了方便,client是与vip同一网段的机器。如果是外部的用户访问,将client替换成gateway即可,因为IP包头是不变的,变的只是源mac地址。
① client向目标vip发出请求,Director接收。此时IP包头及数据帧头信息如下:
② VS根据负载均衡算法选择一台active的realserver(假设是192.168.57.122),将此RIP所在网卡的mac地址作为目标mac地址,发送到局域网里。此时IP包头及数据帧头信息如下:
③ realserver(192.168.57.122)在局域网中收到这个帧,拆开后发现目标IP(VIP)与本地匹配,于是处理这个报文。随后重新封装报文,发送到局域网。此时IP包头及数据帧头信息如下:
④ 如果client与VS同一网段,那么client(192.168.57.135)将收到这个回复报文。如果跨了网段,那么报文通过gateway/路由器经由Internet返回给用户。
以上就是对LVS/DR模式的原理介绍。如果还有其他问题不明白的,可以参考作者另外一篇LVS/DR模式原理剖析的FAQs。
LVS的三种模式区别详解
内容索引 Table of Contents
DR模式:(Direct Routing)直接路由模式
DR模式的工作过程:
当一个client发送一个WEB请求到VIP,LVS服务器根据VIP选择对应的real-server的Pool,根据算法,在Pool中选择一台Real-server,LVS在hash表中记录该次连接,然后将client的请求包发给选择的Real-server,最后选择的Real-server把应答包直接传给client;当client继续发包过来时,LVS根据更才记录的hash表的信息,将属于此次连接的请求直接发到刚才选择的Real-server上;当连接中止或者超时,hash表中的记录将被删除。
DR模式的几个细节:
LVS和Real-server必须在相同的网段
DR模式在转发client的包时,只修改了包目的MAC地址为选定的Real-server的mac地址,所以如果LVS和Real-server在不通的广播域内,那么Real-server就没办法接收到转发的包。下面是mac地址的修改过程:
LVS不需要开启路由转发:
LVS的DR模式不需要开启路由转发功能,就可以正常的工作,出于安全考虑,如果不需要转发功能,最好关闭。
ARP问题:
通常,DR模式需要在Real-server上配置VIP,配置的方式为:
/sbin/ifconfig lo:0 inet VIP netmask 255.255.255.255
原因在于,当LVS把client的包转发给Real-server时,因为包的目的IP地址是VIP,那么如果Real-server收到这个包后,发现包的目的IP不是自己的系统IP,那么就会认为这个包不是发给自己的,就会丢弃这个包,所以需要将这个IP地址绑到网卡上;当发送应答包给client时,Real-server就会把包的源和目的地址调换,直接回复给client。
关于ARP广播:
- 上面绑定VIP的掩码是”255.255.255.255″,说明广播地址是其本身,那么他就不会将ARP发送到实际的自己该属于的广播域了,这样防止与LVS上VIP冲突,而导致IP冲突。
- 另外在Linux的Real-server上,需要设置ARP的sysctl选项:(下面是举例说明设置项的)
假设服务器上ip地址如下所示:
System Interface MAC Address IP Address
HN eth0 00:0c:29:b3:a2:54 192.168.18.10
HN eth3 00:0c:29:b3:a2:68 192.168.18.11
HN eth4 00:0c:29:b3:a2:5e 192.168.18.12
client eth0 00:0c:29:d2:c7:aa 192.168.18.129
当我从192.168.18.129 ping 192.168.18.10时,tcpdump抓包发现:
00:0c:29:d2:c7:aa > ff:ff:ff:ff:ff:ff, ARP, length 60: arp who-has 192.168.18.10 tell 192.168.18.129
00:0c:29:b3:a2:5e > 00:0c:29:d2:c7:aa, ARP, length 60: arp reply 192.168.18.10 is-at 00:0c:29:b3:a2:5e
00:0c:29:b3:a2:54 > 00:0c:29:d2:c7:aa, ARP, length 60: arp reply 192.168.18.10 is-at 00:0c:29:b3:a2:54
00:0c:29:b3:a2:68 > 00:0c:29:d2:c7:aa, ARP, length 60: arp reply 192.168.18.10 is-at 00:0c:29:b3:a2:68
00:0c:29:d2:c7:aa > 00:0c:29:b3:a2:5e, IPv4, length 98: 192.168.18.129 > 192.168.18.10: ICMP echo request, id 32313, seq 1, length 64
00:0c:29:b3:a2:54 > 00:0c:29:d2:c7:aa, IPv4, length 98: 192.168.18.10 > 192.168.18.129: ICMP echo reply, id 32313, seq 1, length 64
00:0c:29:d2:c7:aa > 00:0c:29:b3:a2:5e, IPv4, length 98: 192.168.18.129 > 192.168.18.10: ICMP echo request, id 32313, seq 2, length 64
00:0c:29:b3:a2:54 > 00:0c:29:d2:c7:aa, IPv4, length 98: 192.168.18.10 > 192.168.18.129: ICMP echo reply, id 32313, seq 2, length 64
00:0c:29:b3:a2:54 > 00:0c:29:d2:c7:aa, ARP, length 60: arp who-has 192.168.18.129 tell 192.168.18.10
00:0c:29:d2:c7:aa > 00:0c:29:b3:a2:54, ARP, length 60: arp reply 192.168.18.129 is-at 00:0c:29:d2:c7:aa
三个端口都发送了arp的reply包,但是192.168.18.129使用的第一个回应的eth4的mac地址作为ping请求的端口,由于192.168.18.10是icmp包中的目的地址,那么ping的应答包,会从eth0端口发出。
如果Real-server有个多个网卡,每个网卡在不同的网段,那么可以过滤掉非本网卡ARP请求的回应;但是如果多个网卡的ip在一个网段,那么就不行了。
sysctl -w net.ipv4.conf.all.arp_filter=1
对于多个接口在相同网段可以设置下面的来防止:
sysctl -w net.ipv4.conf.all.arp_ignore=1
sysctl -w net.ipv4.conf.all.arp_announce=2
还是从192.168.18.129 ping 192.168.18.10时,tcpdump抓包发现:
00:0c:29:d2:c7:aa > ff:ff:ff:ff:ff:ff, ARP, length 60: arp who-has 192.168.18.10 tell 192.168.18.129
00:0c:29:b3:a2:54 > 00:0c:29:d2:c7:aa, ARP, length 60: arp reply 192.168.18.10 is-at 00:0c:29:b3:a2:54
00:0c:29:d2:c7:aa > 00:0c:29:b3:a2:54, IPv4, length 98: 192.168.18.129 > 192.168.18.10: ICMP echo request, id 32066, seq 1, length 64
00:0c:29:b3:a2:54 > 00:0c:29:d2:c7:aa, IPv4, length 98: 192.168.18.10 > 192.168.18.129: ICMP echo reply, id 32066, seq 1, length 64
00:0c:29:d2:c7:aa > 00:0c:29:b3:a2:54, IPv4, length 98: 192.168.18.129 > 192.168.18.10: ICMP echo request, id 32066, seq 2, length 64
00:0c:29:b3:a2:54 > 00:0c:29:d2:c7:aa, IPv4, length 98: 192.168.18.10 > 192.168.18.129: ICMP echo reply, id 32066, seq 2, length 64
00:0c:29:b3:a2:54 > 00:0c:29:d2:c7:aa, ARP, length 60: arp who-has 192.168.18.129 tell 192.168.18.10
00:0c:29:d2:c7:aa > 00:0c:29:b3:a2:54, ARP, length 60: arp reply 192.168.18.129 is-at 00:0c:29:d2:c7:aa
看到了么,现在只有eth0会回应arp请求了。
arp报文格式:
请求报文:MAC地址字段是空的。 应答报文:所有字段都又内容。:
The arp_announce/arp_ignore reference:
arp_announce – INTEGER
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. This mode is useful when target
hosts reachable via this interface require the source IP
address in ARP requests to be part of their logical network
configured on the receiving interface. When we generate the
request we will check all our subnets that include the
target IP and will preserve the source address if it is from
such subnet. If there is no such subnet we select source
address according to the rules for level 2.
2 – Always use the best local address for this target.
In this mode we ignore the source address in the IP packet
and try to select local address that we prefer for talks with
the target host. Such local address is selected by looking
for primary IP addresses on all our subnets on the outgoing
interface that include the target IP address. If no suitable
local address is found we select the first local address
we have on the outgoing interface or on all other interfaces,
with the hope we will receive reply for our request and
even sometimes no matter the source IP address we announce.
The max value from conf/{all,interface}/arp_announce is used.
Increasing the restriction level gives more chance for
receiving answer from the resolved target while decreasing
the level announces more valid sender’s information.
arp_announce 用来限制,是否使用发送的端口的ip地址来设置ARP的源地址:
- “0″代表是用ip包的源地址来设置ARP请求的源地址。
- “1″代表不使用ip包的源地址来设置ARP请求的源地址,如果ip包的源地址是和该端口的IP地址相同的子网,那么用ip包的源地址,来设置ARP请求的源地址,否则使用”2″的设置。
- “2″代表不使用ip包的源地址来设置ARP请求的源地址,而由系统来选择最好的接口来发送。
当内网的机器要发送一个到外部的ip包,那么它就会请求路由器的Mac地址,发送一个arp请求,这个arp请求里面包括了自己的ip地址和Mac地址,而linux默认是使用ip的源ip地址作为arp里面的源ip地址,而不是使用发送设备上面的 ,这样在lvs这样的架构下,所有发送包都是同一个VIP地址,那么arp请求就会包括VIP地址和设备 Mac,而路由器收到这个arp请求就会更新自己的arp缓存,这样就会造成ip欺骗了,VIP被抢夺,所以就会有问题。
现在假设一个场景来解释 arp_announce :
Real-server的ip地址:202.106.1.100(public local address),
172.16.1.100(private local address),
202.106.1.254(VIP)
如果发送到client的ip包产生的arp请求的源地址是202.106.1.254(VIP),那么LVS上的VIP就会被冲掉,因为交换机上现在的arp对应关系是Real-server上的VIP对应自己的一个MAC,那么LVS上的VIP就失效了。:
arp_ignore – INTEGER
Define different modes for sending replies in response to
received ARP requests that resolve local target IP addresses:
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 addresses configured with scope host,
only resolutions for global and link addresses are replied
4-7 – reserved
8 – do not reply for all local addresses
The max value from conf/{all,interface}/arp_ignore is used
when ARP request is received on the {interface}
“0″,代表对于arp请求,任何配置在本地的目的ip地址都会回应,不管该arp请求的目的地址是不是接口的ip;如果有多个网卡,并且网卡的ip都是一个子网,那么从一个端口进来的arp请求,别的端口也会发送回应。 “1″,代表如果arp请求的目的地址,不是该arp请求包进入的接口的ip地址,那么不回应。 “2″,要求的更苛刻,除了”1″的条件外,还必须要求arp发送者的ip地址和arp请求进入的接口的ip地址是一个网段的。 (后面略)
IP Tunneling模式:
IP Tunneling的工作过程
1> client 发送request包到LVS服务器的VIP上。
2> VIP按照算法选择后端的一个Real-server,并将记录一条消息到hash表中,然后将client的request包封装到一个新的IP包里,新IP包的目的IP是Real-server的IP,然后转发给Real-server。
3> Real-server收到包后,解封装,取出client的request包,发现他的目的地址是VIP,而Real-server发现在自己的lo:0口上有这个IP地址,于是处理client的请求,然后将relpy这个request包直接发给client。
4> 该client的后面的request包,LVS直接按照hash表中的记录直接转发给Real-server,当传输完毕或者连接超时,那么将删除hash表中的记录。
IP Tunneling的几个细节问题
LVS和Real-server不需要在一个网段:
由于通过IP Tunneling 封装后,封装后的IP包的目的地址为Real-server的IP地址,那么只要Real-server的地址能路由可达,Real-server在什么网络里都可以,这样可以减少对于公网IP地址的消耗,但是因为要处理IP Tunneling封装和解封装的开销,那么效率不如DR模式。
Real-server的系统设置:
由于需要Real-server支持IP Tunneling,所以设置与DR模式不太一样,LVS不需要设置tunl设备,LVS本身可以进行封装 i) 需要配置VIP在tunl设备上:(VIP:172.16.1.254)
shell> ifconfig tunl0 172.16.1.254 netmask 255.255.255.255
shell> ifconfig tunl0
tunl0 Link encap:IPIP Tunnel HWaddr
inet addr:172.16.1.254 Mask:255.255.255.255
UP RUNNING NOARP MTU:1480 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
当添加tunl0设备时,自动载入需要的模块:
shell> lsmod |grep ipip
ipip 7516 0
tunnel4 2700 1 ipip
其中,ipip依赖于tunnel4,假如现在删除tunnel4的话:
shell> rmmod tunnel4
ERROR: Module tunnel4 is in use by ipip
如果添加tunl0失败,那么可能是内核没有开启tunneling功能,默认是以模块形式,加载到内核里的:
ARP问题:
如果LVS和Real-server不在一个网络内,不需要处理ARP问题,如果在相同网络,那么处理方法和DR模式一样,但是如果一样,我就不知道选择tun模式有什么好理由了,DR似乎效率更高些吧。
内核的包转发:
IP Tunneling模式不需要开启ip_forward功能。
NAT模式:
NAT模式的工作过程:
client:202.100.1.2
VIP:202.103.106.5
Real-server:172.16.0.2 和 172.16.0.3(提供http和ftp服务)
1> client发送request到LVS的VIP上,VIP选择一个Real-server,并记录连接信息到hash表中,然后修改client的request的目的IP地址为Real-server的地址,将请求发给Real-server;
2> Real-server收到request包后,发现目的IP是自己的IP,于是处理请求,然后发送reply给LVS;
3> LVS收到reply包后,修改reply包的的源地址为VIP,发送给client;
4> 从client来的属于本次连接的包,查hash表,然后发给对应的Real-server。
5> 当client发送完毕,此次连接结束或者连接超时,那么LVS自动从hash表中删除此条记录。
下面是地址转换的过程:
NAT模式的几个细节问题
NAT模式的Bugs
- 在Linux的2.6版本,LVS-NAT不能做防火墙,在只有一个网关的情况下,没有任何问题。
- 防火墙不兼容:LVS的架构中,LVS的前端不能设置防火墙,修复的补丁”NFCT” patch。
- 源路由问题
ICMP重定向问题
一. 对于路由器来说,只有当如下条件同时满足的时候,才进行重定向
- 数据包的入接口和路由后的指定的出接口是同一个接口。
- 数据包的源IP地址和该包应走的下一跳IP地址属于同一个网段。
- 数据报非源路由的(这种情况应该比较少见了,源路由多见于Token Ring)。
- 系统开启重定向功能。
- 例如:
- 两个路由器都开启了IP重定向功能。HostA 的默认网关为1.1.1.1。当HostA要和不在同一网段中的HostB通信的时候,会把数据报递交给默认网关RT1。然而RT1经过查找发现到达3.3.3.3的路径下一跳恰恰是经由自己的E0/1口的RT2接口1.1.1.2。满足上述条件,将会发生重定向。
二. LVS为什么会产生ICMP重定向问题: * 在LVS-NAT模式下,如果LVS的各个成员,client,LVS,Real-server在同一个网段(比如:192.168.1.*/24);
- 当Real-server将Reply发送回LVS时,Reply包是 RIP -> CIP的,LVS看到RIP-> CIP实际上根本没必要经过LVS,直接到网关就行了,因为大家在一个网段,所以产生ICMP重定向发送给Real-server;
- Real-server收到ICMP重定向包后,如果Real-server的ICMP重定向开启了,Real-server就会处理ICMP重定向包,直接将Reply包发给网关,这时Reply包头并没有被LVS重写,所以LVS负载出现了问题。
注意:这种情况只会出现在所有的LVS的成员都在一个网段的情况下。
重定向的处理办法(Real-server的配置):
1> 关闭Real-server的重定向,忽略LVS发来的重定向包
2> 删除到网段的路由:
执行:
realserver:/etc/lvs#route del -net 192.168.1.0 netmask 255.255.255.0 dev eth0
路由已经被删除了:
3> LVS-NAT模式支持四层的端口重写: LVS-DR,LVS-TUN不能修改client发来的请求的目的端口,但是LVS-NAT可以,参考命令:
shell> ipvsadm -a -t VIP:PORT -r RIP:NEWPORT -m -w 1
我们在上博文“运维工程师必备之负载均衡集群及LVS详解”中详细介绍了负载均衡和集群的基本理论和类别,此处不在详细介绍,在本篇博文中则主要以LB负载均衡集群的类别:NAT和DR模型的web网络架构进行实例介绍,以便我们进一步了解负载均衡集群的理论架构和应用场景!
一、架构平台环境:
平台:RedHat Enterprise Linux 5.8 ipvsadm ipvs 相关服务和名字的定义: Director:负载调度集群的主机,也简称DR VIP:Virtual IP,向外提供服务的IP RIP:Real Server IP,内部真正提供服务的 DIP:与内部主机通信的IP,在DR主机上 CIP:客户端IP
二、架构类型模型的简介
⑴、NAT模型
NAT模型:地址转换类型,主要是做地址转换,类似于iptables的DNAT类型,它通过多目标地址转换,来实现负载均衡,一个Director最多负载提供10个Real Server主机
特点和架构要求:
1、LVS上面需要双网卡:DIP和VIP
2、内网的Real Server主机的IP必须和DIP在同一个网络中,并且要求其网关都需要指向DIP的地址
3、RIP都是私有IP地址,仅用于各个节点之间的通信
4、Director位于client和Real Server之间,负载处理所有的进站、出站的通信
5、支持端口映射
6、通常应用在较大规模的应用场景中,但Director易成为整个架构的瓶颈!
⑵、DR模型
DR模型:直接路由模型,每个Real Server上都有两个IP:VIP和RIP,但是VIP是隐藏的,就是不能提高解析等功能,只是用来做请求回复的源IP的,Director上只需要一个网卡,然后利用别名来配置两个IP:VIP和DIP
Director在接受到外部主机的请求的时候转发给Real Server的时候并不更改目标地址,只是通过arp解析的MAC地址进行封装然后转给Real Server,Real Server在接受到信息以后拆除MAC帧封装,然后直接回复给CIP。
企业中最常用的就是LB架构就是DR模型
特点和架构要求:
1、各个集群节点必须和Director在同一个物理网络中
2、RIP地址不能为私有地址,可以实现便捷的远程管理和监控
3、Director仅仅负责处理入站请求,响应报文则由Real Server直接发往客户端
4、集群节点Real Server 的网关一定不能指向DIP,而是指向外部路由
5、Director不支持端口映射
6、Director能够支持比NAT多很多的Real Server
注意:由于在负载均衡集群和高可用集群的时候要求服务器的时间必须一致,否则将会出现服务不协调等致命性的错误,我们这里把DR设置成为时间服务器,来为RS1和RS2提供时间校准,从而来保证负载均衡集群的正常运行!(关于时间服务器NTP-SERVER的搭建和配置我会在后两天的时间里发表博文详细介绍时间服务器的安装和配置),当然如果没有时间服务器也可以自己手动设置各个服务器的时间来保证时间的一致性!
三、LB基于LVS的web架构之NAT实现web服务的负载均衡
⑴、方案规划和架构图
Director需要两个网卡:DIP和VIP
RS上各需一个网卡即可
由于此处是在虚拟机中测试实验,为了便于实验和搭建,此处的CIP和VIP没有选择公网内的IP,现实的搭建中选择公网IP的时候路由会自动寻路的,这里选择同一个网络中是为了不在设置路由信息了。可以直接搭建环境进行测试
⑵、架构步骤
1、在web-RS1和web-RS2上分别按照设计设置IP地址和web服务,此处利用yum进行软件包的安装,便于解决软件包之间的依赖关系!(yum的安装和配置见:Linux系统常用的软件管理工具rpm、yum及软件源码编译安装http://chrinux.blog.51cto.com/6466723/1193854 )
WEB-RS1:
配置web1的RIP
vim /etc/sysconfig/network-scripts/ifcfg-eth0 #编辑网络配置,配置如下 DEVICE=eth0 BOOTPROTO=static ONBOOT=yes IPADDR=192.168.7.3 NETMASK=255.255.255.0 GATEWAY=192.168.7.2
然后重启网络服务即可
service network restart
为了服务出问题,我们这里先把selinux给关闭了
时间校准:
ntpdate 192.168.7.2 #注意时间的同步,我这里把DR和NTPserver设置在了同一台服务器上了!若没ntp-server也可也手动设置时间,只要保证各个服务器之间的时间相同就行!
然后来安装我们的httpd服务吧!
yum –y install httpd #利用yum安装httpd服务
echo "web1.chris.com" > /var/www/html/index.html #设置主页内容
至此web1上的基本配置基本完成!下面在web2上进行相关的配置吧!
WEB-RS2
配置web2的RIP
vim /etc/sysconfig/network-scripts/ifcfg-eth0 #编辑网络配置,配置如下 DEVICE=eth0 BOOTPROTO=static ONBOOT=yes IPADDR=192.168.7.4 NETMASK=255.255.255.0 GATEWAY=192.168.7.2
然后重启网络服务即可
service network restart
关闭selinux
setenforce 0
永久关闭
vim /etc/selinux/config 设置内容SELINUX=permissive
校准时间
安装httpd服务
yum -y install httpd
echo "web2.chris.com" > /var/www/html/index.html #设置主页内容
至此我们web-RS2上的基本设置基本完成了
⑵、测试web-RS1和web-RS2上的web服务能够正常工作
在RS1和RS2上启动httpd服务:
service httpd start
在DR服务器上进行httpd的服务的测试:
⑶、DR上面的配置
1、先配置网络:eth0-DIP和eth1-VIP
vim /etc/sysconfig/network-scripts/ifcfg-eth0 设置内容如下: # Advanced Micro Devices [AMD] 79c970 [PCnet32 LANCE] DEVICE=eth0 BOOTPROTO=static ONBOOT=yes IPADDR=172.16.7.1 #DIP地址 NETMASK=255.255.0.0 GATEWAY=172.16.7.49 #此网关设置需要根据实际需要设置,我这里设置的是利用我物理卷的IP进行网络访问来架设NTP-SERVER了! HWADDR=00:0c:29:84:7c:a6 vim /etc/sysconfig/network-scripts/ifcfg-eth1 设置内容如下: DEVICE=eth1 BOOTPROTO=static IPADDR=192.168.7.2 #VIP地址 NETMASK=255.255.255.0 ONBOOT=yes HWADDR=00:0c:29:84:7c:b0
2、关闭selinux
和上面的设置一样
临时关闭selinux
setenforce 0
永久关闭
vim /etc/selinux/config 设置内容SELINUX=permissive
时间同步:
现在192.168.7.2自己本身就是NTP时间服务器,它的时间就是标准时间不需要同步!
⑶、LVS基于NAT的配置
1、LVS模块:内核模块ipvs和用户空间命令ipvsadm的安装。
在linux 2.4.23之后及2.4.23的内核中i已经内置了ipvs模块,不需要我们自己再手动编译为内核打补丁了,利用grep -i 'ip_vs' /boot/config-2.6.18-308.el5 可以查看内核编译的时候是否编译了ipvs功能
OK!那我们只需要为安装我们的用户模块:ipvsadm即可
yum –y install ipvsadm #安装ipvsadm
2、配置LVS基于NAT实现负载均衡集群
ipvsadm -A -t 172.16.7.1:80 -s rr #添加集群 ipvsadm -a -t 172.16.7.1:80 -r 192.168.7.3 –m #添加节点 ipvsadm -a -t 172.16.7.1:80 -r 192.168.7.4 –m #添加节点
到此我们基本的配置已经完成,下面来测试下吧
此时我们请求的页面Directorserver会利用轮询的方式依次交换让web服务器来提供页面的响应,但是有时候我们的服务器的性能差异比较大,这时候希望服务器性能比较好的服务器来响应更多的请求,则是就需要修改写负载均衡的算法了,把rr修改为wrr给其加上权重!
此时在进行页面测试,效果如下
OK,至此,我们的LVS基于NAT模式来实现web服务的负载均衡就已经搭建完成了,下面我们进行基于DR模式的负载均衡把!
四、LB基于LVS的web架构之DR实现web服务的负载均衡
⑴、方案规划和架构图
每个服务器上需要一个网卡即可,Director的VIP在eth0:0上,DIP在ETH0上,而RS上的DIP在eth0上,VIP配置在lo:0上,而且VIP和DIP都必须为公网的IP。这样才能实现以RS直接回复客户端的请求!
关于DR模型有两种:
DR的DIP和VIP、RIP都是在同一网段内的服务器
VIP为公网地址,DIP和RIP为私有地址,则此时需要把RS的网关指向另外一个路由接口,来利用arp解析RS的发送报文,来保证eth0结构能够与外部网络通信。
我们这里就以所有IP地址否是公网IP来进行试验了
⑵、通信原理:
每个Real Server上都有两个IP:VIP和RIP,但是VIP是隐藏的,就是不能提高解析等功能,只是用来做请求回复的源IP的,Director上只需要一个网卡,然后利用别名来配置两个IP:VIP和DIP
Director在接受到外部主机的请求的时候转发给Real Server的时候并不更改目标地址,只是通过arp解析的MAC地址进行封装然后转给Real Server,Real Server在接受到信息以后拆除MAC帧封装,然后直接回复给CIP。
而此时需要关闭RS上的基于VIP的arp解析,在linux内核2.4以后,内核中都内置了这种功能,通过一些设置可以关闭其arp的功能:
arp_ignore:定义接收到ARP请求时的响应级别 0:默认,只用本地配置的有响应地址都给予响应 1:仅仅在目标IP是本地地址,并且是配置在请求进来的接口上的时候才给予响应(仅在请求的目标地址配置请求到达的接口上的时候,才给予响应) arp_announce:定义将自己的地址向外通告时的级别 0:默认,表示使用配置在任何接口的任何地址向外通告 1:试图仅向目标网络通告与其网络匹配的地址 2:仅向与本地接口上地址匹配的网络进行通告 注意:要想让其功能生效,必须先设置相关设置,然后在配置IP地址等信息
⑶、架构步骤
1、DR1-web服务器的设置
与上面的设置相同,具体步骤如下,其设置不在详细介绍!
①、关闭arp请求响应---这个必须先设置在再设置IP不然就不能生效了
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce #设置地址向外通告时的级别 echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore #定义接收到ARP请求时的响应级别 echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
注意:此处通过定义这两个才能实现关闭lo上的arp解析功能的响应
这时来自director上面的两个网卡lo和eth0,通告和解析的时候都是通过eth0来进行解析实现的,这样通过关闭此功能来实现用户请求的报文的网卡和IP不在同一个接口上的时候不予响应--arp-ignore linux中有一种行为,数据报文从哪个接口出去就是使用哪个接口作为源地址进行数据封装。所以此处转发的时候的响应报文就不符合规则了,此时需要通过添加一条路由规则来实现数据的目标地址做为源地址。所以我们需要通过添加一条路由来解决这个问题,在下面我们配置ip的时候再说吧!
②、配置ip地址
DEVICE=eth0 BOOTPROTO=static IPADDR=172.16.7.3 NETMASK=255.255.0.0 GATEWAY=172.16.7.49 #此时的网关不再需要指向DS的DIP ONBOOT=yes HWADDR=00:0c:29:29:c4:5a
而后重启网络服务并在lo:0上配置VIP
③、安装并配置httpd服务,上面的已经配置过,这里不在重新设置
2、DR2-web服务器的设置
重启网络服务,然后设置本机的arp请求解析级别并设置VIP
③、安装并配置httpd服务,上面的已经配置过,这里不在重新设置。
3、DS服务器的设置
配置网络地址:
在eth0上的DIP:172.16.7.2/16 DEVICE=eth0 BOOTPROTO=static ONBOOT=yes IPADDR=172.16.7.2 NETMASK=255.255.0.0 GATEEAY=172.16.7.49 HWADDR=00:0c:29:84:7c:a6 在eth0:0上的VIP:172.16.7.1/16
在RS1和RS2上分别启动httpd服务,然后在DS上测试其是否能工作正常
service httpd start
OK,基本的网络设置我们已经配置完成了,那么下面来进行LVS基于DR模型的设置吧,其实也很简单,命令如下:
下面来测试下我们的效果吧
OK,到此我们就实现了LVS基于DR模型的架构来实现web服务的负载均衡集群!下面再介绍下LVS的持久连接的相关内容吧!
五、LVS的持久连接
1、基本原理和简介
在互联网购物、网上银行进行交易的时候,需要用到持久连接,那么什么是持久连接呢?
LVS的持久连接,是一种不基于算法,来实现在一段时间内,将来自于同一个客户端的请求都派发给同一个real server。
其工作机制是:在内存缓存区内,其中记录了每个客户端及其分配给它的RS的映射关系。
2、开启LVS的长连接
ipvsadm -A|E ... -p timeout; 利用-p timeout关键字就可以开启LVS的长连接
其中timeout默认时长是300秒,默认单位秒
3、LVS的类型
PPC:持久端口连接、将来自于同一个客户端的同一个服务的请求始终定向到同一个real server
fg:ipvsadm -A -t 172.16.7.1:80 -s rr –p
PCC:持久客户端连接,将来自于同一个客户端的所有服务都始终定向至此前选定的RS
fg:ipvsadm -A -t 172.16.7.1:0 -s rr –p (0代表所有端口),只用使用了PCC,就是把所有端口统统定义为集群服务,一律向RS转发,PCC定义的是所有端口
PNMPP:持久防火墙标记连接,能够定义端口间的引擎关系的。通过PREROUTING上对端口进行打标纪,来实现部分端口的集群,把几个毫不相关的服务绑在一起实现集群
fg:
iptables -t mangle -A PREROUTING -d 172.16.7.1 -i eth0 -p tcp --dport 80 – j MARK --set-mark 8 #prerouting代表在进入主机之前就打好标记 iptables -t mangle -A PREROUTING -d 172.16.7.1 -i eth0 -p tcp --dport 443 -j MARK --set-mark 8
在lVS内启用PNMPP ipvsadm -A -f 8 -s rr ipvsadm -a -f 8 -r 172.16.7.3 -g -w 2 ipvsadm -a -f 8 -r 172.16.7.4 -g -w 3
持久性连接的配置上上面的集群负载均衡的配置一样,只是增加了个参数而已,这里不在举例说名了,还望谅解~
上面只是我们实现的比较简单的集群功能,当然这样简单的集群式构建后来的高可用集群的基础,必须要能熟练搭建,但是此时的负载均衡看着还是比较脆弱的,例如:RS1挂了,这是DS还是利用我们指定的规则来提供服务的,当轮到RS1的时候我们的网络就无法访问到了,这是我们就需要来利用相关脚本来实现对服务器健康状况的健康,从而来保证服务的不间断性,是不是有点像高可用集群了,哎~写脚本需要时间来慢慢的推敲,并进行多方的测试,才能用在生成环境中,当然我们后面的高可用负载均衡是可以很容易解决这个问题的,如果你想锻炼锻炼自己的思维能力,就自己动手写个脚本吧~我的还没写出来~嘿嘿,脑子不是很好啊!等过两天写好了在分享给大家,到时候还望各位多提点优化的意见!
此时我们的负载均衡服务器还可以结合存储服务器来保证数据的安全性和一致性!例如利用一个nfs服务器来保证我们无论访问的是那个主机其主页面都是一样的,这个是很简单的,大致步骤为下:
1、配置nfs共享目录
2、RS1和RS2分别把共享目录挂载到主页目录放置的位置/var/www/html/下,在其共享目录上提供主页面即可!