LVS:Linux Virtual Server
一、负载均衡
1.1 实现方式
硬件:
- F5
软件:
-
LVS:Linux Virtual Server,阿里云四层SLB(Server Load Balance)
-
nginx:支持七层调度,阿里云七层SLB使用Tengine(nginx二次开发版本)
-
haproxy:支持七层调度
四层、七层的理解
OSI参考模型有7层,从底向上依次是:
sh
第七层 应用层
第六层 表示层
第五层 会话层
第四层 传输层
第三层 网络层
第二层 数据链路层
第一层 物理层
所以,四层负载均衡指的是支持从第四层的传输层到第一层的物理层的负载均衡,七层负载均衡指的是支持从第七层的应用层到第一层的物理层的负载均衡。
LVS支持四层负载均衡,nginx支持四层、七层负载均衡。LVS虽然支持的层数少,但是性能要比nginx高,可以达到百万级别的并发。

最终的架构图如上,用户访问一个LVS的地址,在LVS前面还会有Linux防火墙保证网络安全。LVS收到请求,将请求转到nginx,由nginx转发到对应的应用上面。即:先经过四层负载LVS,再经过七层负载nginx
为什么不是先经过七层负载nginx,再经过四层负载LVS?
因为请求首先是做一个简单粗略的转发,前面使用四层负载LVS足够了。后面不能使用四层负载LVS,因为后面需要根据访问的请求地址来转发到不同的服务上面去,这是需要支持HTTP请求的,LVS无法实现,只能通过nginx来实现。
1.2 负载均衡的会话保持

用户访问应用,转发到第一台服务器,产生session保存到第一台服务器内存中。当此用户第二次访问应用时,可能就会将请求转发到第二台服务器,此时第二台服务器是没有用户session的。就会产生这种问题,用户明明刚刚登录过了,再次访问时提示未登录。
1.2.1 会话绑定

解决的思路就是会话绑定。一种实现方式是基于客户端IP地址,当用户A访问应用请求到第一台服务器上面,后面都会请求到第一台服务器。
但是,这种方式是不太合理的。访问互联网时,在转发网络数据包的时候,客户端IP地址会发生NAT(网络地址转换),看到的实际客户端IP地址都是一个公网地址(比如一间教室搭建的局域网,从这间教室出去的客户端IP公网地址都是一样的),这样,基于客户端IP地址绑定,就只会将请求转发到一台服务器上面,就会出现一台服务器忙死,另一台服务器很闲。
1.2.2 会话复制

用户请求到第一台服务器产生了session,会将第一台服务器的session复制到第二台服务器上面。同理,第二台服务器的session也会复制到第一台服务器上面。这样用户无论访问哪台服务器,都会有会话信息。
1.2.3 redis保存会话信息

使用共享的redis保存会话信息。
二、Linux Virtual Server简介
2.1 LVS介绍
LVS:Linux Virtual Server,是全球最流行的四层负载均衡开源软件,由章文嵩博士在1998年开发。目前,LVS已被整合到Linux内核当中,因此不需要安装LVS软件,默认内核就有负载均衡特性了。
阿里的四层SLB是基于LVS+keepalived实现的。
如何确认当前Linux内核有LVS功能
sh
#查看内核
ls /boot/config*

sh
#查看内核中是否有ipvs字样,有的话即代表有LVS功能
grep -i ipvs /boot/config-3.10.0-1160.119.1.el7.x86_64

2.2 LVS集群体系架构

2.3 LVS集群术语
- VS:Virtual Server,或者称为Director Server(DS), 或者称为Dispatcher(调度器),或者称为Load Balancer。它是LVS调度服务器,对外叫虚拟服务器,是用户访问的入口,让用户感知是访问的该服务器上面的服务,其实真正的服务是部署在其他服务器上面
- RS:LVS中称为Real Server, nginx中称为upstream server, haproxy中称为backend server,它是真实服务器
- CIP:Client IP,客户机IP
- VIP:Virtual serve IP,代理服务器的外网ip,LVS对外接收用户请求的IP
- DIP:Director IP,代理服务器的 内网ip,用来连接真实提供服务的服务器
- RIP:Real server IP,真实服务器 ip
一般LVS有两块网卡,外网VIP绑定一块网卡,内网DIP绑定一块网卡,这样从硬件层面就实现了隔离功能,用户请求就不能直接到达真实服务器。当然,如果VIP和DIP配置到同一块网卡上也可以,但是从物理层面上不安全
访问流程:CIP <--> VIP == DIP <--> RIP
2.4 LVS工作原理
LVS根据请求报文的目标IP和目标协议及端口将其调度转发至某RS,根据调度算法来挑选RS。LVS是内核级功能,工作在INPUT链的位置,将发往INPUT的流量进行"处理"。

三、LVS工作模式和相关命令
3.1 LVS工作模式
- lvs-nat:修改请求报文的目标IP,多目标IP的DNAT(目标地址NAT)
- lvs-dr:操纵封装新的MAC地址(直接路由) 这是默认模式
- lvs-tun:隧道模式,在原请求IP报文之外新加一个IP首部
3.1.1 LVS的NAT模式
lvs-nat:本质是多目标IP的DNAT(目标网络地址转换),通过将请求报文中的目标地址和目标端口修改为某挑出的RS的RIP和PORT实现转发

如上图,有后台服务部署在两台机器上面,对应上图的RS1和RS2,两台机器的IP地址如上。在两台RS前面,我们防止了一个LVS,LVS对内的DIP(转发地址)是10.0.0.8,对外VIP(提供访问的地址)是192.168.10.100。
计算机192.168.10.200要访问后台服务,首先发送第一个数据包,对应链路是计算机到LVS的VIP这一段。源IP是自己的IP地址192.168.10.200,源端口是计算机随机生成的一个端口,源MAC地址是计算机自己的MAC地址,目标地址是LVS的VIP 192.168.10.100,假设是HTTP协议,端口则对应80,目标MAC地址是LVS的VIP这一端网卡的MAC地址。
LVS收到数据包,就会将数据包转发到对应的服务上面,会发送第二个数据包,对应链路是LVS到服务这一段。源IP地址不变,还是192.168.10.200,源端口也保持不变,源MAC地址替换为LVS的DIP的MAC地址(这是因为一会还要接收返回的数据包,交换机是基于MAC地址进行数据包的转发,不配成LVS的DIP的MAC地址,一会就收不到返回的数据包了),目标地址是RS1服务的IP 10.0.0.7,假设服务提供的端口是8080,则端口为8080,目标MAC地址是RS1服务网卡的MAC地址。
服务RS1对请求做出响应,会发送第三个数据包,对应链路是RS1服务到LVS这一段。源IP地址为RS1服务的IP 10.0.0.7,端口为8080,源MAC地址是RS1服务网卡的MAC地址。目标地址是请求计算机的IP 192.168.10.200,目标端口为请求计算机的端口,目标MAC地址为请求计算机的MAC地址。
LVS收到数据包之后,会发送第四个数据包,对应链路是LVS到请求计算机这一段。源IP地址为LVS的VIP 192.168.10.100,端口为80,源MAC地址是LVS的VIP网卡的MAC地址。目标地址是请求计算机的IP 192.168.10.200,目标端口为请求计算机的端口,目标MAC地址为请求计算机的MAC地址。
用户的请求和响应都要经过LVS,所以NAT模式下LVS性能容易出现瓶颈
3.1.2 LVS的DR模式
LVS-DR:Direct Routing,直接路由,LVS默认模式,是基于数据链路层工作的。
用户后端请求经过LVS转到Real Server,Real Server的响应不经过LVS,而是直接返回给用户。但是,这种情况是有些问题的,用户请求的是LVS的VIP,结果响应回来的是Real Server的RIP。
解决方法就是,给Real Server都配上LVS的VIP,响应出去的都是VIP。
但是,这就又产生一个新问题,一个VIP配置到了两台不同的服务器上面,IP地址冲突了。IP地址冲突的原理是,通信的时候会通过ARP协议发送广播给每一台机器,询问这个IP地址对应的MAC地址是什么,结果这些机器的IP地址都一样,就都会返回自己的MAC地址。客户端就只能接收其中一个的MAC地址了。
我们现在给Real Server配上了VIP,本意是为了方便给客户端响应,这里配的VIP是不接收客户端请求的。能否将这里配置的VIP不让外界知道,不就解决了我们上面的问题了吗?解决方法就是,Real Server不能主动向外界公布自己拥有VIP,而且其他机器发送ARP广播询问MAC地址时,它也不能去做出响应,让别人知道自己拥有VIP。
Real Server上面还配置有RIP,这个RIP负责做出响应,是需要让外界知道的。所以,Real Server上面的RIP响应要打开,VIP响应要关闭。
最终的解决方案就是,Real Server的一块网卡配置RIP,另一块网卡配置VIP(实际上,可以使用LO网卡,它是一块虚拟网卡,把做出响应的参数关掉)。

DR模式示意图如上,一共涉及5步:
1、客户端发送请求到路由器Router
2、路由器将数据包转给LVS
3、LVS将数据包转给Real Server
4、Real Server响应给到路由器Router
5、路由器再将响应转给客户端。
第一个数据包:源IP地址是客户端IP地址192.168.10.123,源端口随机,源MAC地址是客户端MAC地址。目标IP地址是LVS的IP地址10.0.0.100,目标端口为80,表示HTTP请求,目标MAC地址是路由器的MAC地址router-eth1,是因为数据包需要过路由器才能到LVS,MAC地址是下一跳地址。
第二个数据包:源IP地址是客户端IP地址192.168.10.123,源端口随机,源MAC地址是路由器另一个口的MAC地址router-eth0。目标IP地址是LVS的IP地址10.0.0.100,目标端口为80,表示HTTP请求,目标MAC地址是LVS的MAC地址。
第三个数据包:源IP地址是客户端IP地址192.168.10.123,源端口随机,源MAC地址是LVS的MAC地址。目标IP地址是Real Server的IP地址10.0.0.100,目标端口为80,表示HTTP请求,目标MAC地址是Real Server的MAC地址。
第四个数据包:源IP地址是VIP地址10.0.0.100,源端口80,源MAC地址是Real Server的MAC地址。目标IP地址是客户端IP地址192.168.10.123,目标端口随机,目标MAC地址是路由器的MAC地址。
第五个数据包:源IP地址是VIP地址10.0.0.100,源端口80,源MAC地址是路由器的MAC地址。目标IP地址是客户端IP地址192.168.10.123,目标端口随机,目标MAC地址是客户端的MAC地址。
可以看到,DR模式只是修改了MAC地址,IP地址是没有变动的。这种模式也有缺陷,如果客户端访问的是80端口,则Real Server也需要使用80端口,因为整个过程是不支持端口修改的。由于它只修改MAC地址,只改动数据链路层,相对于NAT模式更底层,同时返回报文不需要经过LVS,所以速度较NAT模式要快
LVS上会配置后端RS的RIP, 但是MAC地址是不知道的。LVS通过arp广播, 根据被被调度的RS的RIP, 查询其MAC地址 由于LVS和RS依靠arp广播, 因此, LVS和RS必须在同一个网段, 不能用路由器相连, 不远程调度, 需要LVS和RS部署在同一个机房, 一旦机房出现问题, 会有单点故障
DR模式的特点
-
LVS和各RS都配有VIP
-
在RS上调整内核参数, 禁止RS服务器响应免费arp广播, 禁止RS服务器发送免费arp广播
sh/proc/sys/net/ipv4/conf/all/arp_ignore /proc/sys/net/ipv4/conf/all/arp_announce -
LVS和RS在同一个物理网络
-
请求报文要经过LVS,响应报文不需要经过LVS