一、介绍

    LVS是Linux Virtual Server的简写,即Linux虚拟服务器,是一个虚拟的服务器集群系统。该项目由章文嵩博士成立,是中国国内最早出现的自由软件项目之一。

    使用LVS技术要达到的目标是:通过LVS提供的负载均衡技术和Linux操作系统实现一个高性能、高可用的服务器群集,它具有良好可靠性、可扩展性和可操作性。从而以低廉的成本实现最优的服务性能。

    负载均衡技术有很多实现方案,如基于DNS域名轮流解析的方法、基于客户端调度访问的方法、基于应用层系统负载的调度方法,还有基于IP地址的调度方法,在这些负载调度算法中,执行效率最高的就是IP负载均衡技术。
    LVS的IP负载均衡技术是通过ipvs内核模块来实现的,ipvs是LVS集群系统的核心软件,它的主要作用是:安装在Director Server上,同时在Director Server上虚拟出一个IP地址,用户必须通过这个虚拟的IP地址访问集群服务。这个虚拟IP一般称为LVS的VIP,即Virtual IP。访问的请求首先经过VIP到达负载调度器,然后由负载调度器从Real Server列表中选取一个服务节点响应用户的请求。当用户的请求到达负载调度器后,调度器如何将请求发送到提供服务的Real Server节点,而Real Server节点如何返回数据给用户,是ipvs实现的重点技术,ipvs实现负载均衡机制有四种,分别是NAT、TUN和DR以及后来经淘宝开发的FullNat。下面将详细介绍这四种机制的工作模型。


二、工作原理

    这里所谈的工作原理主要是介绍ipvs的工作机制,以及用户管理。

    LVS分为两个部件:ipvs和ipvsadm

        ipvs : 工作于内核空间,主要用于使用户定义的策略生效;

        ipvsadm : 工作于用户空间,主要用于用户定义和管理集群服务的工具;

   wKiom1PGPUiDeSykAADpqGSMdEA174.jpg

    上图所示,ipvs工作于内核空间的INPUT链上,当收到用户请求某集群服务时,经过PREROUTING链,经检查本机路由表,送往INPUT链;在进入netfilter的INPUT链时,ipvs强行将请求报文通过ipvsadm定义的集群服务策略的路径改为FORWORD链,将报文转发至后端真实提供服务的主机。

    而我们一直说LVS是一个4层负载均衡软件,那它是如何做到的呢,下面我们就来介绍一下ipvs的集群管理和调度算法;


三、集群管理与调度算法

    对LVS的管理与netfilter极为相似,所以这里也是很好理解的;

    1、ipvsadm 语法详解:

ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] [-M netmask]
ipvsadm -D -t|u|f service-address
ipvsadm -C
ipvsadm -R
ipvsadm -S [-n]
ipvsadm -a|e -t|u|f service-address -r RS-address [-g|i|m] [-w weight] [-x upper] [-y lower]
ipvsadm -d -t|u|f service-address -r RS-address
ipvsadm -L|l [options]
ipvsadm -Z [-t|u|f service-address]
注释:
    -A    添加一个新的集群服务;
    -E    修改一个己有的集群服务;
    -D    删除指定的集群服务;
    -a    向指定的集群服务中添加RS及属性;
    -e    修改RS属性;
    -t    指定为tcp协议;
    -u    指定为udp协议;
    -f    指定防火墙标记码,通常用于将两个或以上的服务绑定为一个服务进行处理时使用;
    -s    调度方法,默认为wlc;
    -w    指定权重,默认为1;
    -p timeout   persistent connection, 持久连接超时时长;
    -g    Gateway, DR模型;
    -i    ipip, TUN模型;
    -m    masquerade, NAT模型;
    -S    保存ipvsadm设定的规则策略,默认保存在/etc/sysconfig/ipvsadm中;
    -R    载入己保存的规则策略,默认加载/etc/sysconfig/ipvsadm;
    -C    清除所有集群服务;
    -Z    清除所有记数器;
    -L    显示当前己有集群服务,能通过相应的options查看不同状态信息;
        -n: 数字格式显示IP地址;
        -c: 显示连接数相关信息;
        --stats: 显示统计数据;
        --rate: 速率;
        --exact:显示统计数据的精确值;


Director在接收到来自客户机的请求时,会基于schedule(调度算法)从RealServer中选择一个响应客户机的请求,下面将介绍10种调度算法;

    2、常用调度算法

    1)RR   轮询

        Round Robin :新的连接请求被轮流分配至各RealServer,优点是该算法无需记录当前所有连接的状态,效率高;但缺点是在RealServer当中如果有性能不均等的情况下,性能差的主机将负载比较大。该算法容易倒致服务器之间负载不均衡;

    2)WRR  加权轮询

        Weighted RR :优点与RR一样,无需记录所有连接状态;通过设定一定的权重值来分配连接请求;
    3)SH   源地址哈希

        Source Hashing :通过一个散列函数将去往同一个目的IP的请求映射到一台服务器或链路上。   

    4)DH   目标地址哈希

        Destination Hashing : 通过一个散列函数将来自同一个源IP的请求映射到一台服务器或链路上

    5)LC   最少连接数

        Least Connection :根据当前各服务器的连接数来估计服务器的负载情况,把新的连接分配给连接数最小的服务器;负载率=active*256+inactive,值小的优先分配请求;
    6)WLC   加权最少连接数

        Weighted LC :与LC类似,根据当前各服务器的连接数来估计服务器的负载情况,把新的连接分配给连接数最小的服务器;负载率=(active*256+inactive)/weight,值小的优先分配请求;   

    7)SED   最短期望延迟

        Shortest Expect Delay : 这个算法主要是优化LC的,在服务均在请求少的时候避免负载到一台服务器上做的优化;负载率=(active+1)*256/weight,值小的优先分配请求;
    8)NQ   永不排队

        Nerver Queue :在负载低时,请求直接分配到空闲服务器上,不会产生请求等待;当服务器都很忙时,将轮询;

    9)LBLC   基于本地最少连接

        Locality-Based Least Connection :根据请求的目标IP地址找出该目标IP地址最近使用的RealServer,若该Real Server是可用的且没有超载,将请求发送到该服务器;若服务器不存在,或者该服务器超载且有服务器处于一半的工作负载,则用“最少链接”的原则选出一个可用的服务器,将请求发送到该服务器。

    10)LBLCR   带复制的基于本地最少连接

        Replicated and Locality-Based Least Connection :该算法根据请求的目标IP地址找出该目标IP地址对应的服务器组,按“最小连接”原则从服务器组中选出一台服务器,若服务器没有超载,将请求发送到该服务器;若服务器超载,则按“最小连接”原则从这个集群中选出一台服务器,将该服务器加入到服务器组中,将请求发送到该服务器。


四、工作模型

    前面己介绍了LVS,我们知道ipvs安装在DR上面,在DR上虚拟一个对外访问的IP(VIP),用户访问VIP,到达DR,然后DR根据调度算法选择一个RS,处理完成后返回给客户端数据。但RS如何返回给客户端数据呢?ipvs有以下几种工作模式:

1、LVS-NAT

wKioL1PGc9TTuZhEAABTJbvCy2Q192.jpg

    此模型中,DR只需要将VIP配置到DR上,它的工作机制是,将收到的集群服务请求报文目标地址转换成经调度算法计算得出的后端主机IP地址,然后端主机将响应报文发送至DR,再由DR将源地址转换成VIP的地址;此机制与iptables中我们学习的DNAT类似;

NAT的特性:
  1> RS应该使用私有地址;
  2> RS的网关的必须指向DIP;
  3> RIP和DIP必须在同一网段内;
  4> 请求和响应的报文都得经过Director;在高负载场景中,Director很可能成为系统性能瓶颈;
  5> 支持端口映射;
  6> RS可以使用任意支持集群服务的OS;


2、LVS-DR

    此处列举出DR模型中两种常见的网络模型:关注数据帧格式的变化;

    1)client向目标vip发出请求,Director接收.此时IP包头及数据帧头信息如(1),(2);

    2)LVS根据负载均衡算法选择一台active的RS,将此RIP所在网卡的mac地址作为目标mac地址,发送到局域网里.此时IP包头及数据帧头信息如(3);

    3)RS在局域网中收到这个帧,拆开后发现目标IP(VIP)与本地匹配,于是处理这个报文.随后重新封装报文,发送到局域网.此时IP包头及数据帧头信息如(4);



wKiom1PHKI3joh1EAAD-vgMXdkM121.jpg

说明:在现实的环境中,我们的网络前端都有路由器,无论你的路由是运商提供还是局域网内部;此网络模型下CIP,DIP,RIP,VIP均为公网IP地址。

wKiom1PHKMOzIRKcAAEvlETaed0574.jpg

说明:同样,前端还是会有路由器,当我们没有足够多的公网IP时,可以采用此网络模型;该模型下DIP,RIP均为私有IP,而VIP为公网IP;此时需将其网关地址指向另一下路由器内网IP,这样才能保证数据正常传送出去。

   

    当我们分析上面两个网络模型的数据报时会发现一些问题:

        1)由于vip需要在每台主机中配置,如何保证ARP请求报文不会被交换机或其它网络设备知道?

        2)如何保证ARP通告报文不被交换机或其它网络设备知道?

        3)由于RS只有一个网络接口,而linux内核默认情况下包封装时是从哪个网口出去那个网口就是源地址,如何确保RS转发出来的报文源IP是VIP,而不是RIP?

        4)因为DR与RS都配置有相同的VIP,如何避免各主机VIP广播,造成无法通信?

    解决办法:

        1)Linux内核有两个关于ARP对待请回报文与通告报文的参数(arp_announce/arp_ignore),可以设定相应的级别来规避上述问题中的1、2两点;

        2)对于问题3,我们可以在数据报封装后指定路由经lo别名上的接口发送出去然后再通过eth0网卡转发出去;

        3)对于问题4,我们只需要设定vip的广播地址为它自己即可;

   下面我们继续来介绍linux内核参数arp_announce与arp_ignore:

arp_annouce:Define different restriction levels for announcing the local source IP address from IP packets in ARP requests sent on interface;
 0 - (default) Use any local address, configured on any interface.
 1 - Try to avoid local addresses that are not in the target's subnet for this interface.
 2 - Always use the best local address for this target.
 
arp_ignore: Define different modes for sending replies in response to received ARP requests that resolve local target IP address.
 0 - (default): reply for any local target IP address, configured on any interface.
 1 - reply only if the target IP address is local address configured on the incoming interface.
 2 - reply only if the target IP address is local address configured on the incoming interface and both with the sender's IP address are part from same subnet on this interface.
 3 - do not reply for local address configured with scope host, only resolutions for golbal and link addresses are replied.
 4-7 - reserved
 8 - do not reply for all local addresses

       

3、LVS-TUN

    在数据包必须传递到另一个网络或因特网上时,可以使用ip隧道,ip隧道能够将数据包从一个子网或虚拟局域网(VLAN)转发到另一个子网或虚拟局域网(VLAN),建立ip隧道是Linux内核功能的一部分,LVS-TUN转发方法允许你将集群节点放在与Director不同的网络上。

wKiom1PHUB-hMKfKAAErFLpoOdo937.jpg

    请留意DR将数据包转发给RS时的IP数据报文;由于DR,RS都不在同一局域网内,而DR要将client请求报文转发给RS时,DR是直接在数据包中直接添加IP首部(源IP:DR和目标IP:RS),这样就是隧道技术了。

    同样,该模型下RS都将配置VIP地址,且不能被外界所获知VIP存在于RS上;


4、LVS-FullNat

    LVS当前应用主要采用DR和NAT模式,但这2种模式要求RS和DR在同一个vlan中,导致部署成本过高;TUN模式虽然可以跨vlan,但RS上需要部署ipip模块等,网络拓扑上需要连通外网,较复杂,不易运维。为了解决上述问题,我们在DR上添加了一种新的转发模式:FullNat,该模式和NAT模式的区别是:Packet IN时,除了做DNAT,还做SNAT(用户ip->内网ip),从而实现DR-RS间可以跨vlan通讯,RS只需要连接到内网;

wKiom1PHT-qiq_nGAAEJ7XqVIUQ769.jpg

 

五、总结   

    此处只分析了一下各模型的工作原理,水平有限,尽量做到见图知义;如果你看完整后还相信他人所说LVS只工作于4层,那就大错特错了!


4种模型概要总结:

    1、LVS NAT的特性:
        1)RS应该使用私有地址;
        2)RS的网关的必须指向DIP;
        3)RIP和DIP必须在同一网段内;
        4)请求和响应的报文都得经过Director;在高负载场景中,Director很可能成为系统性能瓶颈;
        5)支持端口映射;
        6)RS可以使用任意支持集群服务的OS;


    2、LVS DR类型的特性:
        1)RS可以使用私有地址;但也可以使用公网地址,此时可以直接通过互联网连入RS以实现配置、监控等;
        2)RS的网关一定不能指向DIP;
        3)RS跟DR要在同一物理网络内(不能由路由器分隔);
        4)请求报文经过DR,但响应报文一定不经过DR
        5)不支持端口映射;
        6)RS可以使用大多数的操作系统;


    3、LVS TUN类型:IP隧道
        1)RIP、DIP、VIP都得是公网地址;
        2)RS的网关不会指向也不可能指向DIP;
        3)请求报文经过DR,但响应报文一定不经过DR;
        4)不支持端口映射;
        5)RS的OS必须得支持隧道功能;


    4、LVS FullNat:

        1)DR,RS可以不在同一网络内,但它与TUN不同,所有IP报文头部信息变更都在DR上进行,所以性能方面比LVS_NAT更差一些;

        2)需要注意配置路由,保证能正常通信;