LVS即Linux Virtual Server,淘宝大牛章文嵩读博士时发起的开源软件项目,是性能非常好的四层负载均衡集群服务,Linux内核2.4以后已经被直接收录至内核。


LVS的工作模式:

    在了解工作模式之前首先要晓得为什么会有不同的工作模式,用户的请求进来会先发送到director(virtual server),然后director通过一定的调度算法把请求比较公平的分发到后端的real server,那么自然由real server响应回去给用户。


本文中提到的缩写解释:

    VIP: Director对外提供服务的 Virtual IP

    DIP: Director IP地址

    CIP: Client IP 客户端的IP地址

    RIP: 实际提供服务的Real Server的IP


因为一个主机收到一个数据包,如果源IP地址不是自己请求过的IP地址那么它则认为这个包是无效的,会直接丢弃。而通过负载均衡给后端Real Server再响应回去的数据包如果直接不加修饰的响应回去则就因为源IP是RIP而不是用户请求的VIP而被丢弃,lvs的几种工作模式就是为了解决这个问题的。


NAT模型:网络地址转换

NAT模式下,客户端的请求包到达Director时源IP和目标IP分别是客户端CIP和VIP,所以VIP是公网IP,而转发至后端时则把目标IP改为RIP,响应的包回去经过Director时再把源IP改回VIP,所以Real Server的网关是必须指向DIP的,而DIP和RIP则可以是私有地址且在同一网段,这样也比较安全避免realserver直接暴露在互联网上。其中目标地址和源地址的转换过程由内核模块自动完成,无需人工干预。


FullNAT: 淘宝另一大牛吴佳明牵头作品,此模式下当数据包离开Director发往realserver时会把源IP和目标IP一起全改掉成DIP|RIP,realserver响应的包则源和目标为RIP|DIP,Director回给客户端时则把源和目标再全改回VIP|CIP。

    这样做的好处是DIP和VIP可以不在同一网段,从而realserver就可以分布在多个不同地点机房,既可以达到类似CDN的效果,又可以实现异地容灾。

wKioL1PxxzvzBG16AAEkhg9T7pU354.jpg


DR模型

实现原理和重点:

  1. 数据包通过director转给realserver时,通过修改帧header,直接只把目标MAC改为要调度的realserver的MAC,这样realserver回应的时候就可以保持源IP为VIP响应回去。

    But,仅仅这样是不行的,因为Linux回应包的时候必须本机有这个IP地址才可以以这个IP做为源IP,这个可以通过网卡别名配上VIP实现。

  2. BUT BUT... 如果各realserver都配上VIP,linux的IP地址是属于主机的而非网卡,且linux一旦接入网络就会立即大公无私的向全网通告自己所有的IP地址和MAC,what? 这下director和realserver连接的交换机就要晕菜了,你们都叫VIP全乱了,谁都不知道这个包会发给哪个完全不可控了,还谈什么负载均衡? 这个问题的解决可以通过修改内核参数实现控制Linux主机只向网络通告既定的网卡的IP和MAC信息。所以假设RIP是配置在eth0上的,那么VIP则一定不可以配在eth0的别名上,一般配置在lo上面即可

  3. 看似解决了问题其实这样还不够,因为Linux还有个特性:一个数据包从某个网卡出去时只有这个网卡上配了某个IP地址才可以以这个IP作为源IP打包出去,也就是说如果响应包从eth0出去响应那么必须eth0上配了VIP才可以把源IP打上VIP再出去,上面已经为了避免网络中VIP的MAC地址通告混乱,已经把VIP配在lo:0(假定lo:0)上了--> 不怕,解决这个问题可以通过添加一条主机路由,让所有到VIP的数据报文出去的时候都从eth0走就好了


  • 这样一来由于包转发给realserver时只修改了目标MAC所以此模式是肯定不支持端口映射的;

  • 既然是直接修改MAC通信的所以DIP和RIP则一定要在同一VLAN内;

  • 由于响应包从realserver出去时源IP和目标IP已经是VIP|CIP所以也不需要经过director,可以通过任何路由出去即可。


wKioL1PxxxaCqQz9AAF7wpbAk_c177.jpg


TUN模型:Tunneling隧道协议

    Director收到Client的请求包后,在外层再加上一个IP头为DIP|RIP后封装成IP隧道协议报文,然后发送给realserver,所以realserver一定要可以理解IP隧道协议才可以,拆包后看到还有一个头是CIP|VIP,所以realserver就打上VIP|CIP的IP头直接回给Client.

wKioL1PywyjCtWunAAGuha1CV70078.jpg


LVS的十种调度算法

  • 静态(fixed):

    • rr:round robin 轮调

    • wrr: weight rr 加权的轮调

    • sh: source hash 源地址哈希,对客户端IP地址做哈希,director会维护一个session hash table,结果就是来自同一个客户端的请求都会被调度到一台后端服务器。

    • dh: destination hash 目标url等hash,适用于有cache server场景,对于同一请求发送到同一cache server.

  • 动态(Dynamic

    • lc: least connection 最少连接

      • overhead = active(活动连接数)*256 + inactive 选最小的

    • wlc: weight lc 加权的最小连接

      • wOverhead= (active*256 + inactive) / weight 选最小的

    • sed: shortest expected delay 最小期望延迟

      • overhead = (active + 1)*256 / weight

    • nq: never queue 永不排队,开始就先一人发一个,然后再按sed算法调度

    • lblc: locality based least connection基于本地的最小连接

      • 动态的dh,大概相当于dh + lc

    • lblcr : lblc with replication 带复制的lblc

      • director维护一个proxy server table,请求进来时选择活动连接最少的