代码改变世界

LVS 四层 TCP/UDP 负载均衡器

2019-01-04 15:12  云物互联  阅读(3600)  评论(0编辑  收藏  举报

目录

LVS

在这里插入图片描述

针对高可伸缩、高可用网络服务的需求,我们给出了基于 IP 层和基于内容请求分发的负载平衡调度解决方法,并在 Linux 内核中实现了这些方法,将一组服务器构成一个实现可伸缩的、高可用网络服务的虚拟服务器。

虚拟服务器的体系结构如上图所示,一组服务器通过高速的局域网或者地理分布的广域网相互连接,在它们的前端有一个负载调度器(Load Balancer)。负载调度器能无缝地将网络请求调度到真实服务器上,从而使得服务器集群的结构对客户是透明的,客户访问集群系统提供的网络服务就像访问一台高性能、高可用的服务器一样。客户程序不受服务器集群的影响不需作任何修改。系统的伸缩性通过在服务机群中透明地加入和删除一个节点来达到,通过检 测节点或服务进程故障和正确地重置系统达到高可用性。由于我们的负载调度技术是在 Linux 内核中实现的,我们称之为 Linux 虚拟服务器(LVS,Linux Virtual Server)。

Linux Virtual Server 项目的目标 :使用集群技术和 Linux 操作系统实现一个高性能、高可用的服务器,它具有很好的可伸缩性(Scalability)、可靠性(Reliability)和可管理性(Manageability)。

简单的说,LVS 就是一个四层(传输层)负载均衡器,支持 TCP/UDP 的负载均衡。LVS 由工作在用户态的 ipvsadm(LVS 的命令行工具)与工作在内核态的 ipvs(LVS 提供服务的内核模块)组成。用户通过 ipvsadm 添加规则,再由 ipvs 来实现功能,ipvs 工作在 iptables 的 input 链上。

LVS 应用结构

在这里插入图片描述

三层结构:负载调度器、服务器池、共享存储。

架构对象

  • VS:Virtual Server,也称为 Director,负载均衡服务器
  • RS:Real Server,真正的服务器,集群中各节点
  • VIP:Director 向外部提供服务的 IP
  • DIP:Director 向内部与 RS 通信的 IP
  • RIP:真实服务器的 IP
  • CIP:客户端的 IP

LVS 提供的三种模式

在调度器(Director)的实现技术中,IP 负载均衡技术是效率最高的。在已有的 IP 负载均衡技术中有通过网络地址转换(Network Address Translation)将一组服务器构成一个高性能的、高可用的虚拟服务器,我们称之为 VS/NAT 技术(Virtual Server via Network Address Translation),大多数商品化的 IP 负载均衡调度器产品都是使用此方法,如 Cisco 的 LocalDirector、F5 的 Big/IP 和 Alteon 的 ACEDirector。在分析 VS/NAT 的缺点和网络服务的非对称性的基础上,我们提出通过 IP 隧道实现虚拟服务器的方法 VS/TUN (Virtual Server via IP Tunneling),和通过直接路由实现虚拟服务器的方法 VS/DR(Virtual Server via Direct Routing),它们可以极大地提高系统的伸缩性。所以,IPVS 软件实现了这三种IP负载均衡技术,它们的大致原理如下(我们将在其他章节对其工作原 理进行详细描述)。

LVS-NAT

Virtual Server via Network Address Translation(VS/NAT,网络地址转换):通过网络地址转换(NAT),调度器重写请求三层 IP 数据包的目标地址,根据预设的调度算法,将请求分派给后端的真实服务器;真实服务器的响应报文通过调度器时,IP 数据包的源地址被重写,再返回给客户,完成整个负载调度过程。

在这里插入图片描述

详细流程

在这里插入图片描述

特性

  1. RS 的网关必须指向 DIP
  2. 依赖 Director 的路由转发功能,将 CIP、CPort 转换为 RIP、RPort
  3. Director 会成为系统的瓶颈所在

缺点:扩展性有限。当 RS 增长过多时,Director 将成为瓶颈,因为所有请求包和响应包都要经过 Director。

LVS-TUN

Virtual Server via IP Tunneling(VS/TUN,IP 隧道):采用 NAT 技术时,由于请求和响应报文都必须经过调度器地址重写,当客户请求越来越多时,调度器的处理能力将成为瓶颈。为了解决这个问题,调度器把请求报文通过 IP 隧道转发至真实服务器,而真实服务器将响应直接返回给客户,所以调度器只处理请求报文。由于一般网络服务应答比请求报文大许多,采用 VS/TUN 技术后,集群系统的最大吞吐量可以提高 10 倍。

在这里插入图片描述

原理:客户端到真实服务器的 IP 数据包总会经过 Director,经过 Director 时就会进行 NAT(ip, port)映射处理。

详细流程

在这里插入图片描述

特性

  1. RIP、DIP、VIP 必须为 Internet IP(公网)
  2. RS 网关不指向 Director
  3. 请求数据报文由 Director 转发至 RS,响应数据报文由 RS 直接发送至客户端
  4. 不支持端口映射
  5. RS 的 OS 必须支持隧道技术
  6. Director 与 RS、RS 与 RS 可以跨网段、跨机房
  7. 一般用于外网环境

缺点:隧道模式的 RS 需要合法 IP,这种方式需要所有的服务器都支持 “IP Tunneling” 协议,所以操作系统类型可能只局限在部分 Linux 上。

LVS_DR

Virtual Server via Direct Routing(VS/DR,直接路由):通过改写三层请求 IP 数据包的 MAC 地址,将请求发送到真实服务器,而真实服务器将响应直接返回给客户。同 VS/TUN 技术一样,VS/DR 技术可极大地提高集群系统的伸缩性。这种方法没有 IP 隧道的开销,对集群中的真实服务器也没有必须支持 IP 隧道协议的要求,但是要求调度器与真实服务器都有一块网卡连在同一物理网段上。

在这里插入图片描述

原理:所有 RS 都具有与 Director 上的 VIP 相同的 IP,一般配置到 lo 的子网卡设备上(RS 还会具有属于自己的真实 IP)。并且当客户端发出 IP 数据包时,所有的 RS 会抑制 lo 响应 ARP 请求,保证只有 Director 会接收到 IP 数据包,并且通过 Director 修改数据报文的二层数据帧的 MAC 地址指向一个根据特定的负载均衡算法调度的真实服务器。最后由该真实服务器直接响应到客户端(因为真实服务器同样具有 VIP 地址,所以源 IP 地址依旧是 VIP)。

详细流程

在这里插入图片描述

特性

  1. 必须保证前端路由通过 ARP 地址解析将数据包转发至 Director,数据报文不能直接被 RS 接收
  2. RS 可以使用私网 IP,也可以使用公网 IP
  3. Director 只负责调度
  4. Director 与 RS 必须在同一物理网段中,因为 Director 到 RS 是通过二层网络完成的
  5. 不支持端口映射
  6. RS 的网关为前端路由,不能为 Director
  7. RS 支持大多出 OS(可以拒绝 ARP 报文请求的操作系统)

缺点:Director 与 RS 必须在同一物理网段中

LVS 负载均衡算法

静态负载均衡

  • rr(round robin,轮询 ):把每次来自客户端的请求轮流分配到后端真实服务器。它无需记录当前所有连接的状态,是一种无状态调度。但也不会考虑每台服务器的处理能力。

  • wrr(weight round robin,加权轮询):由于每台服务器的配置、安装的业务应用等不同,其处理能力会不一样。所以,根据服务器的不同处理能力,给每个服务器分配不同的权值,使其能够接受相应权值数的服务请求。

  • sh(source hashing,源地址 HASH):实现会话绑定 session affinity,将同一客户端的请求发给同一个真实服务器,源地址散列调度算法正好与目标地址散列调度算法相反,它根据请求的源 IP 地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的并且没有超负荷,将请求发送到该服务器,否则返回空。它采用的散列函数与目标地址散列调度算法的相同。它的算法流程与目标地址散列调度算法的基本相似,除了将请求的目标IP地址换成请求的源 IP 地址。

  • dh(destination hashing,目标地址 HASH):将同样的请求发送给同一个后端服务器,一般用于缓存服务器。简单的说,LB 集群后面又加了一层,在 LB 与真实服务器之间加了一层缓存服务器,通过这种方式来提高缓存的命中率。目标地址散列调度算法也是针对目标 IP 地址的负载均衡,它是一种静态映射算法,通过一个散列函数将一个目标 IP 地址映射到一台服务器。目标地址散列调度算法先根据请求的目标 IP 地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且未超载,将请求发送到该服务器,否则返回空。

动态负载均衡

  • lc(leash-connection,最少连接 ):最少连接调度算法是把新的连接请求分配到当前连接数最小的服务器。最小连接调度是一种动态调度短算法,它通过服务器当前所活跃的连接数来估计服务器的负载均衡,调度器需要记录各个服务器已建立连接的数目,当一个请求被调度到某台服务器,其连接数加 1,当连接中止或超时,其连接数减 1。当服务器的权值为 0 时,表示该服务器不可用而不被调度。

    • 简单算法:active * 256 + inactive (谁的小选谁)
  • wlc(加权最少连接):lc 算法忽略了服务器的性能问题,有的服务器性能好,有的服务器性能差。通过加权重可以区分性能,各个服务器用相应的权值表示其处理性能。服务器的缺省权值为 1,可以动态地设置服务器的权限,加权最小连接调度在调度新连接时尽可能使服务器的已建立连接数和其权值成比例。由于服务器的性能不同,给性能相对好的服务器,加大权重,即会接收到更多的请求。

    • 简单算法:(active * 256 + inactive) / weight(谁的小选谁)
  • sed(最少期望延迟):不考虑非活动连接,谁的权重大,我们优先选择权重大的服务器来接收请求,但会出现问题,就是权重比较大的服务器会很忙,但权重相对较小的服务器很闲,甚至会接收不到请求,所以便有了下面的算法 nq。

    • 简单算法:(active + 1) * 256 / weight (谁的小选谁)
  • nq(never queue,永不排队):是 sed 的改进,不管权重多大都会被分配到请求。如果真实服务器的连接数为 0 就直接分配过去,不需要再进行 sed 运算。

  • LBLC(基于局部性的最少连接 ):针对请求报文目标 IP 地址的负载均衡调度,主要用于 Cache 集群系统,因为 Cache 集群中客户请求报文的目标 IP 地址是变化的,这里假设任何后端服务器都可以处理任何请求,算法的设计目标在服务器的负载基本平衡的情况下,将相同的目标 IP 地址的请求调度到同一个台服务器,来提高服务器的访问局部性和主存 Cache 命中率,从而调整整个集群系统的处理能力。

  • LBLCR(基于局部性的带复制功能的最少连接):针对目标 IP 地址的负载均衡,该算法根据请求的目标 IP 地址找出该目标 IP 地址对应的服务器组,按 “最小连接” 原则从服务器组中选出一台服务器,若服务器没有超载,将请求发送到该服务器;若服务器超载,则按 “最小连接” 原则从这个集群中选出一台服务器,将该服务器加入到服务器组中,将请求发送到该服务器。同时,当该服务器组有一段时间没有被修改,将最忙的服务器从服务器组中删除,以降低复制的程度。

LVS-ipvsadm 指令集

查看

查看帮助手册

ipvsadm --help

查看 LVS 规则

$ ipvsadm -Ln

IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
UDP  10.0.0.9:5678 rr
  -> 192.168.1.8:5678             Masq    1      0          0

添加

  • 添加集群服务
$ ipvsadm -A -t 192.168.1.100:80 -s rr
  • 添加真实服务器到集群服务
ipvsadm -a -t 192.168.1.100:80 -r 172.16.16.2:80 -m -w 1

修改

  • 修改集群服务
ipvsadm -E -t 192.168.1.100:80 -s wlc
  • 修改集群服务中的真实服务器
ipvsadm -e -t 192.168.1.100:80 -r 172.16.16.2:80 -m -w 2

删除

  • 删除集群服务
ipvsadm -D -t 192.168.1.100:80
  • 删除集群服务中的一个真实服务器
ipvsadm -d -t 192.168.1.100:80 -r 172.16.16.2:80
  • 删除所有集群服务
ipvsadm -C

参考文章

http://www.linuxvirtualserver.org/zh/lvs1.html
https://blog.csdn.net/dog250/article/details/17061277
https://cloud.tencent.com/developer/article/1004555
https://blog.csdn.net/john_f_lau/article/details/50961914
https://blog.csdn.net/Jmilk/article/details/79972281
https://blog.csdn.net/py_shell/article/details/53067847#commentBox