LVS(Linux Virtual Server) 即Linux虚拟服务器 , 是由章文嵩博士主导的开源负载均衡项目 , 目前LVS已经被集成到Linux内核模块中。该项目在Linux内核中实现了基于IP的数据请求负载均衡调度方案 , 其体系结构如图1所示 , 终端互联网用户从外部访问公司的外部负载均衡服务器 , 终端用户的Web请求会发送给LVS调度器 , 调度器根据自己预设的算法决定将该请求发送给后端的某台Web服务器 , 比如 , 轮询算法可以将外部的请求平均分发给后端的所有服务器 , 终端用户访问LVS调度器虽然会被转发到后端真实的服务器 , 但如果真实服务器连接的是相同的存储 , 提供的服务也是相同的服务 , 最终用户不管是访问哪台真实服务器 , 得到的服务内容都是一样的 , 整个集群对用户而言都是透明的。最后根据LVS工作模式的不同 , 真实服务器会选择不同的方式将用户需要的数据发送到终端用户 , LVS工作模式分为NAT模式、TUN模式、以及DR模式。
它是一个负载均衡/高可用性集群, 主要针对大业务量的网络应用(如新闻服务、网上银行、电子商务等)。LVS建立在一个主控服务器(通常为双机)及若干真实服务器(real-server)所组成的集群之上。real-server负责实际提供服务,主控服务器根据指定的调度算法对real-server进行控制。而集群的结构对于用户来说是透明的, 客户端只与单个的IP(集群系统的虚拟IP)进行通信, 也就是说, 从客户端的视角来看,这里只存在单个服务器。Real-server可以提供做多服务,如ftp、http、dns、telnet、smtp , 以及现在比较流行将其用于MySQL集群。主控服务器负责对Real-Server进行控制。客户端在向LVS发出服务器请求时, Director会通过特定的调度算法指定由某个Real-Server来应答请求, 而客户端只与Load Balancer的IP(即虚拟的VIP)进行通信。以上工作流程图用LVS的工作拓扑来说明的话,可能效果会更好。由于我们的负载调度技术是在Linux内核中实现的 , 我们称之为Linux虚拟服务器( Linux Virtual Server)。
Linux Virtual Server项目的目标 : 使用集群技术和Linux操作系统实现一个高性能、高可用的服务器 , 它具有很好的可伸缩性( Scalability)、可靠性(Reliability) 和可管理性(Manageability)。
1. LVS 集群的体系结构
在设计时需要考虑系统的透明性、可伸缩性、高可用性和易管理性。一般来说,LVS集群采用三层结构, 三层主要组成部分为:

负载调度器(
load balancer)。它是整个集群对外的前端机,负责将客户的请求发送到一组服务器上执行,而客户认为服务时来自一个IP地址(我们可称之为虚拟IP地址)上的。服务器池(
server pool)。它是一组真正执行客户请求的服务器,执行的服务有WEB、MAIL、FTP和DNS等。共享存储(
shared storage)。它为服务器池提供一个共享的存储区, 这样很容易使得服务器池有相同的内容,提供相同的服务。
调度器是服务器集群系统的唯一入口点(Single Entry Point) , 它可以采用IP负载均衡技术、基于内容请求分发技术或者两者相结合。在IP负载均衡技术中 , 需要服务器池拥有相同的内容提供相同的服务。当客户请求到达时 , 调度器只根据服务器负载情况和设定的调度算法从服务器池中选出一个服务器 , 将该请求转发到选出的服务器 , 并记录这个调度 ; 当这个请求的其他报文到达 , 也会被转发到前面选出的服务器。在基于内容请求分发技术中 , 服务器可以提供不同的服务 , 当客户请求到达时 , 调度器可根据请求的内容选择服务器执行请求。因为所有的操作都是在Linux操作系统核心空间中完成的 , 它的调度开销很小 , 所以它具有很高的吞吐率。
服务器池的结点数目是可变的。当整个系统收到的负载超过目前所有结点的处理能力时 , 可以在服务器池中增加服务器来满足不断增长的请求负载。对大多数 网络服务来说 , 请求间不存在很强的相关性 , 请求可以在不同的结点上并行执行 , 所以整个系统的性能基本上可以随着服务器池的结点数目增加而线性增长。
共享存储通常是数据库、网络文件系统或者分布式文件系统。服务器结点需要动态更新的数据一般存储在数据库系统中 , 同时数据库会保证并发访问时数据的一致性。静态的数据可以存储在网络文件系统(如NFS/CIFS) 中 , 但网络文件系统的伸缩能力有限 , 一般来说 , NFS/CIFS服务器只能支持3~6个繁忙的服务器结点。对于规模较大的集群系统 , 可以考虑用分布式文件系统 , 如AFS、GFS、Coda和 Intermezzo等。分布式文件系统可为各服务器提供共享的存储区 , 它们访问分布式文件系统就像访问本地文件系统一样 , 同时分布式文件系统可提供良好的伸缩性和可用性。此外 , 当不同服务器上的应用程序同时读写访问分布式文件系统上同一资源时 , 应用程序的访问冲突需要消解才能使得资源处于一致状态。这需要一个分布式锁管理器(Distributed Lock Manager) , 它可能是分布式文件系统内部提供的 , 也可能是外部的。开发者在写应用程序时,可以使用分布式锁管理器来保证应用程序在不同结点上并发访问的一致性。
负载调度器、服务器池和共享存储系统通过高速网络相连接 , 如100Mbps交换网络、Myrinet和Gigabit网络等。使用高速的网络 , 主要为避免当系统规模扩大时互联网络成为整个系统的瓶颈。
Graphic Monitor是为系统管理员提供整个集群系统的监视器 , 它可以监视系统的状态。Graphic Monitor是基于浏览器的 , 所以无论管理员在本地还是异地都可以监测系统的状况。为了安全的原因 , 浏览器要通过HTTPS (Secure HTTP) 协议和身份认证后 , 才能进行系统监测 , 并进行系统的配置和管理。
Linux Virtual Server项目的目标 : 使用集群技术和Linux操作系统实现一个高性能、高可用的服务器 , 它具有很好的可伸缩性(Scalability) 、可靠性(Reliability) 和可管理性(Manageability)。
2. LVS集群中的术语
VS:Virtual Server,Director Server(DS),Dispatcher(调度器),Load Balancer。LVS负载均衡调度器本身 , 接收用户请求 ,负责把数据包分发到后端真实服务器。RS:Real Server(lvs),upsteam Server(nginx),backend Server(haproxy)。LVS后端真实业务服务器。CIP:Client IP。客户端IP, 外网用户的源IP。VIP:Virtual Server IP,vs外网的IP。虚拟服务IP, VS 暴露在外网的 IP ,用户访问的目标IP。DIP:Director IP,VS内网的IP。调度器内网IP,VS用来和后端RS通信的内网网卡IP。RIP:Real Server IP。后端真实服务器RS的内网IP。
访问流程: CIP<-->VIP == DIP <--> RIP
3. LVS工作原理
VS根据请求报文的目标IP和目标协议及端口将其调度转发至某RS , 根据调度算法来挑选RS。LVS是基于Linux内核中netfilter框架实现的负载均衡系统 ,工作在INPUT链的位置 , 将发往INPUT的流量进行“处理”, 在INPUT链上注册ip_vs_in HOOK函数 , 进行IPVS相关主流程 。netfilter其实很复杂也很重要,平时说的Linux防火墙就是netfilter , 不过我们操作的还是iptables ,iptables和netfilter是Linux防火墙组合工具, 是一起来完成系统防护工作的。iptables是位于用户空间 , 而Netfilter是位于内核空间。iptables只是用户空间编写和传递规则的工具而已 , 真正工作的还是netfilter。

当
Director接收到封包时 , 如果它的目的地址是VIP, 则PREROUTING后路由决策 , 会导致封包被发送到LOCAL_IN。这是因为VIP是Local地址 ,ip_vs_in挂钩到LOCAL_IN, 是VIP必须在Director上的原因 , 因为只有目标是本地地址 , 才能走到LOCAL_INLVS在LOCAL_IN注册钩子ip_vs_in, 需要注意的是 , 钩子具有优先级。最低优先级的钩子 , 最先看见封包。LVS的钩子的优先级 ,比iptables规则高 , 因此iptables规则首先应用到封包 , 然后是LVS上一步中 , 如果
ip_vs_in得到封包 , 它会根据负载均衡算法 , 选择一个RS, 然后如变魔法一般 , 将封包直接瞬移到POSTROUTING链LVS不会在FORWARD中寻找ingress封包 , 仅当NAT模式下 , 收到来自RS的回程报文时 ,LVS才和FORWARD链相关 , 封包在此unNATed( 源地址从RS改为Director)。同样需要注意 ,LVS在任何iptables规则之后看到封包
在Director上, filter rules会在ip_vs之前拦截。否则lvs的firewall mark不能工作。


详细原理概述如下:
当客户端用户访问 www.baidu.com 网站时 , 用户访问请求通过层层网络 , 最终通过交换机进入
LVS服务器网卡进入内核空间层。进入
PREROUTING后通过查找路由 , 确定访问目的VIP是本机IP地址的话 , 数据包将进入INPUT链中。因为
IPVS工作在INPUT链上 ,会根据访问的VIP和端口判断请求是否为IPVS服务 , 是的情况下 , 则调用注册的IPVS HOOK函数,进行IPVS相关流程 , 并强制修改数据包的相关数据 , 并将数据包发往POSTROUTING链中。POSTROUTING链收到数据包后 , 将根据目标IP地址服务器 , 通过路由选路 ,将数据包最终发送至后端真实服务器中。
范例 : 查看内核支持LVS
[root@centos8 ~]# grep -i -C 10 ipvs /boot/config-4.18.0-348.el8.x86_64
...(省略内容)...
# CONFIG_NETFILTER_XT_MATCH_IPCOMP is not set
CONFIG_NETFILTER_XT_MATCH_IPRANGE=m
CONFIG_NETFILTER_XT_MATCH_IPVS=m
...(省略内容)...
#
# IPVS transport protocol load balancing support
#
CONFIG_IP_VS_PROTO_TCP=y
CONFIG_IP_VS_PROTO_UDP=y
CONFIG_IP_VS_PROTO_AH_ESP=y
CONFIG_IP_VS_PROTO_ESP=y
CONFIG_IP_VS_PROTO_AH=y
CONFIG_IP_VS_PROTO_SCTP=y
#
# IPVS scheduler
#
CONFIG_IP_VS_RR=m
CONFIG_IP_VS_WRR=m
CONFIG_IP_VS_LC=m
CONFIG_IP_VS_WLC=m
CONFIG_IP_VS_FO=m
CONFIG_IP_VS_OVF=m
CONFIG_IP_VS_LBLC=m
CONFIG_IP_VS_LBLCR=m
CONFIG_IP_VS_DH=m
CONFIG_IP_VS_SH=m
CONFIG_IP_VS_MH=m
CONFIG_IP_VS_SED=m
CONFIG_IP_VS_NQ=m
...(省略内容)...