lvs+keepalived集群架构服务

LVS(linux virtual server)介绍

lvs是linux virtual server的简写(也叫做IPVS),意思是即linux虚拟服务器,是一个虚拟机的服务器集群系统,可以在UNIX/LINUX平台下实现负载均衡集群功能。

企业网站LVS集群架构图lvs+keepalived集群架构服务_第1张图片

用户的请求直接DNET过来,过来有可能是个网关,然后tcp三次握手和lvs负载均衡获取,通过lvs转发数据包到达内网,然后,然后后面的内网是同一网段的,如果没有外网的话我们可以通过http协议通过监控到内网,也可以进行绑定网关地址到dns服务器上。

IPVS软件工作层次图

lvs+keepalived集群架构服务_第2张图片

从上图我们看出,LVS负载均衡调度技术是在Linux内核中实现的,因此,被称之为Linux虚拟服务器(Linux Virtual Server)。我们使用该软件配置LVS时候,不能直接配置内核中的ipbs,而需要使用ipvs管理工具ipvsadm间接进行控制内核层,或者通过Keepalived软件直接管理ipvs。

LVS体系结构与工作原理简单描述

LVS集群负载均衡器接受服务的所有入站客户端计算机请求,并根据调度算法决定哪个集群节点应该处理回复请求。负载均衡器(简称LB)有时也被称为LVS Director(简称Director)。
LVS虚拟服务器的体系结构如下图所示,一组服务器通过高速的局域网或者地理分布的广域网相互连接,在他们的前端有一个负载调度器(Load Balancer)。 负载调度器能无缝地将网络请求调度到真实服务器上,从而使得服务器集群的结构对客户是透明的,客户访问集群系统提供的网络服务就像访问一台高性能,高可用的服务器一样。客户程序不受服务器集群的影响不需要作任何修改。系统的伸缩性通过在服务集群中透明地加入和删除一个节点来达到,通过检测节点或服务进程故障和正确地重置系统达到高可用性。由于我们的负载调度技术是在Linux内核中实现的,我们称之为Linux虚拟服务器(Linux Virtual Server)。

lvs+keepalived集群架构服务_第3张图片

lvs+keepalived集群架构服务_第4张图片

LVS集群内部的节点称为真实服务器(Real Server),也叫做集群节点。请求集群服务的计算机称为客户端计算机。
与计算机通常在网上交换数据包的方式相同,客户端计算机,Director和真实服务器使用IP地址彼此进行通信。
不同架构角色命名情况如下图:

lvs+keepalived集群架构服务_第5张图片
LVS后方的服务器叫做RealServer(真实服务器),用户的访问的ip地址,都是LVS的也就是VIP,可以真正给用户提供服务的是RealSever,后方的服务器,用户不知道是那个服务器提供服务的,前方是假的。

LVS的四种工作模式

NAT(Network Address Translation)
TUN(Tunneling)
DR(Direct Routing) (最重要的)
FULLNAT(Full Network Address Translation)

DR的工作原理

lvs+keepalived集群架构服务_第6张图片

1:通过在调度器LB上修改数据包的目的MAC地址实现转发。(源IP地址仍然是CIP,目的IP地址仍然是VIP)
2:请求的报文经过调度器,而RS响应处理后的报文无需经过调度器LB,因此,并发访问量大时使用效率很高(和NAT模式相比)
3:因DR模式是通过MAC地址的改写机制实现的转发,因此,所有RS节点和调度器LB只能在一个局域网LAN中(缺点)
4:RS节点的默认网关不需要是调度器LB的DIP,而直接是IDC机房分配的上级路由器的IP(这是RS带有外网IP地址的情况),理论讲:只要RS可以出网即可,不是必须要配置外网IP
5:由于DR模式的调度器仅进行了目的MAC地址的改写,因此,调度器LB无法改变请求的报文的目的端口(缺点)
6:当前,调度器LB支持几乎所有的UNIX,LINUX系统,但目前不支持WINDOWS系统。真实服务器RS节点可以是WINDOWS系统。
7:总的来说DR模式效率很高,但是配置也较麻烦,因此,访问量不是特别大的公司可以用haproxy/nginx取代之。这符合运维的原则:简单,易用,高效。日2000W PV或并发请求1万以下都可以考虑用haproxy/nginx(LVS NAT模式)
8:直接对外的访问业务,例如:Web服务做RS节点,RS最好用公网IP地址。如果不直接对外的业务,例如:MySQl,存储系统RS节点,最好只用内部IP地址。

1:用户输入域名地址,通过dns服务器解析出了网关的公网ip---->GIP 2:此时他的源ip是:CIP 目标ip:GIP
3,想让用户访问到内网,此时在网关这里做了个DNAT目标地址转换 4:源地址CIP,目标地址:VIP,被DNAT到
5:假如负载均衡给了WEB1(RIP1)
6,LVS的vip,和客户端ip地址,是同一个网段,所以同网段数据传输依靠的是MAC地址转换,因此网关先要就行arp协议获取LVS的MAC地址,所以是MAC地址转发数据包,源MAC地址:GMAC
,目标MAC地址:VMAC, 通过负载均衡给了web节点1。 7:把数据包发给同网段的电脑。是不用修改ip地址的,修改mac地址就行
9:此时CIP:VIP,GMAC:RMAC,然后数据包就可以转发了。
10,LVS也需要获取后方RS的MAC地址才能修改目标MAC,把数据发送过去
11:ARP协议是已知VIP获取的MAC地址,LVS是已知RIP获取的MAC地址,无论是web1,2,3。。。都不会冲突
12:然后LVS回复一个响应包,然后连接过来
,假如期中一个web端,收到数据包之后,发现目标ip是找VIP的,VIP没了,自己是RIP,不是自己的会丢弃数据包,这样必须要让后方的server知道VIP就是RIP。
第一步:绑定VIP地址,但是一但绑了VIP,LVS发给后方的server,刚才说过了要想网关地址要转发数据包,必须要在同一网段内,要先发送arp协议是已知VIP,获取对方的MAC地址,只绑定了一个VIP的话,会有多个VIP发送响应包,server里每一个都VIP,都要响应了。

第二步;需要 抑制VIP这个地址的ARP响应,在server上不在针对VIP发送的响应包,不能限制RIP的,绑定VIP的时候并不是绑定是eth0上的,还是绑定在环回网卡上的,这样就能知道数据包是自己的了。

13;此时web上的RIP就知道数据包是自己的了,然后将内容UZIP打包,发送给客户端,源地址是:VIP 目标地址:CIP

TUN模式

lvs+keepalived集群架构服务_第7张图片

1::负载均衡器通过把请求的报文通过IP隧道的方式转发至真实服务器,而真实服务器将响应处理后直接返回给客户端用户。
2:由于真实服务器将响应处理后的报文直接返回给客户端用户,因此,最好RS有一个外网IP地址,这样效率才会更高。理论上:只要能出网即可,无需外网IP地址。
3:由于调度器LB只处理入站请求的报文。因此,此集群系统的吞吐量可以提高10倍以上,但隧道模式也会带来一定得系统开销。TUN模式适合LAN/WAN。
4:TUN模式的LAN环境转发不如DR模式效率高,而且还要考虑系统对IP隧道的支持问题。
5:所有的RS服务器都要绑定VIP,抑制ARP,配置复杂。
6:LAN环境一般多采用DR模式,WAN环境可以用TUN模式,但是当前在WAN环境下,请求转发更多的被haproxy/nginx/DNS调度等代理取代。因此,TUN模式在国内公司实际应用的已经很少。跨机房应用要么拉光纤成局域网,要么DNS调度,底层数据还得同步。
7:直接对外的访问业务,例如:Web服务做RS节点,最好用公网IP地址。不直接对外的业务,例如:MySQL,存储系统RS节点,最好用内部IP地址。

1:TUN模式与DR模式的唯一区别是:不在通过修改MAC地址,来吧数据包发给后方的真实节点,修改MAC必须要在同一网段内,后方的节点可以和LVS不在同一网段内,可以实现跨网段的,甚至可以跨机房。
2: 那么TUN模式通过ip隧道技术在ip头部的前面又封装了一个ip头,目标头部就变成了RIP了,CIP:RIP
把里面得到包起来了(里面还是CIP:VIP),那么通过RIP发现是跨网段用从网关出去了,然后真实节点可以在另一个机房了,通过Internet到另一个机房,把外面内层去了,然后在人为VIP是自己,目标是用户

NAT模式

lvs+keepalived集群架构服务_第8张图片

1:NAT技术将请求的报文(DNAT)和响应的报文(SNAT),通过调度器地址重写然后在转发发给内部的服务器,报文返回时在改写成原来的用户请求的地址。
2:只需要在调度器LB上配置WAN公网IP即可,调度器也要有私有LAN IP和内部RS节点通信。
3:每台内部RS节点的网关地址,必须要配成调度器LB的私有LAN内物理网卡地址(LDIP),这样才能确保数据报文返回时仍然经过调度器LB。
4:由于请求与响应的数据报文都经过调度器LB,因此,网站访问量大时调度器LB有较大瓶颈,一般要求最多10-20台节点。
5:NAT模式支持对IP及端口的转换,即用户请求10.0.0.1:80,可以通过调度器转换到RS节点的10.0.0.2:8080(DR和TUN模式不具备的)
6:所有NAT内部RS节点只需要配置私有LAN IP即可。
7:由于数据包来回都需要经过调度器,因此,要开启内核转发net.ipv4.ip_forward=1,当然也包括iptables防火墙的forward功能(DR和TUN模式不需要)。

用户发送的请求到了LVS的时候,LVS做一个DNAT数据转发到其中一个节点上,然后回来的时候做一个SNAT会到用户了

FULLNAT

lvs+keepalived集群架构服务_第9张图片

lvs+keepalived集群架构服务_第10张图片

lvs+keepalived集群架构服务_第11张图片

专门有一个NAT-session表,放在其中一个服务器中,每次负载的时候,由session统一给源地址是谁,实现横向的LVS的负载均衡
FULLANT特点
1,源IP改成不同的VIP和目的IP改成RIP
2,RS处理完毕返回时,返回给不同的LVS调度器
3,所有LVS调度器之间通过session表进行Client Address的共享

FULLNAT全地址转换,去的时候DNAT和SNAT一起做,用户的请求到LVS目标SNAT+DNAT,源地址进行修改了,把另一个LVS当做源了,中间有个服务器计算改那个,着个模式只有淘宝用

LVS的调度算法(上面一直说的是模式)

  • LVS的调度算法决定了如何在集群节点之间分布工作负荷。
  • 当Director调度器收到来自客户端计算机访问它的VIP上的集群服务的入站请求时,Director调度器必须决定哪个集群节点应该处理请求。Director调度器可用于做出该决定的调度方法分成两个基本类别:
    固定调度方法:rr,wrr,dh,sh
    动态调度算法:wlc,lc,lblc,lblcr,SED,NQ

算法------>如何计算LVS把请求给那个RS节点:相当于负载给那个节点

lvs+keepalived集群架构服务_第12张图片

LVS的调度算法的生产环境选型

==一般的网络服务,如Http,Mail,MySQL等,常用的LVS调度算法为: ==

  • 基本轮叫调度rr算法
  • 加权最小连接调度wlc
  • 加权轮叫调度wrr算法

基于局部性的最少链接LBLC和带复制的基于局部性最少链接LBLCR主要适用于Web Cache和Db Cache集群,但是我们很少这样用。(都是一致性哈希算法)
源地址散列调度SH和目标地址散列调度DH可以结合使用在防火墙集群中,它们可以保证整个系统的唯一出入口。
:最短预期延时调度SED和不排队调度NQ主要是对处理时间相对比较长的网络服务。

实际使用中,这些算法的适用范围不限于这些。我们最好参考内核中的连接调度算法的实现原理,根据具体业务需求合理的选型。

LVS集群的特点:

(1)功能
实现三种IP负载均衡技术和10种连接调度算法的IPVS软件。在IPVS内部实现上,采用了高效的Hash函数和垃圾回收机制,能正确处理所调度报文相关的ICMP消息(有些商品化的系统反而不能)。虚拟服务的设置数目没有限制,每个虚拟服务都有自己的服务器集。它支持持久的虚拟服务(如HTTP Cookie 和HTTPS等需要该功能的支持),并提供详尽的统计数据,如连接的处理速率和报文的流量等。针对大规模拒绝服务(Deny of service)攻击,实现了三种防卫策略:有基于内容请求分发的应用层交换软件KTCPVS,它也是在Linux内核中实现。有相关的集群管理软件对资源进行检测,能及时将故障屏蔽,实现系统的高可用性。主,从调度器能周期性地进行状态同步,从而实现更高的可用性。
(2)使用性
1)后端真实服务器可运行任何支持TCP/IP的操作系统,包括Linux,各种Unix(如FreeBSD,Sun Solaris,HP Unix等),Mac/OS和windows NT/2000等。

2)负载均衡调度器LB能够支持绝大多数的TCP和UDP协议:
lvs+keepalived集群架构服务_第13张图片

无需对客户机和服务作任何修改,可使用大多数internet服务

3)调度器本身当前不支持windows系统。支持大多数的Linux和UINIX系统。

(3)性能

LVS服务器集群系统具有良好的伸缩性,可支持几百万个并发连接。配置100M网卡,采用VS/TUN或VS/DR调度技术,集群系统的吞吐量可高达1Gbits/s;如配置千兆网卡,则系统的最大吞吐量可接近10Gbits/s

(4)可靠性

LVS服务器集群软件已经在很多大型的,关键性的站点得到很好的应用,所以它的可靠性在真实应用得到很好的证实。

(5)软件许可证

LVS集群软件是按GPL(GNU Public License)许可证发行的自由软件,这意味着你可以得到软件的源代码,有权对其进行修改,但必须保证你的修改也是以GPL方式发行。

标题 地址
LVS项目介绍 http://www.linuxvirtualserver.org/zh/lvs1.html
LVS集群的体系结构 http://www.linuxvirtualserver.org/zh/lvs2.html
LVS集群中的ip负载均衡技术 http://www.linuxvirtualserver.org/zh/lvs3.html
LVS集群的负载调度 http://www.linuxvirtualserver.org/zh/lvs4.html

lvs+keepalived集群架构服务_第14张图片

手动实现LVS的负载均衡功能(DR模式)

IP地址 角色 备注
192.168.182.160 LVS调度器(Director) 对外提供服务的VIP为192.168.182.240
192.168.182.161 RS1(真实服务器)
192.168.182.162 RS2(真实服务器)
192.168.182.164 客户端

提前做好两台web

[root@localhost ~]# yum install -y kernel-devel			#光盘安装
[root@localhost ipvsadm-1.26]# ls -d /usr/src/kernels/2.6.32-431.el6.x86_64/			#安装完就会有这个目录
/usr/src/kernels/2.6.32-431.el6.x86_64/

[root@localhost ~]# ln -s /usr/src/kernels/2.6.32-431.el6.x86_64/ /usr/src/linux		#安装完就会有前面的目录,然后给做个软连接
[root@localhost ~]# ll -d /usr/src/linux/
drwxr-xr-x 22 root root 4096 Jan  3 08:41 /usr/src/linux/
[root@localhost ~]# ll /usr/src/
total 8
drwxr-xr-x. 2 root root 4096 Sep 23  2011 debug
drwxr-xr-x. 3 root root 4096 Jan  3 08:41 kernels
lrwxrwxrwx  1 root root   39 Jan  3 08:45 linux -> /usr/src/kernels/2.6.32-431.el6.x86_64/

特别注意:
此ln命令的链接路径要和uname -r输出结果内核版本对应,工作中如果做安装虚拟化可能有多个内核路径
如果没有/usr/src/kernels/2.6.32-431.el6.x86_64/路径,很可能是因为缺少kernel-devel软件包。可通过yum进行安装centos5.x版本不能用ipvs1.26

安装lvs命令:

###定制化yum安装lvs
[root@localhost rpm]# yum install createrepo
[root@localhost rpm]# cd rpm/
[root@localhost rpm]# createrepo -v .				#最好是做完定制化yum在进行索引
[root@localhost rpm]# ls
libnl-1.1.4-2.el6.x86_64.rpm          libnl-devel-1.1.4-2.el6.x86_64.rpm
libnl3-3.2.21-8.el6.x86_64.rpm        popt-devel-1.13-7.el6.x86_64.rpm
libnl3-cli-3.2.21-8.el6.x86_64.rpm    popt-static-1.13-7.el6.x86_64.rpm
libnl3-devel-3.2.21-8.el6.x86_64.rpm  repodata
libnl3-doc-3.2.21-8.el6.x86_64.rpm
[root@localhost yum.repos.d]# tail -5 CentOS-Media.repo 
[rpm]
name=rpm
baseurl=file:///root/rpm/
gpgcheck=0
enabled=1
[root@localhost yum.repos.d]# yum -y clean all
[root@localhost yum.repos.d]# yum makecache
[root@localhost rpm]# yum -y install libnl* popt*			#进行安装lvs
[root@localhost ~]# tar xf ipvsadm-1.26.tar.gz -C /usr/src/
[root@localhost ~]# cd /usr/src/ipvsadm-1.26/
[root@localhost ipvsadm-1.26]# make			#直接编译不需要./configure
[root@localhost ipvsadm-1.26]# make install
[root@localhost ipvsadm-1.26]# which ipvsadm
/sbin/ipvsadm

[root@localhost ipvsadm-1.26]# ipvsadm
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn

[root@localhost ipvsadm-1.26]# lsmod | grep ip_vs			#执行完ipvsadm就会有信息了
ip_vs                 125220  0 
libcrc32c               1246  1 ip_vs
ipv6                  317340  270 ip_vs,ip6t_REJECT,nf_conntrack_ipv6,nf_defrag_ipv6
#出现这个信息,就代表着LVS已经安装好了,并加载到了内核

LVS安装小结:
1,CentOS5.X安装lvs,使用1.24版本。
2,CentOS6.X安装lvs,使用1.26版本。
3,安装lvs后,要执行ipvsadm把ip_vs模块加载到内核。

手动配置LVS负载均衡服务

(1)配置LVS的虚拟ip地址(VIP)

[root@localhost ipvsadm-1.26]# ifconfig eth0:0 192.168.182.240 broadcast 192.168.182.240 netmask 255.255.255.0 up		#虚拟vip地址,这个ip地址,必须要和你本机地址在同一个网段
[root@localhost ipvsadm-1.26]# ifconfig eth0:0
eth0:0    Link encap:Ethernet  HWaddr 00:0C:29:84:C4:87  
          inet addr:192.168.182.240  Bcast:192.168.182.140  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          Interrupt:19 Base address:0x2000 

(2)手工执行配置添加LVS服务并增加两台RS节点

[root@localhost ipvsadm-1.26]# ipvsadm -C		#清空ipvs历史设置数据
[root@localhost ipvsadm-1.26]# ipvsadm --set 30 5 60		#设置超时时间(tcp tcpfin udp),这里可以不用写遇到了问题就会知道了,这个是连接保持的时间
[root@localhost ipvsadm-1.26]# ipvsadm -A -t 192.168.182.240:80 -s rr 			#意思是添加路由主机的vip地址的80端口 指定了lvs的负载均衡算法rr算法
#说明
-A:添加一个虚拟路由主机(LB)
-t:指定虚拟路由主机的VIP地址和监听端口
-s:指定负载均衡算法
-p:指定会话保持时间

[root@localhost ipvsadm-1.26]# ipvsadm -a -t 192.168.182.240:80 -r 192.168.182.161:80 -g -w 1		
[root@localhost ipvsadm-1.26]# ipvsadm -a -t 192.168.182.240:80 -r 192.168.182.162:80 -g -w 1
#说明:
-a:添加RS节点
-t:指定虚拟路由主机的VIP地址和监听端口
-r:指定RS节点的RIP地址和监听端口
-g:指定DR模式
-w:指定权值

(3)lvs的配置结果

[root@localhost ipvsadm-1.26]# ipvsadm
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn	##下面俩个是lvs的后方节点
TCP  192.168.182.240:http rr			
  -> 192.168.182.161:http         Route   1      0          0         
  -> 192.168.182.162:http         Route   1      0          0     

此时,可以打开浏览器访问http://192.168.0.240体验结果,如果没意外,是无法访问的。(RS将包丢弃了),是应为用户发过来的请求,通过lvs转发,但是不知道要那个所以找不到了。

手工在RS绑定ip地址或者MAC地址

#在RS01
[root@RS01 ~]# ifconfig lo:0 192.168.182.240/32 up			#给自己用的,所以必须要设置为32掩码
Last login: Thu Jan  3 08:28:58 2019 from 192.168.182.1
[root@RS01 ~]# ifconfig lo:0 
lo:0      Link encap:Local Loopback  
          inet addr:192.168.0.240  Mask:0.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
在RS02          
[root@RS02 ~]# ifconfig lo:0 192.168.182.240/32 up         	#必须设置为32位掩码
[root@RS02 ~]# ifconfig lo:0
lo:0      Link encap:Local Loopback  
          inet addr:192.168.0.240  Mask:0.0.0.0
          UP LOOPBACK RUNNING  MTU:16436  Metric:1

注意:
在测试时候你会发现刷新看的都是同一个RS节点
这是因为浏览器的缓存问题
等一段时间以后,刷新就会重新负载均衡到新RS节点了,应为这里如果设置tcp连接保持的话,就得等待了

关于DR模式RS节点的ARP抑制的问题

  • 因为在DR模式下,RS节点和LVS同处一个局域网网段内。
  • 当网关通过ARP广播试图获取VIP的MAC地址的时候
  • LVS和节点都会接收到ARP广播并且LVS和节点都绑定了192.168.0.240这个VIP,所以都会去响应网关的这个广播,导致冲突现象。
  • 因此,我们需要对RS节点做抑制ARP广播的措施。
[root@RS02 html]# echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@RS02 html]# echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@RS02 html]# echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce 
[root@RS02 html]# echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce 

#测试
[root@localhost ~]# curl 192.168.182.240
192.168.182.161 welcoame
[root@localhost ~]# curl 192.168.182.240
192.168.182.162 welcoame

lvs+keepalived集群架构服务_第15张图片

内部ip(eth0) 外部ip(eth1) 角色 备注
192.168.182.160 LVS负载均衡器 VIP:192.168.182.240,网关:192.168.182.250
192.168.182.161 web01节点 网关:192.168.182.250
192.168.182.162 web02节点 网关:192.168.182.250
192.168.192.129 外网客户端 不配网关
192.168.182.250 192.168.192.128 网关型防火墙 双网卡均无网关

配置网关

#刷新,前者是开启转发原理
[root@localhost ~]# iptables -t nat -A PREROUTING -i eth1 -d 192.168.192.128 -p tcp --dport 80 -j DNAT --to-destination 192.168.182.240:80

[root@localhost ~]# vim /etc/sysctl.conf 

# Kernel sysctl configuration file for Red Hat Linux
#
# For binary values, 0 is disabled, 1 is enabled.  See sysctl(8) and
# sysctl.conf(5) for more details.

# Controls IP packet forwarding
net.ipv4.ip_forward = 1		#这里进行修改成1

[root@localhost network-scripts]# sysctl -p
net.ipv4.ip_forward = 1
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
error: "net.bridge.bridge-nf-call-ip6tables" is an unknown key
error: "net.bridge.bridge-nf-call-iptables" is an unknown key
error: "net.bridge.bridge-nf-call-arptables" is an unknown key
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
#外网进行映射ip地址
[root@localhost ~]# tail -1 /etc/hosts
192.168.192.128 www.yunjisuan.com			#ip地址是网关的外网的网卡地址

arp抑制技术参数说明

arp_ignore-INTRGER
定义对目标地址为本地IP的ARP询问不同的应答模式
o 0(默认值):回应任何网络接口上对任何本地IP地址的arp查询请求。
o 1:只回答目标IP地址是来访网络接口本地地址的ARP查询请求
o 2:只回答目标IP地址是来访网络接口本地地址的ARP查询请求,且来访IP必须在该网络接口的子网段内。
o 3:不回应该网络界面的arp请求,而只对设置的唯一和连接地址做出回应。
o 4-7:保留未使用
o 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地址作为优先的网络接口。

开发脚本配置LVS负载均衡器端

LVS负载均衡器端自动配置脚本:

[root@lvs01 scripts]# cat ipvs_server.sh 
#!/bin/bash
#LVS scripts
. /etc/init.d/functions
VIP=192.168.0.240
SUBNET="eth0:`echo $VIP | awk -F "." '{print $4}'`"
PORT=80
RIP=(
192.168.0.223
192.168.0.224
)
function start(){
    if [ `ifconfig | grep $VIP | wc -l` -ne 0 ];then
        stop
    fi
    ifconfig $SUBNET $VIP broadcast $VIP netmask 255.255.255.0 up
	ipvsadm -C
	ipvsadm --set 30 5 60
	ipvsadm -A -t $VIP:$PORT -s rr -p 20
	for ((i=0;i<${#RIP[*]};i++))
    do
        ipvsadm -a -t $VIP:$PORT -r ${RIP[$i]} -g -w 1
    done
}
function stop(){
    ipvsadm -C
    if [ `ifconfig | grep $VIP | wc -l` -ne 0 ];then
        ifconfig $SUBNET down
	fi
	route del -host $VIP dev eth0 &>/dev/null
}
case "$1" in 
	start)
		start
		echo "ipvs is started"
	;;
	stop)
		stop
		echo "ipvs is stopped"
	;;
	restart)
		stop
		echo "ipvs is stopped"
		start
		echo "ipvs is started"
	;;	
	*)
	echo "USAGE:$0 {start | stop | restart}"
esac

RS节点web服务器端自动配置脚本

[root@web01 scripts]# cat rs_server.sh 
#!/bin/bash
# RS_sever scripts
. /etc/rc.d/init.d/functions
VIP=192.168.0.240
case "$1" in 
	start)
		echo "start LVS of REALServer IP"
		interface="lo:`echo $VIP | awk -F "." '{print $4}'`"
		/sbin/ifconfig $interface $VIP broadcast $VIP netmask 255.255.255.255 up
        route add -host $VIP dev $interface
        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
    ;;
    stop)
        interface="lo:`echo $VIP | awk -F "." '{print $4}'`"
        /sbin/ifconfig $interface down
		echo "STOP LVS of REALServer IP"
		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 "Usage: $0 {start|stop}"
        exit 1
esac

企业LVS负载均衡高可用最优方案

lvs+keepalived集群架构服务_第16张图片

两台Web服务器安装Web服务

[root@lvs01 ~]# yum -y install keepalived

仅实现LVS负载均衡器主和备的keepalived高可用功能

LVS负载均衡器主的keepalived配置文件内容如下

[root@lvs01 ~]# sed -n '1,30p' /etc/keepalived/keepalived.conf 
! Configuration File for keepalived
global_defs {
   notification_email {
    [email protected]
   }
   notification_email_from yunjisuan
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS01
}
vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 55
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
    192.168.0.240/24 dev eth0 label eth0:240
    }
}

添加LVS的负载均衡规则

[root@localhost ~]# ipvsadm -C
[root@localhost ~]# ipvsadm -A -t 192.168.0.240:80 -s rr
[root@localhost ~]# ipvsadm -a -t 192.168.0.240:80 -r 192.168.0.223:80 -g -w 1
[root@localhost ~]# ipvsadm -a -t 192.168.0.240:80 -r 192.168.0.224:80 -g -w 1
[root@localhost ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.0.240:80 rr persistent 20
  -> 192.168.0.223:80             Route   1      0          0         
  -> 192.168.0.224:80             Route   1      0          0  

启动LVS主和备的keepalived服务

#在LVS主上
[root@lvs01 ~]# /etc/init.d/keepalived start
[root@lvs01 ~]# ifconfig 
eth0      Link encap:Ethernet  HWaddr 00:0C:29:D5:7F:9D  
          inet addr:192.168.0.210  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fed5:7f9d/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:23567 errors:0 dropped:0 overruns:0 frame:0
          TX packets:14635 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:2008524 (1.9 MiB)  TX bytes:1746298 (1.6 MiB)
eth0:240  Link encap:Ethernet  HWaddr 00:0C:29:D5:7F:9D  
          inet addr:192.168.0.240  Bcast:0.0.0.0  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
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:769 errors:0 dropped:0 overruns:0 frame:0
          TX packets:769 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:56636 (55.3 KiB)  TX bytes:56636 (55.3 KiB)
#在LVS副上
[root@localhost ~]# /etc/init.d/keepalived start
[root@localhost ~]# ifconfig
eth0      Link encap:Ethernet  HWaddr 00:0C:29:E7:06:1D  
          inet addr:192.168.0.211  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fee7:61d/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:14109 errors:0 dropped:0 overruns:0 frame:0
          TX packets:4902 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:12683754 (12.0 MiB)  TX bytes:553207 (540.2 KiB)
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:155 errors:0 dropped:0 overruns:0 frame:0
          TX packets:155 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:11283 (11.0 KiB)  TX bytes:11283 (11.0 KiB)
#如果LVS副上没有VIP就对了。如果主副都有,那么请检查防火墙是否开启状态

内网客户端进行访问测试

#在内网客户端上进行访问测试
[root@LanClient ~]# curl 192.168.0.240
192.168.0.224 bbs
[root@LanClient ~]# curl 192.168.0.240
192.168.0.223 bbs
[root@LanClient ~]# curl 192.168.0.240
192.168.0.224 bbs
[root@LanClient ~]# curl 192.168.0.240
192.168.0.223 bbs
[root@LanClient ~]# curl 192.168.0.240
192.168.0.224 bbs
[root@LanClient ~]# curl 192.168.0.240
192.168.0.223 bbs
[root@LanClient ~]# curl 192.168.0.240
192.168.0.224 bbs
#在LVS主上进行访问连接查询
[root@lvs01 ~]# ipvsadm -Lnc
IPVS connection entries
pro expire state       source             virtual            destination
TCP 00:01  FIN_WAIT    192.168.0.220:59887 192.168.0.240:80   192.168.0.223:80
TCP 00:01  FIN_WAIT    192.168.0.220:59889 192.168.0.240:80   192.168.0.223:80
TCP 00:01  FIN_WAIT    192.168.0.220:59888 192.168.0.240:80   192.168.0.224:80
TCP 00:00  FIN_WAIT    192.168.0.220:59886 192.168.0.240:80   192.168.0.224:80
#在LVS主上停掉keepalived服务
[root@lvs01 ~]# /etc/init.d/keepalived stop
Stopping keepalived:                                       [  OK  ]
[root@lvs01 ~]# ifconfig | grep eth0:240
#在LVS副上查看VIP
[root@localhost ~]# ip a | grep eth0:240
    inet 192.168.0.240/24 scope global secondary eth0:240
#再次在内网客户端上进行访问测试
[root@LanClient ~]# curl 192.168.0.240
192.168.0.223 bbs
[root@LanClient ~]# curl 192.168.0.240
192.168.0.224 bbs
[root@LanClient ~]# curl 192.168.0.240
192.168.0.223 bbs
[root@LanClient ~]# curl 192.168.0.240
192.168.0.224 bbs
[root@LanClient ~]# curl 192.168.0.240
192.168.0.223 bbs
#在LVS副上进行访问连接查询
[root@localhost ~]# ipvsadm -Lnc
IPVS connection entries
pro expire state       source             virtual            destination
TCP 01:47  FIN_WAIT    192.168.0.220:59900 192.168.0.240:80   192.168.0.223:80
TCP 01:09  FIN_WAIT    192.168.0.220:59891 192.168.0.240:80   192.168.0.224:80
TCP 01:48  FIN_WAIT    192.168.0.220:59902 192.168.0.240:80   192.168.0.223:80
TCP 01:09  FIN_WAIT    192.168.0.220:59892 192.168.0.240:80   192.168.0.224:80
TCP 01:14  FIN_WAIT    192.168.0.220:59896 192.168.0.240:80   192.168.0.224:80
TCP 01:10  FIN_WAIT    192.168.0.220:59894 192.168.0.240:80   192.168.0.224:80
#开启LVS主上的keepalived服务
[root@lvs01 ~]# /etc/init.d/keepalived start
[root@lvs01 ~]# ip a | grep eth0:240
    inet 192.168.0.240/24 scope global secondary eth0:240
#查看LVS副上VIP资源是否释放
[root@localhost ~]# ip a | grep eth0:240
[root@localhost ~]# 

通过keepalived对LVS进行管理的功能实现

[root@lvs01 ~]# cat /etc/keepalived/keepalived.conf 
! Configuration File for keepalived
global_defs {
   notification_email {
    [email protected]
   }
   notification_email_from yunjisuan
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS01
}
vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 55
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
    192.168.0.240/24 dev eth0 label eth0:240
    }
}
virtual_server 192.168.0.240 80 {       #虚拟主机VIP
    delay_loop 6            #
    lb_algo rr              #算法
    lb_kind DR              #模式
    nat_mask 255.255.255.0  #掩码
#    persistence_timeout 50 #会话保持
    protocol TCP            #协议
    real_server 192.168.0.223 80 {      #RS节点
        weight 1                #权重
        TCP_CHECK {             #节点健康检查
        connect_timeout 8       #延迟超时时间
        nb_get_retry 3          #重试次数
        delay_before_retry 3    #延迟重试次数
        connect_port 80         #利用80端口检查
    }
    }
    real_server 192.168.0.224 80 {      #RS节点
        weight 1
        TCP_CHECK {
        connect_timeout 8
        nb_get_retry 3
        delay_before_retry 3
        connect_port 80 
    }
    }
}

以上keepalived配置文件在LVS主和备上都进行修改。 然后在lvs服务器上通过ipvsadm -C清除之前设置的规则 重新启动keepalived服务进行测试,操作过程如下:

[root@lvs01 ~]# /etc/init.d/keepalived stop             #关闭主LVS的keepalived服务
Stopping keepalived:                                       [  OK  ]
[root@lvs01 ~]# ipvsadm -Ln                             #没有ipvs规则
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
[root@lvs01 ~]# ip a | grep 240                         #没有VIP
[root@lvs01 ~]# /etc/init.d/keepalived start            #启动keepalived服务
Starting keepalived:                                       [  OK  ]
[root@lvs01 ~]# ipvsadm -Ln                             #出现ipvs规则
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.0.240:80 rr
  -> 192.168.0.223:80             Route   1      0          0         
  -> 192.168.0.224:80             Route   1      0          0         
[root@lvs01 ~]# ip a | grep 240                         #出现VIP
    inet 192.168.0.240/24 scope global secondary eth0:240   

LVS集群分发请求RS不均衡生产环境实战解决

生产环境中ipvsadm -L -n 发现两台RS的负载不均衡,一台有很多请求,一台没有。并且没有请求的那台RS经测试服务正常,lo:VIP也有。但是就是没有请求。

IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.0.240:80 rr persistent 10
  -> 192.168.0.223:80             Route   1      0          0         
  -> 192.168.0.224:80             Route   1      8          12758         

问题原因:

persistent 10的原因,persistent会话保持,当clientA访问网站的时候,LVS把请求分发给了52,那么以后clientA再点击的其他操作其他请求,也会发送给52这台机器。

解决办法:

到keepalived中注释掉persistent 10 然后/etc/init.d/keepalived reload,然后可以看到以后负载均衡两边都均衡了。

其他导致负载不均衡的原因可能有:

1.LVS自身的会话保持参数设置(-p 300,persistent 300)。优化:大公司尽量用cookies替代session
2.LVS调度算法设置,例如:rr,wrr,wlc,lc算法
3.后端RS节点的会话保持参数,例如:apache的keepalive参数
4.访问量较少的情况,不均衡的现象更加明显
5.用户发送得请求时间长短,和请求资源多少大小。

lvs+keepalived集群架构服务_第17张图片
环境部署

ip 角色 备注
192.168.182.160 LVS负载均衡器(主) VIP:192.168.182.240
192.168.182.171 LVS负载均衡器器(备) VIP:192.168.182.250
192.168.182.166 nginx反向代理
192.168.182.161 web01(上传)
192.168.182.162 web02(静态)
192.168.182.170 web03(动态)
192.168.182.172 tomcat VIP:192.168.182.250
192.168.182.164 客户端

配置lvs中的keepalived的配置文件
(1)keepalived的主配置文件

[root@localhost ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
   notification_email {
     [email protected]
     [email protected]
     [email protected]
   }
   notification_email_from [email protected]
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id lv01
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 150					
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
	192.168.182.240/24 dev eth0 label eth0:0    	#VIP的地址
}
}

vrrp_instance VI_2 {
    state BACKUP
    interface eth0
    virtual_router_id 52
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
	192.168.182.250/24 dev eth0 label eth0:1    
}

(2)keepalived备的配置文件

[root@localhost ~]# vim /etc/keepalived/keepalived.conf 

   notification_email_from [email protected]
   smtp_server 192.168.200.1
   smtp_connect_timeout 30
   router_id lv02
}

vrrp_instance VI_1 {
    state BACKUP
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.182.240/24 dev eth0 label eth0:0			#主的keepalived的VIP地址变为备了
}
}

vrrp_instance VI_2 {
    state MASTER
    interface eth0
    virtual_router_id 52
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.182.250/24 dev eth0 label eth0:1				#主的备的VIP地址变为主
}

启动keepalived

[root@localhost ~]# ifconfig
eth0:0    Link encap:Ethernet  HWaddr 00:0C:29:84:C4:87  
          inet addr:192.168.182.240  Bcast:0.0.0.0  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          Interrupt:19 Base address:0x2000 

eth0:1    Link encap:Ethernet  HWaddr 00:0C:29:84:C4:87  
          inet addr:192.168.182.250  Bcast:0.0.0.0  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          Interrupt:19 Base address:0x2000 

环境部署,一台nginx反向代理,三台nginx节点服务器

#一键部署nginx的脚本
[root@www ~]# cat nginx.sh 
#!/bin/bash
mkdir -p /media/cdrom
umount /dev/sr0 &>/dev/null
mount /dev/sr0 /media/cdrom &>/dev/null
dir=/etc/yum.repos.d
[ -d $dir ] || mkdir -p $dir
cd $dir
mv * /tmp/
cat >/etc/yum.repos.d/local.repo << KOF
[local]
name=localrepo
baseurl=file:///media/cdrom/
gpgcheck=0
enabled=1
KOF
/usr/bin/yum -y clean all &>/dev/null
/usr/bin/yum makecache &>/dev/null
[ $? -eq 0 ] || (/bin/echo "yun缓存错误" && exit)
/usr/bin/yum -y install pcre-deved openssl-devel &>/dev/null
[ $? -eq 0 ] || /bin/echo "安装失败"
yum -y install gcc gcc-c++ make pcre pcre-devel zlib zlib-devel openssl  openssl-devel &>/dev/null
[ $? -eq 0 ] || /bin/echo "安装失败"
cd ~
tar xf nginx-1.10.2.tar.gz -C /usr/src/
cd /usr/src/nginx-1.10.2/
useradd -M -s /sbin/nologin www 
./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module && make && make install  &> /dev/null
[root@www conf]# egrep -v "#|^$" nginx.conf.default > nginx.conf

#修改nginx的配置文件
[root@www conf]# cat nginx.conf
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
	upstream upload_pools {
	server 192.168.182.161:80 weight=1;
	}
	upstream static_pools {
	server 192.168.182.162:80 weight=1;
	}
	upstream dt_pools {
	server 192.168.182.170:80 weight=1;
	}
    server {
        listen       80;
        server_name  www.yunjisuan.com;
        location /upload/ {
	proxy_pass http://upload_pools;
	include proxy.conf;        
	}
	location /static/ {
	proxy_pass http://static_pools;
	include proxy.conf;
	}
	location /dt/ {
	proxy_pass http://dt_pools;
	include proxy.conf;
        }
    }
}
[root@www conf]# ln -s /usr/local/nginx/sbin/* /usr/bin/			#做一个软连接
[root@www conf]# nginx
[root@www conf]# ss -antup | grep 80
tcp    LISTEN     0      128                    *:80                    *:*      users:(("nginx",1191,6),("nginx",1216,6))

配置web节点服务器的配置文件

#配置文件的内容可以复制两份给,web02,web03,然后创建内容的目录的时候注意一下服务器池的内容
[root@www conf]# cat nginx.conf
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
	log_format main '"$http_x_forwarded_for"$remote_addr-$remote_user[$time_local]"$request"'
        '$status $body_bytes_sent "$http_referer"'
        '"$http_user_agent"';
    server {
        listen       80;
        server_name  www.yunjisuan.com;
        location / {
            root   html;
            index  index.html index.htm;
        }
	access_log logs/access_bbs.log main;
        }
    }
[root@www html]# mkdir upload				
[root@www html]# cd upload/
[root@www upload]# echo "`hostname -I`upload" > index.html
[root@www upload]# echo "`hostname -I` www.yunjisuan.com" >> /etc/hosts
[root@www upload]# curl www.yunjisuan.com/upload/index.html
192.168.182.161 upload

web03是动态服务器节点,添加图片访问的路径

#web02
[root@www /]# cd /usr/src/local/nginx/html/static/
[root@www static]# ls
111.jpg.jpg  index.html				#把图片放到了静态服务器池的里面

#web03
[root@www /]# cd /usr/local/nginx/html/dt/
[root@www dt]# cat index.html
192.168.182.170 dt
				#这里的ip地址是nginx反向代理的ip地址,有反向代理location过滤到静态的服务器池拿取图片

浏览器访问测试

上传服务器池的访问结果
lvs+keepalived集群架构服务_第18张图片

静态服务器池的访问结果
lvs+keepalived集群架构服务_第19张图片

动态服务器池的访问结果

tomcat

#tomcat部署略过
[root@localhost ~]# ifconfig lo:0 192.168.0.250/32 up		#手工绑定RS端口
[root@localhost ~]# echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@localhost ~]# echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce 
[root@localhost ~]# echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore 
[root@localhost ~]# echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce 

你可能感兴趣的:(lvs+keepalived集群架构服务)