什么是负载均衡

负载均衡,英文名称为Load Balance,其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,例如FTP服务器、Web服务器、企业核心应用服务器和其它主要任务服务器等,从而协同完成工作任务。

负载均衡的作用

对多台服务器进行流量分发的服务。负载均衡可以通过流量分发扩展应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。

  1. 提高可用性和访问速度
    在单个可用区或多个可用区内的多个目标之间自动分配流量。
  2. 运行状况检查
    检测无法正常运行的目标、停止向它们发送流量,然后将负载分散到剩余的正常运行的目标上。
  3. 安全性功能
    创建和管理与负载均衡器关联的安全组,以提供更多联网和安全选项。
  4. TLS 终止
    提供集成化证书管理和 SSL/TLS 解密,可以灵活地集中管理负载均衡器的 SSL 设置,并从应用程序上卸载 CPU 密集型工作。

负载均衡分类

  1. 软负载均衡
    • 软件实现负载均衡
  2. 硬负载均衡
    • 硬件设备
  3. 四层/七层负载均衡
    • 二层的就是基于MAC地址,二层负载均衡会通过一个虚拟MAC地址接受请求,然后再分配到真实的MAC地址。
    • 三层负载就是通过一个虚拟IP地址,然后再分配到真实的IP。
    • 四层就是通过虚机的IP+端口接收请求,然后再分配到真实的服务器;
    • 七层就是通过虚机主机名或者URL接收请求,再根据一些规则分配到真实的服务器,常见的应用是nginx。
  4. ALB:Application Load Balancer 运行于请求级别(第 7 层),可根据请求的内容将流量路由至 EC2 实例、容器、IP 地址和 Lambda 函数等目标。Application Load Balancer 最适合 HTTP 和 HTTPS 流量的高级负载均衡,面向交付包括微服务和基于容器的应用程序在内的现代应用程序架构,提供高级请求路由功能。Application Load Balancer 通过确保始终使用最新的 SSL/TLS 密码和协议,简化并提高应用程序的安全性。
  5. NLB:Network Load Balancer 网络负载均衡器运行于连接级别(第 4 层),可根据 IP 协议数据将连接路由至 Amazon Virtual Private Cloud (Amazon VPC) 内的不同目标(Amazon EC2 实例、微服务和容器)。网络负载均衡器最适合 TCP 流量的负载均衡,能够在保持超低延迟的同时每秒处理数百万个请求。网络负载均衡器还经过了优化,能够处理突发的和不稳定的流量模式,同时在每个可用区使用单个静态 IP 地址。它与其他流行的 AWS 服务集成,例如 Auto Scaling、Amazon EC2 Container Service (ECS)、Amazon CloudFormation 和 Amazon AWS Certificate Manager (ACM)。

负载均衡算法

1、轮询法

将请求按顺序轮流地分配到后端服务器上,它均衡地对待后端的每一台服务器,而不关心服务器实际的连接数和当前的系统负载。

2、随机法

​ 通过系统的随机算法,根据后端服务器的列表大小值来随机选取其中的一台服务器进行访问。由概率统计理论可以得知,随着客户端调用服务端的次数增多,其实际效果越来越接近于平均分配调用量到后端的每一台服务器,也就是轮询的结果。

3、源地址哈希法

​ 源地址哈希的思想是根据获取客户端的IP地址,通过哈希函数计算得到的一个数值,用该数值对服务器列表的大小进行取模运算,得到的结果便是客服端要访问服务器的序号。采用源地址哈希法进行负载均衡,同一IP地址的客户端,当后端服务器列表不变时,它每次都会映射到同一台后端服务器进行访问。

4、加权轮询法

不同的后端服务器可能机器的配置和当前系统的负载并不相同,因此它们的抗压能力也不相同。给配置高、负载低的机器配置更高的权重,让其处理更多的请;而配置低、负载高的机器,给其分配较低的权重,降低其系统负载,加权轮询能很好地处理这一问题,并将请求顺序且按照权重分配到后端。

5、加权随机法

​ 与加权轮询法一样,加权随机法也根据后端机器的配置,系统的负载分配不同的权重。不同的是,它是按照权重随机请求后端服务器,而非顺序。

6、最小连接数法

​ 最小连接数算法比较灵活和智能,由于后端服务器的配置不尽相同,对于请求的处理有快有慢,它是根据后端服务器当前的连接情况,动态地选取其中当前积压连接数最少的一台服务器来处理当前的请求,尽可能地提高后端服务的利用效率,将负责合理地分流到每一台服务器。

常用负载均衡比较

比较 HAProxy Nginx LVS
优点 支持session保持,Cookie引导。 可通过url检测后端服务器健康状态。 也可做MySQL、Email等负载均衡。 支持通过指定的URL对后端服务器健康检查。 http、https、Emai协议功能较好,处理相应请求快。 Web能力强,配置简单,支持缓存功能、适用动静分离,低内存消耗。 支持WebSocket协议支持强大的正则匹配规则 通过vrrp转发(仅分发)效率高,流量通过内核处理,没有流量产生。(理论) 相当稳定可靠
缺点 一般不做Web服务器的Cache。 不支持session直接保持,但可通过ip_hash解决。只能通过端口对后端服务器健康检查。 不支持正则,不能做动静分离,配置略复杂,需要IP略多。没有后端主机健康状态检查。
支持算法 目标uri hash(uri)url参数 (url_params)请求头信息调度(hdr(name))cookie (rdp-cookie) 最小响应时间**自定义hash内容(hash key [consistent])**url hash最短时间和最少连接 最短期望延迟(Shortest Expected Delay)不排队(Never Queue)基于局部性的最少连接(LBLC)带复制的基于局部性最少链接(LCLBR)
官网 www.haproxy.com nginx.org www.linuxvirtualserver.org
虚拟主机 支持 支持 不支持
适用性 四层,七层(常用) 四层,七层(常用) 四层
量级 七层重量级,四层轻量级 七层重量级,四层轻量级 四层重量级
常用热备 Keepalived+其它 Keepalived+其它 Keepalived+其它

OpenStack负载均衡

Lbaas V1与V2的区别如下:

功能 lbaas lbaasV2
最大连接数 Y Y
TCP负载均衡 Y Y
HTTP负载均衡 Y Y
HTTPS负载均衡 Y Y
TERMINATED_HTTPS负载均衡 X Y
基于hostname的url转发 X Y
基于path的url转发 X Y
基于filename的url转发 X Y
基于header的url转发 X Y
基于cookie的url转发 X Y
一个vip支持多种协议和端口 X Y

Octavia

Octavia当前作为OpenStack LbaasV2的一个driver存在,完全兼容lbaasV2的接口,最终的发展趋势会作为一个独立的项目代替lbaasV2。

根据官网的信息,Octavia brings network load balancing to OpenStack.,Octavia是一个NLB的负载均衡。

基本概念

Octavia就是将用户的API请求经过逻辑处理,转换成Haproxy或者Nginx的配置参数,下发到amphora虚机中。

Octavia的内部实现中,逻辑流程的处理主要使用TaskFlow库。

  • LBaas

Load Balancing as a Service,在openstack平台上,LB被作为一种服务提供给用户,用户可以按需获取可配置的业务负载分担方案。

  • loadbalancer

负载均衡服务的跟对象,一般为虚机,用户基于此对负载均衡进行配置和操作。

  • VIP

与LB关联的IP地址,作为外部访问后端服务的入口。

  • Listener

监听器,用户可通过其配置外部对VIP访问的端口,算法,类型等等。

  • Pool

负责后端的虚拟机池。在Haproxy为driver的情况下,一个Pool对应着一个独立的network namespace中运行的HaProxy进程中管理的backend。

一个VIP只会有一个Pool。

  • Member

Member 对应的是 pool 里面处理网络请求的一个 OpenStack Nova 虚机。

  • Health monitor

它用来检测pool里面的member的状态,支持很多种检测方法,在neutron里面是可选的。

  • L7 Policy

七层转发策略,描述数据包转发动作。

  • L7 Rule

七层转发规则,描述数据包转发的匹配域。(匹配部分云主机)

forward.png

架构模型

Octavia组件概述

网络模型

network.png

  • Amphora

负载均衡的载体,一般为云主机。(当然也可以使用物理机,将多个负载均衡配置到同一/两台Amphora节点上,提高数据包转发效率,但是有单点故障隐患

  • manage-network

管理网络,通常管理数据走这条线路,东侧连接Amphora西侧连接Octavia服务进程

  • tenant-network

租户网络,内部通信使用,SLB转发报文通过租户网络到各个后端服务器上。

  • vip-network

服务地址,主要用于对外提供服务

PS:vip-net和tenant-net可以是同一个网络,但是在生产环境中建议分开,以便于更好得划分网络安全隔离

  • VM

后端服务器,用户的真实服务器。

  • health-manager

octavia里面进行健康检查的进程,主要有以下两个作用:

  1. 监听来自amphora虚拟机发来的运行状态数据,以此更新lb,listener,pool,member的状态,同时更新listener_statistics表(可作为计费依据),最重要的是更新amphora_health表。

  2. 根据amphora_health数据表中的数据,找到异常状态的amphora虚拟机,对该虚拟机进行更换操作。(即删除旧的虚拟机,创建新的虚拟机并下发配置)

  • house-keeping

名副其实的 Housekeeping(家政)服务,保障 Octavia 的健康运行。

主要实现三个功能:

  1. SpareAmphora: 清理虚拟机的池子, 确保空闲的amphorae池大小。

  2. DatabaseCleanup: 定期清理数据库中已删除的amphorae记录。

  3. CertRotation: 定期更新amphorae中的证书

  • Octavia Worker

负责完成 API 请求,是 Octavia 主干功能的执行者

主要作用是和nova,neutron等组件通信,用于虚拟机调度以及把对于虚拟机操作的指令下发给octavia agent。

请求流程

request.png

具体实现

1. 创建负载均衡

通过页面创建负载均衡

2. 查看LB详情

1
openstack loadbalancer show {lbId}

image-20210302181609960

通过查看详情,知道provideramphora;

创建时选择的vpc信息最终生成的ip是一个VIP

3. 查看service项目下的vm信息

负载均衡的虚拟机

然后查看service项目下的虚拟机信息,发现有多个:

image-20210302182010345

这些虚拟机中,最主要的服务就是:haproxy、octavia-keepalived和amphora-agent服务

  • haproxy、octavia-keepalived:通过这两个服务实现负载均衡;

  • amphora-agent:提供Octavia API,并且定时向health-monitor发送haproxy的运行时信息,该信息是通过向haproxy进程发送socket查询命令获取到;

存在多个amphora云主机是因为开启了集群模式,可以通过查看octavia-api/etc/octavia/octavia.conf配置文件内容来确认。

  1. SINGLE:单机

  2. ACTIVE_STANDBY :高可用模式(主备模式)

image-20210302183609566

同时可以看到,每个amphora云主机都使用了两个网络,一个是lb-mgmt-net,一个是租户网络(创建负载均衡的时候选择的VPC,也是云主机所在的VPC),同时Octavia每创建一个 loadbalancer,都会创建包含同样 policy 的 server group(反亲和组),没有所属租户,用户可见。

即:创建 loadbalancer 的租户只能看到这个 loadbalancer 的信息以及 loadbalancer 所占用的 port(VIP的port)信息,背后的VM、VM的port、SecurityGroup、ServerGroup 都是不可见的。一个 lb 的创建会占用租户 subnet 内的 ip 资源和 port 配额(一般会在 subnet 中创建3个 port)。

image-20210303152421902

可以看到,这个反亲和组中,默认就添加了amphora的两台机器:

image-20210303152448987

在 octavia 中,资源之间的映射关系如下:

  • lb:就是两个管理员租户的虚拟机
  • listener:虚拟机里面的一个 haproxy 进程,frontend 配置
  • pool:haproxy 配置中的一个 backend
  • member:backend 配置中的一个 member

负载均衡的listener

创建listener其实就是启动haproxy服务,大致分为如下步骤:

  1. 将haproxy的配置文件传到amphora虚拟机中;
  2. 根据虚拟机信息,进行配置修改;
  3. amphora-agent调用haproxy -c -L {peer} -f {config_file} -f {haproxy_ug}校验配置文件;
  4. 验证无误之后,生成对应该listener的haproxy服务脚本;
  5. 通过amphora-agent启动amphora虚拟机中haproxy服务;
    1. 先确定listener的配置目录(/var/lib/octavia/{listener-id}/)在不在
    2. 如果是active standby,更新keepalived对各个haproxy的check脚本,/var/lib/octavia/vrrp/check_scripts/haproxy_check_script.sh
    3. 启动haproxy服务,service haproxy-{listener_id} start

pool

创建pool的实现基本跟创建listener一致,在amphora中仅仅是在 haproxy 的配置文件增加backend配置;

添加members

添加members需要保证网络可达,在OpenStack中,只能选同一子网的云主机,所以网络是连通的;

octavia已经支持直接指定IP地址添加membe,而不跟虚拟机绑定,前提是用户自己需要保证amphora能够与这个IP地址通信。这种情况最好能在pool上添加 health_monitor 来保证 member 的可用性,这样如果ip地址不可达时,lb也不会将消息路由给它。(OpenStack是在同一子网,可以不开启健康检查)

因为与member通信的 port 都在namespace中,所以管理 IP 段就可以与租户的网络重叠。

4. 负载均衡实现方式验证

此时,可以通过查看service项目下的虚拟机,来验证Octavia的相关配置是否如预期:

ssh到service项目下两台虚拟机其中的一台,使用lb-mgmt-net网络

1
2
3
ssh {lb-mgmt-net}
ps -ef |grep keepalived;
cat /var/lib/octavia/vrrp/octavia-keepalived.conf

然后会看到具体的配置,总体来说octavia的高可用是通过haproxy+keepalived来完成的。

5. 验证负载均衡

1
2
3
4
5
6
7
8
9
10
openstack loadbalancer show {lbId}  ## 得到vip_network_id
## 然后根据这个id,查询对应的路由信息
## 最终得到路由的id
## 也可以直接通过页面拿到对应的路由的ID
## 执行ip netns 得到对应的网络
ip netns | grep {routerId}
## 执行一下ping,是否可以连通
ip netns exec qrouter-{routerId} ping {lbVip}
## 根据负载均衡选择的监听方式进行验证,此处负载均衡是监听的22端口,进行ssh验证
ip netns exec qrouter-{routerId} ssh {lbVip}

负载均衡的监听器,监听的是22端口:

image-20210303141525891

查看22pool资源池,映射的也是22端口:

image-20210303141623791

然后进行ping的验证:

image-20210303140307409

ssh验证:

image-20210303140336380

输入密码登录之后,通过ip a查看网卡信息,可以看到此时连到了负载均衡下面资源池中的一台云主机。

参考: https://lingxiankong.github.io/2017-09-13-octavia.html