1.1 初步介绍

负载均衡(Load balancing)是运维工程师必须要掌握的一项技术,因为其应用广泛且往往位于业务的核心位置。广义上的负载均衡是指将一组任务分配到一组资源(计算单元)上的过程。在运维领域里,则基本上是和WEB类型的业务打交道,即主要处理TCP、HTTP、HTTPS等协议。

负载均衡一般位于网站(或服务)的入口处,接受进来的流量,然后按照指定的分配算法,分配到后端的一组服务器上。从这点上看,负载均衡有点像是一个外包公司的领导,从外部客户接到很多的任务,但是领导自己不会处理这些任务,而是直接将其分配给不同的下属。下属完成后交付给领导,领导再交付给客户,从而高效地完成工作。

这里的“领导”有几个特征:

  1. 领导在这里只是起到一个分配任务、传输任务的功能,而不需要实际去处理任务,所以领导花在每个任务上的时间上是很少的,进而可以在短时间内接收和传输很多任务。这对应着负载均衡的高性能特征。
  2. 领导需要时刻知晓下属的工作状态,即下属如果有请假或离职等原因而无法处理任务,领导会将该下属标记为下线,以后的任务就不会交给该下属。这对应负载均衡的健康监测功能。
  3. 客户提交的任务和下属完成的任务都会经过领导,即理论上领导是可以查看所有的数据的。这给了负载均衡器处理应层数据的能力。
  4. 领导如何高效率地将任务分配给下属。这里就涉及到负载均衡的算法了。 当然了,这只是负载均衡的部分特征。

我们一般所说的负载均衡通常被分为两种: 四层(Layer 4)和七层(Layer 7),这里的四层、七层是对应OSI里的四、七层的概念。所以想要理解负载均衡,需要对OSI七层模型有所了解。

下表为OSI七层和TCP/IP四层网络模型: tcp/ip-layer

OSI模型是一个电信或通信系统间互联的标准体系,被划分为七层(由上往下,物理层为第一层)。它仅仅是一个模型,并没有被实际实现过,但有着巨大的参考价值。而TCP/IP模型被划分为四层,是我们今天实际在使用的。两个模型在此不做细述。

OSI四层被定义为传输层,所以四层负载均衡能处理传输层协议,那么位于传输层的TCP、UDP协议就属于四层负载均衡所能处理的协议。

七层是应用层,位于OSI的最上层,因而是可以同时具备四层和七层负载均衡能力的,既可以处理HTTP、HTTPS这些协议,也可以处理TCP、UDP协议。

那如果我业务使用的HTTP,是不是就不能够使用四层负载均衡了呢?当然不是,四层负载均衡的意思是它能够解封装出TCP头部信息,即能识别出TCP协议,而HTTP协议在四层之上,四层负载均衡是不会去解封装HTTP头部信息的。不过HTTP也是基于TCP进行传输的,所以对TCP做负载均衡也就是对HTTP做负载均衡了,只不过四层负载均衡不知道是否是HTTP,我们知道罢了。

不同的负载均衡器可能支持的调度算法不同,下面是用的比较多的几种调度算法:

  • 轮询(Round robin):会按照1:1的比例向后端服务器分发请求
  • 加权轮询(Weighted round robin):如果有性能较好的服务器,可以给它比较高的权重值,多分担请求
  • 最少连接数(Least connections):是把新的连接请求分配到当前连接数最小的服务器
  • 源地址散列(Source Hashing):根据请求的源IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器

实际应用中应该根据具体的使用场景,选择适合我们自己的算法。

下面介绍几款与负载均衡技术相关的软件产品:LVS、Nginx、HAProxy。

1.2 LVS

1.2.1 LVS介绍 LVS全称为Linux Virtual Server,即Linux虚拟服务器,创始人为国人章文嵩,在1998年编写出来后便将其开源,逐渐被越来越多地采用。现在是Linux内核的一部分,可以说是经久不衰。

根据章文嵩写的LVS的相关论文,LVS的出现是为了解决服务高性能、高可用、易扩展等这些问题的,但其实LVS本身是不支持高可用的(因为不对后端服务器进行健康监测),需要使用其他工具实现。

1.2.2 关于高可用 想要实现服务高可用,那么用一台服务器来部署LVS是做不到的,因为如果这台服务器宕机的话,服务就会中断。所以通常至少要用两台服务器部署LVS,一主一备,主备之间使用一个VIP(虚拟IP)作为请求入口。VIP被某些管理软件(如下面讲到的keepalived)负责设置在主服务器上,对外提供服务。而当主服务器意外宕机时,管理软件会将VIP设置到备服务器上,继续对外提供服务。

1.2.3 工作原理 LVS工作于传输层,所以属于四层负载均衡器。由于工作在四层,所以可以支撑很大的流量,常用来当做流量的入口。

LVS工作原理: 用户请求到达LVS(术语为director)后,LVS根据设置的算法,将请求转发给后端真实服务器(术语为Real Server),后端服务器接收到请求,返回给用户。 即这样的: 用户请求 –> LVS(director) –> Real Server

那么当请求的数据包达到LVS(director)后,此时IP包的目的地址、目的端口是LVS上的VIP地址和端口,那么如何转发给选出的Real Server,以及Realserver收到后如何处理请求、如何返回数据呢?这里便要说说LVS的三种工作模式了。

1.2.3.1 NAT模式 可能大家比较熟悉NAT,全称为Network address translation,即网络地址转换。这项技术的出现是为了缓解IPv4地址短缺的问题,比如它能使内网地址转为公网地址,进而可以在公网传输数据。

此模式下,处理流程为:

  1. 用户请求达到LVS
  2. LVS会根据算法选择一台Real Server,然后将数据包的目的地址和目的端口修改为Real Server的IP地址和规则中指定的端口,再进行转发
  3. Real Server收到数据包后,检查目的IP,发现可以处理后,则发送到相应端口进行处理
  4. 数据返回的时候必须要经过LVS,LVS将地址再转换回来,这样才能顺利的把数据交给用户
                                      ________
                                     |        |     ## dst   ip: 192.168.1.200
                                     | client |     ## dst port: 80
                                     |________|     ## src   ip: 192.168.1.100
                                 CIP=192.168.1.100  ## src port: 1234
                                       | | 
                                       v | ^
                                         | |
                                         |
                                VIP=192.168.1.200 (eth0:1)
                                    __________  
                                   |          |      ## 重写目的地址为选出的realserverIP和端口
                                   |    LVS   |      ## dst   ip: 10.1.1.2  
                                   |__________|      ## dst port: 80
                                IP=10.1.1.9 (eth1)   ## src   ip: 192.168.1.100
                                         |           ## src port: 1234
                                       | |           ## 记录并转发,数据返回时再重写回去
                                       | | ^          
                                       v | |
                                         |
                        -----------------------------------
                        |                |                |
                        |                |                |
                 RIP1=10.1.1.2      RIP2=10.1.1.3   RIP3=10.1.1.4 (eth0)
                 _____________     _____________    _____________
                |             |   |             |  |             |
                | realserver  |   | realserver  |  | realserver  |
                |_____________|   |_____________|  |_____________|

图1.2-1 NAT模式

此模式会多做两次地址转换的操作,且数据返回经过LVS,严了重影响LVS的性能。 又因为数据返回需要经过LVS,所以LVS本身又得是realserver的网关。

1.2.3.2 DR(Direct Routing)模式

此模式下的处理流程:

  1. 用户请求达到LVS
  2. LVS通过调度算法从集群中选择一台Real Server,修改目的MAC地址为Real Server的MAC地址,然后转发
  3. Real Server收到转发的数据包时,发现该数据包的目的IP本机可达(loopback口上绑定的VIP),于是对请求进行处理,最后将结果直接返回给用户,不经过LVS

DR模式由于只需要LVS修改包的二层MAC地址,并且数据返回不经过LVS,所以处理速度是三种模式中最快的,但也限制了LVS和Real Server需要在同一网段,且需要在Real Server上对网卡做ARP抑制操作,因为realserver本机需要绑定VIP,且只能本地可达。

                                              ________
                                             | client |
                                             |________|
                                          CIP=192.168.1.100
                                                 |
                                      CIP->VIP | |
                                               v | ^
                                                 | |
                                              ________
                                             | router |------------- 
                                             |________|             | 
                                               | |                  |
                                               v |                  |
                                                 |                  |
                                       VIP=192.168.2.100 (eth0:1)   |
                                             __________             |
                                            |   LVS    |            |
                                            |__________|            |
                                        IP=192.168.2.101 (eth0)     | 
                                                 |                  |  ^             
                               change dst MAC  | |                  |  | VIP->CIP 
                                               | |                  |  | 192.168.2.100->192.168.1.100
                                               v |                  |
                                ------------------------------------|
                                |                |                  |
                                |                |                  |
                     RIP1=192.168.2.102  RIP2=192.168.2.103  RIP3=192.168.2.104 (eth0)
                      VIP=192.168.2.100   VIP=192.168.2.100   VIP=192.168.2.100 (lo:0)
                        ______________     _____________      _____________
                       | realserver   |   | realserver  |    | realserver  |
                       |______________|   |_____________|    |_____________|

图-1.2-2 DR模式

1.2.3.3 IP tunneling(IP隧道)模式

IP隧道可理解为一种封装技术,可以将收到的IP数据包封装在新的IP数据包内。

处理流程:

  1. 用户请求达到LVS
  2. LVS将请求的数据包再次进行封装,即在原有的IP层上添加新的IP层,新的IP包头的源地址为LVS,目的地址为realserver的IP,然后转发到所选的Real Server
  3. 当Real Server的tunl0网卡(由ipip内核模块加载后创建)收到封装后的数据包后,会对数据包进行解封装,也就是去掉新加的IP层,所以能够查看到原始的IP层,然后对请求进行处理,最后根据自己的路由表将结果直接返回给用户,返回的数据不经过LVS
                                      ________
                                     | client |
                                     |________|
                                 CIP=192.168.1.100
                                         |
                                    |    |
                                    v    |                                             
                                     __________ 
                CIP->VIP            | router 1 |-------------------
      192.168.1.100->192.168.2.100  |__________|                   |
                                         |                         |
                                    |    |                         |
                                    v    |                         |
                               VIP=192.168.2.100 (eth0:1)          |
                                     __________                    |
                                    | Director |                   |
                                    |__________|                   |
                               DIP=192.168.2.101 (eth0)            |
                                         |                         |  ^
                DIP->RIP1            |   |                         |  |       VIP->CIP 
               (CIP->VIP(tunl0))     v   |                         |192.168.2.100->192.168.1.100      
      192.168.2.101->192.168.2.102       |                         |
     (192.168.1.100->192.168.2.100)      |                         |
                                         |                         |
                        --------------------------------------------
                        |                           |
                        |                           |
                RIP1=192.168.2.102            RIP2=192.168.2.103(eth0)
                 VIP=192.168.2.100             VIP=192.168.2.100(tunl0)
                 ______________________         ___________________     
                | realserver           |       | realserver        |
                | eth0:  VIP->CIP(out) |       |                   |
                | tunl0: CIP->VIP(in)  |       |                   | 
                |______________________|       |___________________|

图-1.2-3 TUN模式

数据的原始目的地址是LVS的IP,转发给Real Server时没有改变,只是新加了一层IP层,Real Server解封装后依然可以处理,这是因为tunl0网卡上绑定了VIP,并且只有本机可达。

IP隧道模式的性能比NAT要好,比DR模式性能要差,但是相比DR模式,IP隧道模式可以跨网段部署。

1.2.4 管理LVS 说完三种模式,下面说说LVS的管理工具。怎么使用LVS呢,LVS的管理通过ipvsadm这个工具来设置,CentOS系统可以直接使用yum install ipvsadm安装,Ubuntu使用sudo apt install ipvsadm安装。比如下面的命令,就是添加相应LVS规则。

ipvsadm -A -t 172.26.20.10:80 -s rr
新增虚拟服务器172.26.20.10(通常就是VIP),端口是80,调度算法是轮询
ipvsadm -a -t 172.26.20.10:80 -r 172.26.20.11:80 -g
新增一台Real Server,IP为172.26.20.11,端口80,-g参数表示模式为DR模式

不过使用ipvsadm直接管理是比较不方便的,keepalived为我们提高了更好的选择。 keepalived是一款路由软件,提供负载均衡和高可用性,可以说就是为配置LVS而生的。Keepalived根据负载均衡服务器池的健康状况,动态地、自适应地维护和管理它们,是通常情况下推荐管理LVS的方式。

比如下面keepalived配置和上面ipvsadm命令管理的效果是一样的,并且对realserver增加了健康监测。

virtual_server 172.26.20.10 80 {
    lb_algo rr
    lb_kind DR
    nat_mask 255.255.255.255
    protocol TCP

    real_server 172.26.20.11 80 {
        TCP_CHECK {
           connect_timeout 6
           nb_get_retry 3
       }
    }
}

关于章文嵩的LVS的论文地址: http://www.linuxvirtualserver.org/ols/lvs.pdf ,有兴趣的话可以看一下。