用LVS构架负载均衡Linux集群系统.docx
《用LVS构架负载均衡Linux集群系统.docx》由会员分享,可在线阅读,更多相关《用LVS构架负载均衡Linux集群系统.docx(23页珍藏版)》请在冰豆网上搜索。
用LVS构架负载均衡Linux集群系统
用LVS构架负载均衡Linux集群系统
最近有客户需要一个负载均衡方案,笔者对各种软硬件的负载均衡方案进行了调查和比较,从IBMsServerCluster、SunClusterPlatForm等硬件集群,到中软、红旗、TurboLinux的软件集群,发现无论采用哪个厂商的负载均衡产品其价格都是该客户目前所不能接受的。
于是笔者想到了开放源项目LinuxVirtualServer(简称LVS)。
经过对LVS的研究和实验,终于在RedHat9.0上用LVS成功地构架了一组负载均衡的集群系统。
整个实现过程整理收录如下,供读者参考。
选用的LVS实际上是一种Linux操作系统上基于IP层的负载均衡调度技术,它在操作系统核心层上,将来自IP层的TCP/UDP请求均衡地转移到不同的服务器,从而将一组服务器构成一个高性能、高可用的虚拟服务器。
使用三台机器就可以用LVS实现最简单的集群,如图1所示。
图1显示一台名为Director的机器在集群前端做负载分配工作;后端两台机器称之为RealServer,专门负责处理Director分配来的外界请求。
该集群的核心是前端的Director机器,LVS就是安装在这台机器上,它必须安装Linux。
RealServer则要根据其选用的负载分配方式而定,通常RealServer上的设置比较少。
接下来介绍Director机器上LVS的安装过程。
图1LVS实现集群系统结构简图
安装
LVS的安装主要是在Director机器上进行,RealServer只需针对不同的转发方式做简单的设定即可。
特别是对LVS的NAT方式,RealServer惟一要做的就是设一下缺省的网关。
所以构架集群的第一步从安装Director机器开始。
首先要在Director机器上安装一个Linux操作系统。
虽然早期的一些RedHat版本,如6.2、7.2、8.0等自带RedHat自己的集群软件,或者是在内核中已经支持LVS,但是为了更清楚地了解LVS的机制,笔者还是选择自行将LVS编入Linux内核的方式进行安装,Linux版本采用RedHat9.0。
如果用户对RedHat的安装比较了解,可以选择定制安装,并只安装必要的软件包。
安装中请选择GRUB做为启动引导管理软件。
因为GRUB在系统引导方面的功能远比LILO强大,在编译Linux内核时可以体会它的方便之处。
LVS是在Linux内核中实现的,所以要对原有的Linux内核打上支持LVS的内核补丁,然后重新编译内核。
支持LVS的内核补丁可以从LVS的官方网站http:
//www.linuxvirtualserver.org下载,下载时请注意使用的Linux核心版本,必须下载和使用的Linux内核版本相一致的LVS内核补丁才行。
对于RedHat9.0,其Linux内核版本是2.4.20,所以对应内核补丁应该是http:
//www.linuxvirtualserver.org/software/kernel-2.4/linux-2.4.20-ipvs-1.0.9.patch.gz。
笔者经过多次实验,使用RedHat9.0自带的Linux源代码无法成功编译LVS的相关模组。
由于时间关系笔者没有仔细研究,而是另外从kernel.org上下载了一个tar包格式的2.4.20内核来进行安装,顺利完成所有编译。
下面是整个内核的编译过程:
1.删除RedHat自带的Linux源代码
#cd/usr/src
#rm-rflinux*
2.下载2.4.20内核
#cd/usr/src
#wgetftp:
//ftp.kernel.org/pub/linux/kernel/v2.4/linux-2.4.20.tar.bz2
3.解压到当前目录/usr/src
#cd/usr/src
#tar-xjpvflinux-2.4.20.tar.bz2
4.建立链接文件
#cd/usr/src#ln-slinux-2.4.20linux-2.4#ln-slinux-2.4.20linux
5.打上LVS的内核补丁
#cd/usr/src
#wgethttp:
//www.linuxvirtualserver.org/software/kernel-2.4/linux-2.4.20-ipvs-1.0.9.patch.gz
#gzip-cdlinux-2.4.20-ipvs-1.0.9.patch.gz
#cd/usr/src/linux
#patch-p1<../linux-2.4.20-ipvs-1.0.9.patch
在打补丁时,注意命令执行后的信息,不能有任何错误信息,否则核心或模组很可能无法成功编译。
6.打上修正ARP问题的内核补丁
#cd/usr/src
#wgethttp:
//www.ssi.bg/~ja/hidden-2.4.20pre10-1.diff
#cd/usr/src/linux
#patch-p1<../hidden-2.4.20pre10-1.diff
这一步在Director机器上可以不做,但是在使用LVS/TUN和LVS/DR方式的RealServer上必须做。
7.为新核心命名
打开/usr/src/linux/Makefile。
注意,在开始部分有一个变量EXTRAVERSION可以自行定义。
修改这个变量,比如改成“EXTRAVERSION=-LVS”后,编译出的核心版本号就会显示成2.4.20-LVS。
这样给出有含义的名称将有助于管理多个Linux核心。
8.检查源代码
#makemrproper
这一步是为确保源代码目录下没有不正确的.o文件及文件的互相依赖。
因为是新下载的内核,所以在第一次编译时,这一步实际可以省略。
9.配置核心选项
#makemenuconfig
命令执行后会进入一个图形化的配置界面,可以通过这个友好的图形界面对内核进行定制。
此过程中,要注意对硬件驱动的选择。
Linux支持丰富的硬件,但对于服务器而言,用不到的硬件驱动都可以删除。
另外,像Multimediadevices、Sound、Bluetoothsupport、AmateurRadiosupport等项也可以删除。
注意,以下几项配置对LVS非常重要,请确保作出正确的选择:
(1)Codematurityleveloptions项
对此项只有以下一个子选项,请选中为*,即编译到内核中去。
[*]Promptfordevelopmentand/orincompletecode/drivers
(2)Networkingoptions项
对此项的选择可以参考以下的配置,如果不清楚含义可以查看帮助:
<*>Packetsocket
[]Packetsocket:
mmappedIO
<>Netlinkdeviceemulation
[*]Networkpacketfiltering(replacesipchains)
[]Networkpacketfilteringdebugging
[*]SocketFiltering
<*>Unixdomainsockets
[*]TCP/IPnetworking
[*]IP:
multicasting
[*]IP:
advancedrouter
[*]IP:
policyrouting
[]IP:
usenetfilterMARKvalueasroutingkey
[]IP:
fastnetworkaddresstranslation
IP:
tunneling
[*]IP:
broadcastGREoverIP
[]IP:
multicastrouting
[]IP:
ARPdaemonsupport(EXPERIMENTAL)
[]IP:
TCPExplicitCongestionNotificationsupport
[]IP:
TCPsyncookiesupport(disabledperdefault)
IP:
NetfilterConfiguration--->
IP:
VirtualServerConfiguration--->
(3)Networkingoptions项中的IP:
VirtualServerConfiguration项
如果打好了LVS的内核补丁,就会出现此选项。
进入VirtualServerConfiguration选项,有以下子选项:
virtualserversupport(EXPERIMENTAL)
[*]IPvirtualserverdebugging
(12)IPVSconnectiontablesize(theNthpowerof2)
---IPVSscheduler
round-robinscheduling
weightedround-robinscheduling
least-connectionschedulingscheduling
weightedleast-connectionscheduling
locality-basedleast-connectionscheduling
locality-basedleast-connectionwithreplicationscheduling
destinationhashingscheduling
sourcehashingscheduling
shortestexpecteddelayscheduling
neverqueuescheduling
---IPVSapplicationhelper
FTPprotocolhelper
以上所有项建议全部选择。
(4)Networkingoptions项中的IP:
NetfilterConfiguration项
对于2.4版本以上的LinuxKernel来说,iptables是取代早期ipfwadm和ipchains的更好选择,所以除非有特殊情况需要用到对ipchains和ipfwadm的支持,否则就不要选它。
本文在LVS/NAT方式中,使用的就是iptables,故这里不选择对ipchains和ipfwadm的支持:
<>ipchains(2.2-style)support
<>ipfwadm(2.0-style)support
10.编译内核
(1)检查依赖关系
#makedep
确保关键文件在正确的路径上。
(2)清除中间文件
#makeclean
确保所有文件都处于最新的版本状态下。
(3)编译新核心
#makebzImage
(4)编译模组
#makemodules
编译选择的模组。
(5)安装模组
#makemodules_install
#depmod-a
生成模组间的依赖关系,以便modprobe定位。
(6)使用新模组
#cpSystem.map/boot/System.map-2.4.20-LVS
#rm/boot/System.map
#ln-s/boot/System.map-2.4.20-LVS/boot/System.map
#cparch/i386/boot/bzImage/boot/vmlinuz-2.4.20-LVS
#rm/boot/vmlinuz
#ln-s/boot/vmlinuz-2.4.20-LVS/boot/vmlinuz
#new-kernel-pkg--install--mkinitrd--depmod2.4.20-LVS
(7)修改GRUB,以新的核心启动
执行完new-kernel-pkg命令后,GRUB的设置文件/etc/grub.conf中已经增加了新核心的启动项,这正是开始安装Linux时推荐使用GRUB做引导程序的原因。
grub.conf中新增内容如下:
titleRedHatLinux(2.4.20-LVS)
root(hd0,0)
kernel/boot/vmlinuz-2.4.20LVSroroot=LABEL=/
initrd/boot/initrd-2.4.20LVS.img
将Kernel项中的root=LABEL=/改成root=/dev/sda1(这里的/dev/sda1是笔者Linux的根分区,读者可根据自己的情况进行不同设置)。
保存修改后,重新启动系统:
#reboot
系统启动后,在GRUB的界面上会出现RedHatLinux(2.4.20-LVS)项。
这就是刚才编译的支持LVS的新核心,选择此项启动,看看启动过程是否有错误发生。
如果正常启动,ipvs将作为模块加载。
同时应该注意到,用LVS的内核启动后在/proc目录中新增了一些文件,比如/proc/sys/net/ipv4/vs/*。
11.安装IP虚拟服务器软件ipvsadm
用支持LVS的内核启动后,即可安装IP虚拟服务器软件ipvsadm了。
用户可以用tar包或RPM包安装,tar包可以从以下地址http:
//www.linuxvirtualserver.org/software/kernel-2.4/ipvsadm-1.21.tar.gz下载进行安装。
这里采用源RPM包来进行安装:
#wgethttp:
//www.linuxvirtualserver.org/software/kernel-2.4/ipvsadm-1.21-7.src.rpm
#rpmbuild--rebuildipvsadm-1.21-7.src.rpm
#rpm-ivh/usr/src/redhat/RPMS/i386/ipvsadm-1.21-7.i386.rpm
注意高版本的rpm命令去掉了--rebuild这个参数选项,但提供了一个rpmbuild命令来实现它。
这一点和以前在RedHat6.2中以rpm—rebuildXXX.src.rpm来安装源RPM包的习惯做法有所不同。
安装完,执行ipvsadm命令,应该有类似如下的信息出现:
#ipvsadm
IPVirtualServerversion1.0.9(size=4096)
ProtLocalAddress:
PortSchedulerFlags
->RemoteAddress:
PortForwardWeightActiveConnInActConn
出现类似以上信息,表明支持LVS的内核和配置工具ipvsadm已完全安装,这台Director机器已经初步安装完成,已具备构架各种方式的集群的条件。
原理
接下来的工作是根据实际需求选择采用何种负载分配方式和调度算法。
目前LVS主要有三种请求转发方式和八种调度算法。
根据请求转发方式的不同,所构架集群的网络拓扑、安装方式、性能表现也各不相同。
用LVS主要可以架构三种形式的集群,分别是LVS/NAT、LVS/TUN和LVS/DR,可以根据需要选择其中一种。
在选定转发方式的情况下,采用哪种调度算法将决定整个负载均衡的性能表现,不同的算法适用于不同的应用场合,有时可能需要针对特殊场合,自行设计调度算法。
LVS的算法是逐渐丰富起来的,最初LVS只提供4种调度算法,后来发展到以下八种:
1.轮叫调度(RoundRobin)
调度器通过“轮叫”调度算法将外部请求按顺序轮流分配到集群中的真实服务器上,它均等地对待每一台服务器,而不管服务器上实际的连接数和系统负载。
2.加权轮叫(WeightedRoundRobin)
调度器通过“加权轮叫”调度算法根据真实服务器的不同处理能力来调度访问请求。
这样可以保证处理能力强的服务器能处理更多的访问流量。
调度器可以自动问询真实服务器的负载情况,并动态地调整其权值。
3.最少链接(LeastConnections)
调度器通过“最少连接”调度算法动态地将网络请求调度到已建立的链接数最少的服务器上。
如果集群系统的真实服务器具有相近的系统性能,采用“最小连接”调度算法可以较好地均衡负载。
4.加权最少链接(WeightedLeastConnections)
在集群系统中的服务器性能差异较大的情况下,调度器采用“加权最少链接”调度算法优化负载均衡性能,具有较高权值的服务器将承受较大比例的活动连接负载。
调度器可以自动问询真实服务器的负载情况,并动态地调整其权值。
5.基于局部性的最少链接(Locality-BasedLeastConnections)
“基于局部性的最少链接”调度算法是针对目标IP地址的负载均衡,目前主要用于Cache集群系统。
该算法根据请求的目标IP地址找出该目标IP地址最近使用的服务器,若该服务器是可用的且没有超载,将请求发送到该服务器;若服务器不存在,或者该服务器超载且有服务器处于一半的工作负载,则用“最少链接”的原则选出一个可用的服务器,将请求发送到该服务器。
6.带复制的基于局部性最少链接(Locality-BasedLeastConnectionswithReplication)
“带复制的基于局部性最少链接”调度算法也是针对目标IP地址的负载均衡,目前主要用于Cache集群系统。
它与LBLC算法的不同之处是它要维护从一个目标IP地址到一组服务器的映射,而LBLC算法维护从一个目标IP地址到一台服务器的映射。
该算法根据请求的目标IP地址找出该目标IP地址对应的服务器组,按“最小连接”原则从服务器组中选出一台服务器,若服务器没有超载,将请求发送到该服务器;若服务器超载,则按“最小连接”原则从这个集群中选出一台服务器,将该服务器加入到服务器组中,将请求发送到该服务器。
同时,当该服务器组有一段时间没有被修改,将最忙的服务器从服务器组中删除,以降低复制的程度。
7.目标地址散列(DestinationHashing)
“目标地址散列”调度算法根据请求的目标IP地址,作为散列键(HashKey)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。
8.源地址散列(SourceHashing)
“源地址散列”调度算法根据请求的源IP地址,作为散列键(HashKey)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。
了解这些算法原理能够在特定的应用场合选择最适合的调度算法,从而尽可能地保持RealServer的最佳利用性。
当然也可以自行开发算法,不过这已超出本文范围,请参考有关算法原理的资料。
实例
理解了上述关于请求转发方式和调度算法的基本概念后,就可以运用LVS来具体实现几种不同方式的负载均衡的集群系统。
LVS的配置是通过前面所安装的IP虚拟服务器软件ipvsadm来实现的。
ipvsadm与LVS的关系类似于iptables和NetFilter的关系,前者只是一个建立和修改规则的工具,这些命令的作用在系统重新启动后就消失了,所以应该将这些命令写到一个脚本里,然后让它在系统启动后自动执行。
网上有不少配置LVS的工具,有的甚至可以自动生成脚本。
但是自己手工编写有助于更深入地了解,所以本文的安装没有利用其它第三方提供的脚本,而是纯粹使用ipvsadm命令来配置。
下面就介绍一下如何配置LVS/NAT、LVS/TUN、LVS/DR方式的负载均衡集群。
1.设定LVS/NAT方式的负载均衡集群
NAT是指NetworkAddressTranslation,它的转发流程是:
Director机器收到外界请求,改写数据包的目标地址,按相应的调度算法将其发送到相应RealServer上,RealServer处理完该请求后,将结果数据包返回到其默认网关,即Director机器上,Director机器再改写数据包的源地址,最后将其返回给外界。
这样就完成一次负载调度。
构架一个最简单的LVS/NAT方式的负载均衡集群如图2所示。
图2LVS/NAT方式的集群简图
RealServer可以是任何的操作系统,而且无需做任何特殊的设定,惟一要做的就是将其默认网关指向Director机器。
RealServer可以使用局域网的内部IP(192.168.0.0/24)。
Director要有两块网卡,一块网卡绑定一个外部IP地址(10.0.0.1),另一块网卡绑定局域网的内部IP(192.168.0.254),作为RealServer的默认网关。
这里将所有LVS的配置命令写到一个可执行脚本中,脚本如下:
#!
/bin/bash
#OpenIPForwarding
echo1>/proc/sys/net/ipv4/ip_forward
#Tomaketheloadbalancerforwardthemasqueradingpackets
iptables-tnat-APOSTROUTING-s192.168.2.0/24-d0.0.0.0/0-oeth0-jMASQUERADE
ipvsadm-C
#ChoosetheWeightedRoundRobing
ipvsadm-A-t10.0.0.1:
80-swrr
#SetRealServer
ipvsadm-a-t10.0.0.1:
80-r192.168.0.1:
873-m-w2
ipvsadm-a-t10.0.0.1:
80-r192.168.0.2:
873-m-w3
ipvsadm
将该脚本保存为/root/lvs_nat.sh,然后加上可执行属性,执行它:
#chmoda+x/root/lvs_nat.sh
#/root/lvs_nat.sh
运行该脚本后,一个简单的LVS/NAT方式的负载均衡集群已经成功架设。
模拟多个用户从外界访问10.0.0.1的80端口,用ipvsadm