负载均衡就是,在多个提供相同服务主机的前段,增加一个分发器,根据用户请求,然后根据某种方式或者策略,将用户请求分发到提供服务的主机上。同时负载均衡应用还应该提供对后其后端服务健康检查的功能。
如何转发取决于调度算法,有2种算法一个是RR一个是WRR。用户看到的是负载均衡的地址,一般还会对负载均衡做高可用,这样才能保证业务的持续性。
负载均衡有2大类:
一般七层的负载均衡叫做代理或者叫反向代理。四层和七层的主要区别在于四层只解析到TCP/IP层,它不在解析更高层,说白了就是不再继续拆包,所以四层的比七层的性能更好,但是缺点是没有高级特性,网康设备就是工作在七层的,所以它可以有很多高级功能,比如查看用户访问了那些网站,其实就是对HTTP请求做的解析。对负载均衡设备来说,工作在七层的可以根据用户请求的URL来做负载均衡。而且七层负载均衡一般都是针对特定一种或者几种(不会是所有,也就是针对某一个方面)做解析,同时它还支持对解析出来的东西做一些修改然后在向后端分配。不过相对来讲七层的性能比四层的略低(在相同硬件配置和相同请求量的前提下),不过在生产环境中七层的更能贴近实际需求,所以在选择使用哪种负载均衡的时候要根据业务特性和需求来进行判断。
LVS可以解析三层和四层请求,只要是TCP/IP协议都可以解析,假设一个WEB服务器集群,使用默认80端口,其中一台主机是172.16.100.1,如果负载均衡器收到一起请求,那么它就会把请求转发到该主机上,这个过程有点类似于NAT,但是还不同,因为它可以向后转发到多台主机上。
用户请求IP:PORT地址A(这个地址是路由器的地址),路由器收到这个地址后会查看自己的过滤表,如果找到匹配的配置项,就会修改数据包的目标地址为后端主机的真实地址,然后把数据包放到转发队列,然后进行转发。如果发现没有匹配项,则认为这个请求是请求给路由器自己的,因为请求带有端口号,路由器会检查自己是否开启了对应端口的进程,如果有就说明是访问该进程的,如果没有就会给请求发起方报错。
LVS其实也是借鉴了DNAT的工作方式,LVS工作在Linux的内核空间上。但是不同的是LVS收到请求会直接修改请求的数据包中的目标地,然后进行转发。
在Iptables中,ipbables只是用来写规则的,真正执行的是netfilter;在LVS中也是类似的结构,ipvsadmin是管理工具(工作在用户空间的工具),ipvs是执行的且工作在内核中。Ipvs是工作在input链上(Input链是Iptables所用的到的Linux内核框架的一部分),一旦用户请求到了input链,就会被IPVS捕获,然后IPVS就会去检查数据包,如果它发现请求是一个集群服务就会修改数据包,然后转发。如果IPVS发现这个请求不是对集群服务的请求,就会把这个请求转发到用户空间(Linux系统的用户空间)。这一点和iptables有点不太一样,所以iptables和LVS不能同时在一台Linux主机上使用。所以LVS中的IPVS必须工作在内核中。所以基于IP和端口的转发就是四层转发。
一个负载均衡调度器可以为多个集群服务提供服务,功能上可以,但是出于性能考虑一般不会这么做,所以一个负载均衡调度器只会为一个集群服务提供服务。
LVS的服务器有2个网卡,对外接收请求的网卡的IP叫做VIP,也就是虚拟IP,其实也是真实的IP地址,至少这样称呼,相对于内部真正的应用服务器而言;对内的网卡的IP叫做DIP,也就是转发IP;而真实的应用服务器网卡的IP叫做RIP。用户电脑的IP叫做CIP。
对于这种类型,负载均衡调度器需要有2个网络接口,一个面对互联网,一个面对内网,也就是上面的图形。属于串联模式。相当于在LVS后面组成一个私有网络。
实现原理就是把用户的请求的地址修改为后端真是服务器的IP地址来然后进行转发。工作机制和DNAT一样。
源地址是CIP,目标地址是VIP,然后修改数据包,挑选一个后端服务器,然后就把数据包转发到该后端服务器,这时候数据包的源IP是CIP,目标IP则是某一台主机的RIP。
当主机返回信息的时候,转发器会在做一次转发,修改数据包。
在这种模式下对于用户请求的进出都要经过转发器,所以转发器的压力相对较大。在这种模式下后端应用最多10个,但一般都会少于10个。
基本法则:
一般企业不使用NAT模型,哪怕应用服务器比较少。
缺陷:转发器和应用服务器必须在同一子网中
LVS服务器和应用服务器都是单网卡,LVS和应用服务器并联在交换机上。
在这个模型上就是请求进来被发送到LVS上,LVS的内核空间的IPVS截取,然后分析,如果是访问集群服务,就转发到被LVS选中的应用服务器上,应用服务器处理完成后,直接返回数据给客户端,而不再经过LVS,这样就减少了LVS的工作负担,同时应用服务器也不用和LVS组成一个私有网络。
这里就有一个问题,我们知道转发器在会把数据包中的目标IP更换为RIP进行转发,那么应用服务器处理完成后返回结果,返回数据包的源IP会是RIP,目标IP则是CIP,这时就不对了,因为请求进来的时候目标IP是LVS上的VIP。所以为了解决这个问题,LVS和所有应用服务器上都配置了VIP。
那么这里就又有一个问题,如果都配置相同的VIP,那么就会冲突,而且路由器也不知道该发给谁,所以这里就用到了网卡别名。在LVS上它其实配置了VIP和DIP,虽然只有一个网卡,VIP配置在网卡上,DIP配置在网卡别名上。在应用服务器上,RIP是不同的这个是肯定的,VIP是一样的,这个VIP也是配置在网卡别名上而且是隐藏的,它不用来接收任何请求,接收数据还是RIP来完成,这个VIP只有在应用服务器响应请求的时候把它作为源地址时使用,当然实际使用的网卡开始那个配置了RIP的网卡,在通讯层面上VIP不起作用,它只是作为数据包的源地址使用。
不过需要注意的是,在DR模式中,转发器会修改请求的数据包的地址,但是修改不是把VIP替换成RIP,而是修改了地址(源MAC和目标MAC)。因为从路由器进来以后,会把报文封装成帧,会加入源MAC和目标MAC,路由器的内网口会把源MAC地址写成自己的内网口MAC,目标写成LVS物理网卡的MAC地址,然后LVS收到以后会修改帧里面的目标MAC地址(原来为LVS网卡的MAC地址)为被挑选的应用服务器的MAC地址,修改源MAC地址(原来路由器内网口的MAC地址)为自己网卡的MAC地址,而不是修改目标IP地址。
当应用服务器收到数据包以后,拆掉MAC地址,看到的数据包的源IP是CIP也就是客户端的IP,而目标IP就是VIP,而且应用服务器上通过网卡别名已经设置了VIP,所以它会认为这就是个自己的。处理完请求后需要返回数据,因为客户端是请求的VIP,所以应用服务器就用VIP来封装数据包,这样就直接响应出去了,而不需要再经过LVS。
这样的话就LVS的性能就会有很大提高,因为请求数据包都很小,响应报文都比较大。
说明:无论是否是DR模式,来自网络层的IP报文都最终都会被封装成帧。所以路由器接收到IP数据包之后会先到到数据链路层后经过LLC子层和MAC子层进行协议头封装,最终形成以太网MAC帧,送达到主机。
基本法则:
缺陷:所有应用服务器都暴露在公网,就算它用私有地址,但是也要保障它可以和互联网直接通讯,否则它响应的报文无法到达客户端。
DR模式下集群节点要在同一物理网络内,那有一种场景如果要实现异地容灾,两个机房在不同城市甚至是不同国家,那怎么办?这就用到隧道模式。
在隧道模式下LVS即不替换VIP也不修改MAC地址,而是通过在数据报文外层再套一层报文来封装。
因为客户端请求发过来的时候源IP是CIP,目标IP是VIP,所以LVS要转发到其他地区的应用服务器上这只能在三层协议上进行也就是IP报文,如果你替换了VIP,那么应用服务器响应客户端的时候就有问题,所以就会在原有的IP报文上在套一层来封装,把LVS的DIP作为源IP,而应用服务器的RIP作为目标IP,然后进行转发。当应用服务器收到数据包以后,拆开第一层,然后发现里面的数据包有CIP和VIP,应用服务器上也有VIP(跟DR模式一样使用网卡别名然后隐藏),就会认为是发给自己的,然后做出处理最后响应请求,同时封装响应请求的时候目标是CIP,源IP则使用VIP地址。
在这种模式下LVS和应用服务器要支持隧道机制。
基本法则:
Linux内核发展到2.6.32以后才引入的一种类型,这个类型必须要打补丁才能使用。不过现在大多使用CentOS 7所以无需补丁。
这个模型是采用NAT基础但是解决了应用服务器和调度器可以在不同子网中。因为是NAT模型所以应用服务器就不会暴露在互联网上,同时也实现了应用服务器可以跨网段部署。
所谓FULLNAT就是把数据包的源地址和目标地址都做修改,入栈的时候把CIP +VIP的数据包修改为DIP+RIP的数据包,这样就可以发送到应用服务器上,当应用服务器响应请求的时候,同样适用DIP+RIP的数据包,这样就保障肯定会发到LVS主机上,然后调度器再次修改数据包的源地址和目标地址,改成CIP+VIP然后发送给客户端。
调度算法就是从LVS的后端应用服务器中挑选一个进行转发。调度算法有10种,那么10种又分成2大类,静态方法和动态方法。
只根据算法本身进行调度和分配请求,这种方法中RR和WRR有缺陷就是用户会话无法保持,比如在电商网站上,用户第一次的请求被转发到了A服务器,用户第二次的操作请求被转发到了B服务器,所以这就造成了用户第一次会话请求数据丢失。所以要想解决就只能使用Session复制或者建立单独的服务器。
根据算法和应用服务器的负载情况综合分析来觉得转发到哪个应用服务器。
Session会话保存的方法有三种:
LVS的缺陷是:它不会考虑应用服务器的健康状况,如果应用服务器故障它也会选择。