集 群(一)之负载均衡集群(LVS) ipvsadm(1.0版本)
定义
这是一个由国人主持的项目。它是一个负载均衡/高可用性集群,主要针对大业务量的网络应用(如新闻服务、网上银行、电子商务等)。
LVS是建立在一个主控服务器(通常为双机)(director)及若干真实服务器(real-server)所组成的集群之上。real-server负责实际提供服务,主控服务器根据指定的调度算法对real-server进行控制。而集群的结构对于用户来说是透明的,客户端只与单个的IP(集群系统的虚拟IP)进行通信,也就是说从客户端的视角来看,这里只存在单个服务器。Real-server可以提供众多服务,如ftp, http, dns, telnet, nntp, smtp 等。主控服务器负责对Real-Server进行控制。客户端在向LVS发出服务请求时,主控服务器(Director)会通过特定的调度算法来指定由某个Real-Server来应答请求,而客户端只与Load Balancer的IP(即虚拟IP,VIP)进行通信.
客户端发出服务请求à主控服务器接受请求à指定某个real-server来应答请求
(之间的通讯是通过虚拟IP来进行传递)
二、 集群采用三层结构
一般来说,LVS集群采用三层结构,其主要组成部分为:
A、负载调度器(load balancer),它是整个集群对外面的前端机,负责将客户的请求按照一定的算法分发到下一层不同的服务器进行处理,自己本身不做具体业务的处理。而客户认为服务是来自一个IP地址(我们可称之为虚拟IP地址)上的。这是LVS的核心部分,另外该层还可用监控下一层的状态,如果下一层的某台服务器不能正常工作了,它会自动把其剔除,恢复后又可用加上。该层由一台或者几台Director Server组成。
B、服务器池(server pool),是一组真正执行客户请求的服务器,执行的服务有WEB、MAIL、FTP和DNS等。
C、共享存储(shared storage),它为服务器池提供一个共享的存储区,这样很容易使得服务器池拥有相同的内容,提供相同的服务。
负载调度器、服务器池和共享存储系统通过高速网络相连接,如100Mbps交换网络、Myrinet和Gigabit网络等。使用高速的网络,主要为避免当系统规模扩大时互联网络成为整个系统的瓶颈。
三、负载均衡机制
前面我们说了LVS是工作在网络层。相对于其它负载均衡的解决办法,比如DNS域名轮流解析、应用层负载的调度、客户端的调度等,它的效率是非常高的。LVS的通过控制IP来实现负载均衡。IPVS是其具体的实现模块。
IPVS的主要作用:安装在Director Server上面,在Director Server虚拟一个对外访问的IP(VIP)。用户访问VIP,到达Director Server,Director Server根据一定的规则选择一个Real Server,处理完成后然后返回给客户端数据。这些步骤产生了一些具体的问题,比如如何选择具体的Real Server,Real Server如何返回给客户端数据等等。
IPVS为此有三种机制:
1.VS/NAT(Virtual Server via Network Address Translation),即网络地址翻转技术实现虚拟服务器。
客户通过Virtual IP Address(虚拟服务的IP地址)访问网络服务时,请求报文到达调度器,调度器根据连接调度算法从一组真实服务器中选出一台服务器,将报文的目标地址Virtual IP Address改写成选定服务器的地址,报文的目标端口改写成选定服务器的相应端口,最后将修改后的报文发送给选出的服务器(Real Server)。同时,调度器在连接Hash表中记录这个连接,当这个连接的下一个报文到达时,从连接Hash表中可以得到原选定服务器的地址和端口,进行同样的改写操作,并将报文传给原选定的服务器。
Real Server处理完数据后,需要返回给Diretor Server,然后Diretor server将数据包中的源地址和源端口改成VIP的地址和端口,最后把数据发送出去给用户。这样,客户所看到的只是在Virtual IP Address上提供的服务,而服务器集群的结构对用户是透明的
由此可以看出,用户的请求和返回都要经过Diretor Server,如果数据过多,调度器肯定会不堪重负。
如下图所示:在一组服务器前有一个调度器,它们是通过Switch/HUB相连接的。这些服务器提供相同的网络服务、相同的内容,即不管请求被发送到哪一台服务器,执行结果是一样的。服务的内容可以复制到每台服务器的本地硬盘上,可以通过网络文件系统(如NFS)共享,也可以通过一个分布式文件系统来提供。
VS/NAT 的优点是服务器可以运行任何支持TCP/IP的操作系统,它只需要一个IP地址配置在调度器上,服务器组可以用私有的IP地址。缺点是它的伸缩能力有限, 当服务器结点数目升到20时,调度器本身有可能成为系统的新瓶颈,因为在VS/NAT中请求和响应报文都需要通过负载调度器。
2.VS/TUN(Virtual Server via IP Tunneling),即IP隧道技术实现虚拟服务器。它跟VS/NAT基本一样,但是Real server是直接返回数据给客户端,不需要经过Diretor server,这大大降低了Diretor server的压力。
在VS/TUN 的集群系统中,负载调度器只将请求调度到不同的后端服务器,后端服务器将应答的数据直接返回给用户。这样,负载调度器就可以处理大量的请求,它甚至可以调度百台以上的服务器(同等规模的服务器),而它不会成为系统的瓶颈。即使负载调度器只有100Mbps的全双工网卡,整个系统的最大吞吐量可超过 1Gbps。所以,VS/TUN可以极大地增加负载调度器调度的服务器数量。VS/TUN调度器可以调度上百台服务器,而它本身不会成为系统的瓶颈,可以 用来构建高性能的超级服务器。
IP隧道(IP tunneling)是将一个IP报文封装在另一个IP报文的技术,这可以使得目标为一个IP地址的数据报文能被封装和转发到另一个IP地址。IP隧道技术亦称为IP封装技术(IP encapsulation)。IP隧道主要用于移动主机和虚拟私有网络(Virtual Private Network),在其中隧道都是静态建立的,隧道一端有一个IP地址,另一端也有唯一的IP地址。
VS/TUN技术对服务器的要求是所有的服务器必须支持"IP Tunneling"或者"IP Encapsulation"协议。目前,VS/TUN 的后端服务器主要运行Linux操作系统。因为"IP Tunneling"正成为各个操作系统的标准协议,所以VS/TUN也会适用运行其它操作系统的后端服务器
VS/TUN的工作流程如下图所示,它的连接调度和管理与VS/NAT中的一样,只是它的报文转发方法不同。调度器根据各个服务器的负载情况,动态地选择一台服务器,将请求报文封装在另一个IP报文中,再将封装后的IP报文转发给选出的服务器;服务器收到报文后,先将报文解封获得原来目标地址为VIP的报文,服务器发现VIP地址被配置在本地的IP隧道设备上,所以就处理这个请求,然后根据路由表将响应报文直接返回给客户。(各个服务器要将VIP地址配置在自己的IP隧道设备上)
VS-TUN的real-servers相对于director可以远程;而且每个real-server都可以在单独的网络上,但需要在路由器上做工作,允许源地址为VIP的输出包。配置方法和要求与VS-DR方式类似。只是需要将lo:0设备换为tunl0设备,其对应模块为ipip;VS-TUN方式的特点和VS-DR相似,不过主要用于real-server分布在因特网之上的情况,real-servers对于director可以是远程的,real-servers之间可以处于不同网段
VS/TUN的工作流程图:
在这里需要指出,根据缺省的TCP/IP协议栈处理,请求报文的目标地址为VIP,响应报文的源地址肯定也为VIP,所以响应报文不需要作任何修改,可以直接返回给客户,客户认为得到正常的服务,而不会知道究竟是哪一台服务器处理的。
3.VS/DR(Virtual Server via Direct Routing),即用直接路由技术实现虚拟服务器。跟前面两种方式,它的报文转发方法有所不同,VS/DR通过改写请求报文的MAC地址,将请求发送到Real Server,而Real Server将响应直接返回给客户,免去了VS/TUN中的IP隧道开销。这种方式是三种负载调度机制中性能最高最好的,但是必须要求Director Server与Real Server都有一块网卡连在同一物理网段上。
跟VS/TUN方法相同,VS/DR利用大多数Internet服务的非对称特点,负载调度器中只负责调度请求,而服务器直接将响应返回给客户,可以极大地提高整个集群系统的吞吐量。调度器和服务器组都必须在物理上有一个网卡通过不分断的局域网相连,如通过交换机或者高速的HUB相连。VIP地址为调度器和服务器组共享,调度器配置的 VIP地址是对外可见的,用于接收虚拟服务的请求报文; 所有的服务器(Real server)把VIP地址配置在各自的NonARP网络设备上,它对外面是不可见的,只是用于处理目标地址为VIP的网络请求。
VS/DR的工作流程:
在VS/DR中,根据缺省的TCP/IP协议栈处理,请求报文的目标地址为VIP,响应报文的源地址肯定也为VIP,所以响应报文不需要作任何修改,可以直接返回给客户,客户认为得到正常的服务,而不会知道是哪一台服务器处理的。
VS/DR负载调度器跟VS/TUN一样只处于从客户到服务器的半连接中,按照半连接的TCP有限状态机进行状态迁移
数据包、数据帧的大致流向是这样的:client --> VS --> RS --> client
一. 试验环境
采用VS/DR的工作方式
Load Balance:192.168.1.101
Virtual IP: 192.168.0.200
Gateway: 192.168.0.1.101
Realserver1: 192.168.1.103
Realserver1: 192.168.1.104
三台虚拟机之间采用的是桥接的方式进行连接。
我们用web服务来验证一个最基本的lvs,192.168.1.101主机做调度器,采用轮叫的调度算法,让两台realserver的web分别呈现不同的页面,用户输入Virtual IP的时候,则可以不停的刷新出两台realserver的页面,实现负载均衡。
二. 安装软件
安装ipvsadm,是基于内核安装的,要找到合适自己内核的ipvsadm,因为我自己的yum仓库本身意境有适合自己内核的ipvsadm了,所以我就直接安装。如果光盘自带没有的话,可以去http://www.linuxvirtualserver.org/software/ipvs.html#kernel-2.6 中去下载合适自己内核的,同时要注意因为是基于内核的,所以要确保所有主机内核是要一致的,内核不一致是做不出效果的。
[root@localhost yum.repos.d]# yum install ipvsadm –y
Installing : ipvsadm-1.25-9.el6.i686 1/1
Installed:
ipvsadm.i686 0:1.25-9.el6
Complete!
三. 配置详解
主控服务器配置
1、 主控服务器网络设置
[root@localhost yum]# ifconfig eth0:0 192.168.1.122 netmask 255.255.255.255 up
2、 清空配置目录
为了防止以前的配置干扰到我们的实验,所以我这里先对以前ipvsadm的配置进行清空,当然刚安装的是没必要进行此步骤的
[root@localhost yum.repos.d]# ipvsadm –C
3、 给主控服务器添加规则
★ [root@localhost ~]# ipvsadm -A -t 192.168.1.122:80 -s rr
-A --add-service 在内核的虚拟服务器表中添加一条新的虚拟服务器记录。也就是增加一台新的虚拟服务器。
-t --tcp-service service-address 说明虚拟服务器提供的是tcp 的服务[vip:port] or [real-server-ip:port]
-s –scheduler scheduler 使用的调度算法,有这样几个选项rr|wrr|lc|wlc|lblc|
lblcr|dh|sh|sed|nq,默认的调度算法是: wlc.
所以我本段的意思是添加一个虚拟服务器,地址为192.168.1.122,所提供的服务是80端口的服务,采用的算法是rr,轮叫的算法
[root@localhost ~]# ipvsadm –l //显示内核虚拟服务器表
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.1.122:http rr //瞧,意境显示这个虚拟服务器了,提供了http服务,采用的是轮叫的算法。
★[root@localhost ~]# ipvsadm -a -t 192.168.1.122:80 -r 192.168.1.103:80 -g
[root@localhost ~]# ipvsadm -a -t 192.168.1.122:80 -r 192.168.1.104:80 –g
-a --add-server 在内核虚拟服务器表的一条记录里添加一条新的真实服务器记录。也就是在一个虚拟服务器中增加一台新的真实服务器
-t --tcp-service service-address 说明虚拟服务器提供的是tcp 的服务[vip:port] or [real-server-ip:port]
-r --real-server server-address 真实的服务器[Real-Server:port]
-g --gatewaying 指定LVS 的工作模式为直接路由模式(也是LVS 默认的模式)
所以我本段的意思就是给虚拟服务器表里添加一个真实的服务器记录,采用直接路由的模式,虚拟服务器提供的服务是80端口的服务
[root@localhost ~]# ipvsadm -l
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.1.122:http rr
-> 192.168.1.103:http Route 1 0 0
-> 192.168.1.104:http Route 1 0 0
看到没,两个realserver已经加入到虚拟服务器的表中了,并且提供的服务是http服务
4、 保存ipvsadm配置
前面意境配置好了ipvsadm,如果我们没有保存就开启此服务,会有如下报错:
但是如果我们保存了后,就不会报错
[root@localhost yum]# /etc/init.d/ipvsadm save
Saving IPVS table to /etc/sysconfig/ipvsadm: [ OK ]
[root@localhost yum]# /etc/init.d/ipvsadm start
Clearing the current IPVS table: [ OK ]
Applying IPVS configuration: [ OK ]
ipvsadm的配置这个时候已经保存在/etc/sysconfig/ipvsadm文件下了。
[root@localhost yum]# cat /etc/sysconfig/ipvsadm
-A -t 192.168.1.122:80 -s rr
-a -t 192.168.1.122:80 -r 192.168.1.104:80 -g -w 1
-a -t 192.168.1.122:80 -r 192.168.1.103:80 -g -w 1
real server配置
1、 给两台real server 添加虚拟地址
这是因为,当LVS把client的包转发给Real-server时,因为包的目的IP地址是VIP,那么如果Real-server收到这个包后,发现包的目的IP不是自己的系统IP,那么就会认为这个包不是发给自己的,就会丢弃这个包,所以需要将这个IP地址绑到网卡上;当发送应答包给client 时,Real-server就会把包的源和目的地址调换,直接回复给client。
另外绑定VIP的掩码是”255.255.255.255″,说明广播地址是其本身,那么他就不会将ARP发送到实际的自己该属于的广播域了,这样防止与LVS上VIP冲突,而导致IP冲突
[root@client103 ~]# ifconfig lo:0 192.168.1.122 netmask 255.255.255.255 up
[root@client104 ~]# ifconfig lo:0 192.168.1.122 netmask 255.255.255.255 up
[root@client103 home]# route add -host 192.168.1.122 dev lo:0
[root@client103 home]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.1.122 0.0.0.0 255.255.255.255 UH 0 0 0 eth0
192.168.1.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
169.254.0.0 0.0.0.0 255.255.0.0 U 0 0 0 eth0
0.0.0.0 192.168.1.100 0.0.0.0 UG 0 0 0 eth0
这里需要注意:realserver必须要在lo上设置VIP,不能在出口网卡上设置VIP,这是因为,要让RS能够处理目标地址为VIP的ip包,首先必须要让RS能够收到这个包,而在lo上设置vip是能够完成接受包,并且返回给客户端的。但是如果我是设置在出口网卡上,则会影响客户端的arp request,以至于整个load balance都不能正常工作。
我一开始就是在eth0上设置了VIP,结果刷新页面的时候,总是无法实现交替,查看了半天配置都没问题,一下子纠结了快两周。。。悲催死了。(自己实在太拘泥细节了,这样太耗费时间。。。)不过这里我还是有些疑问的,等以后有时间了,在慢慢研究
2、关闭arp响应
在很多情形下realserver有网口连接到load balancer请求进入网口所连接的交换机,
VIP地址在LVS/DR和LVS/TUN集群中为load balancer和所有realserver共享的。
若有ARP请求询问VIP地址,load balancer和其他real server都作响应,就会乱套了,所以要关闭。
如果Real-server有个多个网卡,每个网卡在不同的网段,那么可以过滤掉非本网卡ARP请求的回应;但是如果多个网卡的ip在一个网段,那么就不行了,比如本例就不行~
[root@client103 home]# vim /etc/sysctl.conf
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
[root@client103 home]# sysctl –p //让更改的配置立即生效
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 4294967295
kernel.shmall = 268435456
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
其实对lo的可以不用,因为arp对逻辑接口没有意义,但如果如果你的RS的外部网络接口是eth0,那么下面的两个则是必须的。
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
当然,也可以写成:
net.ipv4.conf.eth0.arp_announce = 2
net.ipv4.conf.eth0.arp_ignore = 1
---------------------------------------------------------------------------------------
另外一个realserver端配置和此一模一样。到这里基本的配置就已经完成了,我们启动两个real server 的http服务后,在用户端的web页面上输入192.168.1.122页面后,就可以看到两台real server 提供服务的轮叫。
Ok,到这里我们用ipvsadm进行配置就已经都ok了,现在我们对两台realserver开启web服务,通过在客户端刷新192.168.1.122这个网址,就可以实现不同页面的轮回,以实现负载均衡。
图上画圈的说明我再刷新页面的时候,已经实现了轮回
名词解释:
arp_ignore:
定义对目标地址为本地IP的ARP询问不同的应答模式0
0 - (默认值): 回应任何网络接口上对任何本地IP地址的arp查询请求
1 - 只回答目标IP地址是来访网络接口本地地址的ARP查询请求
2 -只回答目标IP地址是来访网络接口本地地址的ARP查询请求,且来访IP必须在该网络接口的子网段内
3 - 不回应该网络界面的arp请求,而只对设置的唯一和连接地址做出回应
4-7 - 保留未使用
8 -不回应所有(本地地址)的arp查询
arp_announce - INTEGER
对网络接口上,本地IP地址的发出的,ARP回应,作出相应级别的限制:
确定不同程度的限制,宣布对来自本地源IP地址发出Arp请求的接口
0 - (默认) 在任意网络接口(eth0,eth1,lo)上的任何本地地址
1 -尽量避免不在该网络接口子网段的本地地址做出arp回应. 当发起ARP请求的源IP地址是被设置应该经由路由达到此网络接口的时候很有用.此时会检查来访IP是否为所有接口上的子网段内ip之一.如果改来访IP不属于各个网络接口上的子网段内,那么将采用级别2的方式来进行处理.
2 - 对查询目标使用最适当的本地地址.在此模式下将忽略这个IP数据包的源地址并尝试选择与能与该地址通信的本地地址.首要是选择所有的网络接口的子网中外出访问子网中包含该目标IP地址的本地地址. 如果没有合适的地址被发现,将选择当前的发送网络接口或其他的有可能接受到该ARP回应的网络接口来进行发送.
限制了使用本地的vip地址作为优先的网络接口
补充:下面的这个我实验的时候是没有添加的,只不过查找到相关资料是有建议这么做,但具体的意义,我还没有理解,这里只是做个补充的介绍
您现在已经配置了每个控制器,可以处理引入的对浮动服务 IP 的 Web 和 SSL 请求,方法是重写这些请求并连续地将工作传递给 realserver。但是为了从 realserver 收回通信量,并且为了在将请求返回给发出请求的客户机之前执行相反的过程,您需要对控制器更改几个连网设置。其原因是需要在平面网络拓扑结构中实现 LVS 控制器和 realserver(即,同一子网上的所有组件)。我们需要执行以下步骤以强制 Apache 通过控制器返回响应通信量,而不是自己直接应答:
echo "0" > /proc/sys/net/ipv4/conf/all/send_redirects
echo "0" > /proc/sys/net/ipv4/conf/default/send_redirects
echo "0" > /proc/sys/net/ipv4/conf/eth0/send_redirects
执行此操作的目的是为了防止活动的 LVS 控制器通知 realserver 和浮动服务 IP 直接相互通信,从而获取 TCP/IP 捷径(因为它们位于同一个子网中)。一般情况下,重定向是有用的,因为它们通过清除网络连接中不必要的中间件提高了性能。但是此时,它可能阻碍了响应通信量的重写,而这又是对客户机透明所必需的。实际上,如果在 LVS 控制器上没有禁用重定向,那么从 realserver 直接发往客户机的通信量将被客户机视为未被请求的网络响应而被丢弃。