Linux-负载均衡LVS
lvs负载均衡
负载均衡集群是load balance 集群的缩写,翻译成中文就是负载均衡集群。常用的负载均衡开源软件有nginx、lvs、haproxy,商业的硬件负载均衡设备有f5、netscale等。
负载均衡lvs基本介绍
lb集群的架构和原理很简单,就是当用户的请求过来时,会直接分发到director server上,然后它把用户的请求根据设置好的调度算法,智能均衡的分发后端真正服务器(real server)上。为了避免不同机器上用户请求的数据不一样,需要用到了共享存储,这样保证所有用户请求的数据是一样的。
lvs是linux virtual server 的简称,也就是linux虚拟服务器。这是由章文嵩博士发起的一个开源项目,官网: 现在lvs已经是 linux 内核标准的一部分。使用 lvs 可以达到的技术目标是:通过 lvs 达到的负载均衡技术和 linux 操作系统实现一个高性能高可用的 linux 服务集群,它具有良好的可靠性、可扩展性和可操作性。从而以廉价的成本实现最优的性能。 lvs 是一个实现负载均衡集群的开源软件项目,lvs架构从逻辑上可分为调度层、server集群层和共享存储。
lvs的体系架构
使用lvs假设的服务器集群系统有三个部分组成:最前端的负载均衡器(loader balancer),中间的服务器群组层,用server array 表示,最底层的数据共享存储层,用shared storage表示。在用户看来所有的应用都是透明的,用户只是在使用一个虚拟服务器提供的高性能服务。
如图:
lvs的各个层次的详细介绍:
- load balancer层:
位于整个集群系统的最前端,有一台或者多台负载调度器(director server)组成,lvs模块就是安装在director server上,而director的主要作用类似于一个路由器,它含有完成lvs功能所设定的路由表,通过这些路由表把用户的请求分发给server array层的应用服务器(real server)上。同时,在director server上还要安装队real server服务的监控模块ldirectord,此模块用于检测各个real server服务的健康状况。在real server不可用时把它从 lvs 路由表中剔除,恢复时重新加入。
-
server arrary层:
由一组实际运行应用服务的机器组成,real server可以是web 服务器、mall服务器、ftp服务器、dns服务器、等等,每个real server 之间通过高速的lan或分布在各地的wan相连接,在实际的应用中,director server也可以同时兼任real server的角色。
-
shared storage层:
是为所有real server提供共享存储空间和内容一致性的存储区域,在物理上,一般有磁盘阵列设备组成,为了提供内容的一致性,一般可以通过nfs网络文件系统共享数据,但是nfs在繁忙的业务系统中,性能并不是很好,此时可以采用集群文件系统,列如red hat的gfs文件系统等等。
lvs的基本工作原理
(1)当用户负载均衡调度器(director server)发起请求,调度器将请求发往至内核空间
(2)prerouting 链首先会接受到用户请求,判断目标ip确实是本地ip,将数据包发往 input 链
(3)ipvs 是工作在 input 链上的,当用户请求到达input时,ipvs 会将用户请求和自己定义好的集群服务进行比对,如果用户请求的就是集群服务,那么此时 ipvs 会强行修改数据包里的目标ip地址和端口,并将新的数据包发往 postrouting 链
(4)postrouting 链将收到数据包后发现目标ip地址刚好是自己的后端服务器,那么此时通过选路,将数据包最终发送给后端的服务器
lvs相关术语
(1)ds:director server 指的是前端负载均衡器节点。
(2)rs:real server 后端真实的工作服务器。
(3)vip:向外部直接面向用户请求,作为用户请求的目标的ip地址。
(4)dip:director server ip 主要用于和内部服务器通讯的ip地址。
(5)rip:real server ip 后端服务器的ip地址。
(6)cip:client ip 访问客户端的ip地址。
lvs工作模式和原理
nat 模式
nat 模式工作原理:
(1)当用户请求到达director server,此时的请求数据报文会先到内核空间的prerouting链。此时报文的源ip为 cip,目标ip为 vip。
(2)prerouting检查发现数据包的目标ip 是本机,将数据包发送至input链。
(3)ipvs比对数据包请求的服务是否为集群服务,若是,修改数据包的目标ip地址为后端服务器ip,然后将数据包发送至postrouting链。此时报文的源ip为 cip,目标ip为 rip。
(4)postrouting链通过选路,将数据包发送给real server。
(5)real server对比发现目标为自己的ip,开始构建响应报文发回给director server。此时报文的源ip为 rip,目标ip为 cip。
(6)director server在响应客户端前,此时会将源ip地址修改为自己的vip地址,然后响应给客户端。此时报文的源ip为 vip,目标ip为cip。
dr 模式
dr 模式工作原理:
(1)首先用户用cip请求vip。
(2)根据上图可以看到,不管是director server 还是real server 上都需要配置相同的vip,那么当用户请求到达我们的集群网络的前端路由器的时候,请求数据包的源地址为cip,目标地址为vip;此时路由器还会发广播问谁是vip,那么我们集群中所有的节点都配置有vip,此时谁先响应路由器那么路由器就会将用户请求发给谁,这样一来我们的集群系统是不是没有意义了,那我们可以在网关路由器上配置静态路由指定vip就是director server,或者使用一种机制不让real server 接受来自网络中的arp 地址解析请求,这样一来用户的请求包都会经过director server。
(3)当用户请求到达director server,此时请求的数据报文会先到内核空间的prerouting链,此时报文的源ip为cip,目标ip为vip。
(4)prerouting检查发现数据包的目标ip为本机,将数据包发送至input链。
(5)ipvs对比数据包请求的服务是否为集群服务,若是,将请求报文中的源mac地址修改dip的mac地址,将目标mac地址修改为rip的mac地址,然后将数据包发至postrouting链,此时的源ip和目标ip均未修改,仅修改了源mac地址为dip的mac地址,目标mac地址为rip的mac地址。
(6)由于ds和rs在同一个网络中,所以是通过二层来传输,postrouting链检查目标mac地址为rip的mac地址,那么此时数据包将会发至real server。
(7)rs发现请求报文的mac地址是自己的mac地址,就接收报文。处理完成之后,将相应报文通过lo接口传送给eth0网卡然后向外发出。此时的源ip地址为vip,目标ip为cip。
(8)响应报文最终送达至客户端。
配置dr的三种方式:
- 第一种:在路由器上明显说明vip对应的地址一定是director上的mac,只要绑定,以后再跟vip通信也不用再请求了,这个绑定是静态的,所以它也不会失效,也不会再次发起请求,但是有个前提,我们的路由设备必须有操作权限才能够绑定mac地址,万一这个路由器是运营商操作的,我们没法操作怎么办?第一种方式固然很简单,但未必可行。
- 第二种:在个别主机上(列如:红帽)它们引进的有一种程序arptables,它有点类似iptables,它肯定是基于arp或者mac做访问控制的,很显然我们只需要在每一个real server上定义arptables规则,如果用户arp广播请求的目标地址是本机的vip则不予响应,或者说响应的报文不让出去,很显然(gateway)是接收不到的,也就是director响应的报文才能到达gateway,这个也行。第二种方式我们可以基于arptables。
-
第三种:在相对较新的版本中新增了两个内核参数(kernelparameter),第一个是arp_ignore定义接受到arp请求时的响应级别;第二个是arp_announce定义将自己地址向外通告时的通告级别。[提示:很显然我们现在的系统一般在内核中都是支持这些参数的,我们用参数的方式进行调整更具有朴实性,它还不依赖额外的条件,像arptables,也不依赖外在路由配置的设置,反而通常我们使用的是第三种配置方式]
arp_ignore:定义接收到arp请求时的响应级别 0:只要本地设置的有相应的地址,就给予响应。(默认) 1:仅回应目标ip地址是本地的入网地址的arp请求。 2:仅回应目标ip地址是本地的入网地址,而且源ip和目标ip在同一个子网的arp请求。 3:不回应网络界面的arp请求,而只对设置的唯一和连接地址做出回应。 4-7:保留未使用。 8:不回应所有的arp请求。 arp_announce:定义将自己地址向外通告的通告级别: 0:将本地任何接口上的任何地址向外通告。 1:视图仅向目标网络通告与其网络匹配的地址。 2:仅向与本地接口上地址匹配的网络进行通告。
dr模式的特性
- 保证前端路由将目标地址为vip报文统统发给director server,而不是rs。
- director和rs的vip为同一个vip。
- rs可以使用私有地址,也可以是公网地址,如果使用公网地址,此时可以通过互联网对rip进行直接访问。
- rs跟director server必须在同一个物理网络中。
- 所有的请求报文经由director server,但响应报文必须不能经过director server。
- 不支持地址转换,也不支持端口转换。
- rs 可以是大多数常见的操作系统。
- rs 的网关绝不允许指向dip(因为我们不允许它经过director)
- rs上的lo接口配置vip的ip地址
- dr模式是市面上用得最广的。
- 缺陷:rs和ds必须在同一机房。
tunnel 模式
tunnel 模式工作原理:
(1)当用户请求到达director server,此时请求的数据报文会先拿到内核空间的prerouting链,此时报文的源ip为cip,目标ip为vip。
(2)prerouting检查发现数据包的目标ip是本机,将数据包发送至input链。
(3)ipvs对比数据包请求的服务是否为集群服务,若是,在请求报文的首部再次封装一层ip报文,封装源ip为dip,目标ip为rip。然后发至postrouting链,此时源ip为dip,目标ip为rip。
(4)postrouting链根据最新封装的ip报文,将数据包发送至rs(因为在外层多封装了一层ip首部,所以可以理解为 此时通过隧道传输)。此时源ip为dip,目标ip为rip。
(5)rs接收到报文后发现是自己的ip地址,就将报文接收下来,拆除掉最外层的ip后,会发现里面还有一层ip首部,而且目标是自己的lo接口vip,那么此时rs开始处理请求,处理完成之后,通过lo接口发送给eth0网卡,然后向外传递。此时源ip为vip,目标ip为cip。
(6)响应报文最终送达至客户端。
tunnel模式的特性
rip、vip、dip全是公网地址。
rs的网关不会也不可能指向dip。
所有的请求报文经由director server,但响应报文必须不能经过director server。
不支持端口映射。
rs的系统必须支持隧道。
lvs 的调度算法
固定调度算法:rr,wrr,dh,sh
动态调度算法:wlc,lc,lblc,lblcr
固定调度算法:即调度器不会去判断后端服务器的繁忙与否,一如既往得将请求派发下去。
动态调度算法:调度器会去判断后端服务器的繁忙程度,然后依据调度算法动态得派发请求。
rr:轮询(round robin)
这种算法是最简单的,就是按依次循环的方式将请求调度到不同的服务器上,该算法最大的特点就是简单。轮询算法假设所有的服务器处理请求的能力都是一样的,调度器会将所有的请求平均分配给每个真实服务器,不管后端 rs 配置和处理能力,非常均衡地分发下去。这个调度的缺点是,不管后端服务器的繁忙程度是怎样的,调度器都会讲请求依次发下去。如果a服务器上的请求很快请求完了,而b服务器的请求一直持续着,将会导致b服务器一直很忙,而a很闲,这样便没起到均衡的左右。
wrr:加权轮询(weight round robin)
这种算法比 rr 的算法多了一个权重的概念,可以给 rs 设置权重,权重越高,那么分发的请求数越多,权重的取值范围 0 – 100。主要是对rr算法的一种优化和补充, lvs 会考虑每台服务器的性能,并给每台服务器添加要给权值,如果服务器a的权值为1,服务器b的权值为2,则调度到服务器b的请求会是服务器a的2倍。权值越高的服务器,处理的请求越多。
dh:目标地址散列调度算法 (destination hash)
简单的说,即将同一类型的请求分配给同一个后端服务器,例如将以 .jgp、.png等结尾的请求转发到同一个节点。这种算法其实不是为了真正意义的负载均衡,而是为了资源的分类管理。这种调度算法主要应用在使用了缓存节点的系统中,提高缓存的命中率。
sh:源地址散列调度算法(source hash)
即将来自同一个ip的请求发给后端的同一个服务器,如果后端服务器工作正常没有超负荷的话。这可以解决session共享的问题,但是这里有个问题,很多企业、社区、学校都是共用的一个ip,这将导致请求分配的不均衡。
lc:最少连接数(least-connection)
这个算法会根据后端 rs 的连接数来决定把请求分发给谁,比如 rs1 连接数比 rs2 连接数少,那么请求就优先发给 rs1。这里问题是无法做到会话保持,即session共享。
wlc:加权最少连接数(weight least-connection)
这个比最少连接数多了一个加权的概念,即在最少连接数的基础上加一个权重值,当连接数相近,权重值越大,越优先被分派请求。
lblc:基于局部性的最少连接调度算法(locality-based least-connection)
将来自同一目的地址的请求分配给同一台rs如果这台服务器尚未满负荷,否则分配给连接数最小的rs,并以它为下一次分配的首先考虑。
lblcr:基于地址的带重复最小连接数调度 (locality-based least-connection with replication)
这个用得少,可以略过。