Keepalived+HAProxy 搭建高可用负载均衡
1. 概述
软件负载均衡技术是指可以为多个后端服务器节点提供前端 IP 流量分发调度服务的软件技术。Keepalived 和 HAProxy 是众多软负载技术中的两种,其中 Keepalived 既可以实现负载均衡也可以实现高可用,而 HAProxy 则更加专注于提供高性能 TCP 和 HTTP 反向代理和负载均衡能力。
1.1 Keepalived
Keepalived 工作在 OSI 模型中的四层传输层。最初它是为了管理并监控 Linux 虚拟服务器(LVS)集群中各服务节点的状态,后来又加入了路由冗余协议(VRRP)来实现高可用功能,所以 Keepalived 除了可以管理配置 LVS 外,还可以作为 Nginx、HAProxy 等的高可用解决方案。
Keepalived 同时运行于主服务器(Master)和备服务器(Backup)之上,所有的服务器上运行的 Keepalived 之间通过 VRRP 交互,VRRP 设计目的是为了解决静态路由单点故障问题,保证个别节点宕机时,整个网络可以不间断的运行。
Keepalived 不但可以实现主备服务器的高可用性,同时还可以管理 LVS 实现后端服务器的负载均衡并进行后端服务器节点的健康检查。它启动核心进程时读取 keepalived.conf 配置文件。在主服务器上 keepalived 进程按照配置文件配置的负载均衡策略开启 LVS 转发并对后端服务进行健康检查。利用 VRRP 协议主服务器周期性的发送广播至备服务器,备服务器将会判断主器服务器的状态,如果在配置的同步超时时间内主服务器节点未能发出广播,那么 keepalived 将启动高可用切换机制选出新的主服务器。切换过程中,原有主服务器上的虚拟地址(VIP)及负载能力将由新的主服务器来接替承载。
1.2 HAProxy
HAProxy 是一款 TCP/HTTP 反向代理负载均衡服务器软件,可工作在 OSI 模型中的四层传输层以及七层应用层。HAProxy 特别适用于那些负载压力大的 web 站点,这些站点通常需要会话保持或七层处理。HAProxy 运行在时下的服务器上,可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全地整合进现有的系统架构中,同时可以保护 web 服务器不被暴露到网络上。HAproxy 允许用户定义多组服务代理,代理由前端和后端组成,前端定义了服务监听的 IP 及端口,后端则定义了一组服务器及负载均衡的算法。通过服务代理将流量由前端负载均衡至后端服务器节点上。
1.3 Keepalived 和 HAProxy 组合
由于 HAProxy 会存在单点故障问题,可以由 Keepalived 来为 HAProxy 提供高可用服务,而 HAProxy 提供四层或七层高性能负载均衡及反向代理服务,两者共同实现高可用负载均衡,结构如图 1 所示。
图 1 Keepalived+HAProxy
2. Keepalived 功能及安装配置
2.1 核心功能
1.管理 LVS 负载均衡软件
Keepalived 最初是专为解决 LVS 的问题而诞生的。因此,Keepalived 和 LVS 可紧密结合。
2.实现对 LVS 集群节点健康检查
当 LVS 集群中某个节点服务器发生故障时,Keepalived 服务会自动将失效的节点从正常队列中剔除,并将请求调度到别的正常的节点服务器上,从而保证用户访问不受影响。当故障节点被修复后,Keepalived 服务又会自动切换回来。
3.网络服务高可用功能
Keepalived 可以实现任意两台主机之间,如 Master 服务器和 Backup 服务器间的故障转移和自动切换。假设某个服务是不能停机的,如 LVS 负载均衡、Nginx 反向代理服务器等,可以利用 Keepalived 保证其高可用性。
2.2 高可用原理
Keepalived 高可用服务的故障切换转移是通过 VRRP 机制来实现的。在 Keepalived 服务正常运行时,Master 节点会不断向 Backup 节点发送(多播方式)心跳信息,用以通知 Master 节点的存活状态。当 Master 节点发生故障时,就无法发送心跳信息,Backup 节点也就无法检测到来自 Master 的心跳信息,于是调用自身的接管程序,接管 Master 的资源和服务。当 Master 恢复时,Backup 又会释放 Master 故障时自身接管的资源和服务,恢复到原来的备用角色。无论 Master 如何切换,对外都应该提供相同的服务 IP 地址,该 IP 也称作虚拟地址 VIP。客户端并不需要因 Master 的改变而修改自己的配置,对他们来说这种切换是透明的。
路由冗余协议 VRRP(Virtual Router Redundancy Protocol)早期是用来解决交换机、路由器等设备单点故障。VRRP 通过竞选机制来实现虚拟路由器的功能,所有的协议报文都是通过 IP 多播(Multicast)包形式来发送。在一组 VRRP 路由器集群中,有多台物理路由器,但并不是同时工作,而是由一台 Master 路由器负责路由工作,其他都是 Backup,Master 有一些特权,比如拥有 VIP 地址等,拥有系统资源的 Master 负责转发发送给网关地址的包和响应 ARP 请求。只有 Master 路由器会一直发送心跳信息,此时 Backup 不会抢占 Master。当 Master 不可用时,Backup 就收不到来自 Master 的心跳信息,此时多台 Backup 中优先级最高的路由器会抢占为 Master,这种抢占非常快速,以保证服务的连续性。
2.3 安装与配置
由于本文引用的技术构架中 Keepalived 将仅为 HAProxy 提供高可用服务,所以管理配置 LVS 负载均衡及节点健康检查功能将不准备展开篇幅,仅对高可用功能进行介绍演示。
2.3.1 安装
Keepalived 支持源码安装,同时也可以通过不同操作系统安装工具进行安装,本文以 CentOS 的 yum 工具为例进行安装介绍。此时应该准备两台服务器分别作为 Master 节点和 Backup 节点,分别在两台服务器上执行以下命令进行安装。
yum install -y keepalived
2.3.2 高可用配置
yum 安装后,Keepalived 将生成配置文件:/etc/keepalived/keepalived.conf,可利用文本编辑器进行配置修改。
vi /etc/keepalived/keepalived.conf
配置文件中主要由全局段、VRRP 实例段、脚本段组成。
1.全局段定义(global_defs)
全局段定义允许用户设置全局相关信息,例如通知信息、关键参数配置等,该段配置在 Master 节点和 Backup 节点上应当一致。
notification_email 定义报警邮件地址,当服务切换时发送报警邮件。notification_email_from 定义发件人信息,smtp_server 和 smtp_connect_timeout 分别定义了 SMTP 服务器及相应的连接超时时间,vrrp_mcast_group4 为 VRRP IPv4 多播地址,默认为 224.0.0.18,如果同一局域网内有多组 Keepalived 时需要指定不同多播地址。
2.VRRP 实例段定义(vrrp_instance)
这部分主要用来定义具体服务的实例配置,包括 Keepalived 主备状态、接口、优先级、认证方式和 VIP 信息等,每个 VRRP 实例可以认为是 Keepalived 服务的一个实例或作为一个业务服务,在一组 Keepalived 服务配置中,VRRP 实例可以有多个。
注意,存在于 Master 节点中的 VRRP 实例配置在 Backup 节点中也要有一致的配置(除了节点角色、优先级不同),这样才能实现故障切换转移。
vrrp_instance 配置段定义了一个 VRRP 实例并设定实例名称;
state 设定初始 VRRP 实例角色,配置先要为该实例所在的 Keepalived 服务器设定其角色,在 Master 服务器上设置为“MASTER”,在 Backup 服务器上则设置为“BACKUP”;
priority 优先级设定,范围 1-254,数字越大,表示实例优先级越高,在同一个 VRRP 实例里,Master 节点优先级要高于 Backup 节点;
virtual_router_id 虚拟路由 ID 标识,范围 0-255,Master 和 Backup 节点配置中相同 VRRP 实例的虚拟路由 ID 标识必须一致,否则将出现脑裂问题;
advert_int 用来同步通知间隔,Master 节点和 Backup 节点之间通信检查的时间间隔,单位是秒。
角色相关信息设定完毕后就要开始配置 VIP 并绑定至指定的网络接口上,在 virtual_ipaddress 中配置 VIP,可以配置多个 VIP,VIP 将绑定至 interface 参数配置的网络接口上。
authentication 认证配置段作用于同一个 VRRP 实例的 MASTER 和 BACKUP 之前的通信,具体的配置内容有 auth_type 认证类型,auth_pass 认证密码,认证类型有 PASS(Simple Passwd)和 AH(IPSEC),官方推荐 PASS,验证密码为明文方式,最多 8 位。同一个 VRRP 实例的 MASTER 和 BACKUP 使用相同的密码才能正常通信。
当添加 nopreemp 关键字时表示设置高可用模式为非抢占模式,如果去掉此关键字则为默认的抢占模式。抢占模式是指当高优先级节点恢复后会抢占低优先级节点成为 MASTER,非抢占模式允许低优先级节点继续担任 MASTER,preempt_delay 用来设置抢占延迟,单位秒,范围 0~1000,发现低优先级 MASTER 后多少秒开始抢占。
track_script 配置段是用于调用指定脚本,脚本相关配置请参考下一节。
3.脚本段定义(vrrp_script)
默认情况下,Keepalived 仅仅在节点宕机或 Keepalived 进程停掉的时候才会启动切换机制。但在实际工作中,有业务服务停止而 Keepalived 服务还存在的情况,这就会导致用户访问的 VIP 无法找到对应的服务,这时可以利用 Keepalived 触发预制的监测脚本,实现 VIP 漂移来继续提供服务。
vrrp_script 配置段定义一段脚本配置并设定脚本段名称。script 用双引号设置引用的 shell 语句或者 shell 脚本,通过该语句或脚本执行结果来判断是否触发指定动作,成功的结果不会触发动作,执行失败会触发动作。interval 设置监控间隔时间,单位为秒,weight 设置当监控脚本执行结果为失败时触发 priority 值调整,正数为增加优先级,负数为降低优先级,范围-255~255,fall 设置认定结果为失败时的执行失败次数,rise 设置判定结果为成功时的执行成功次数。
2.3.3 启动
Keepalived 配置完成后,在 Master 节点和 Backup 节点上使用以下命令开启 Keepalived 服务。
systemctl start keepalived
如果需要设置开机启动,则执行以下命令。
systemctl enable keepalived
3. HAProxy 功能及安装配置
3.1 核心功能
1.负载均衡、会话保持
在多个服务器间实现四层或七层负载均衡,支持多种负载均衡算法,并且根据 Hash 或者 cookies 方式实现会话保持。
2.健康检查
支持 TCP、HTTP 两种后端服务器健康检查模式。
3.统计监控
接受访问特定端口实现服务监控,并提供带有用户认证机制的服务状态报告页面。
4.SSL 卸载
可以解析 HTTPS 报文并将请求解密为 HTTP 向后端服务器传输。
5.其他功能
在 HTTP 请求或响应报文中添加、修改、删除首部信息;HTTP 请求重写与重定向;根据访问控制路由或阻断请求。
3.2 负载均衡调度算法
HAProxy 负载均衡调度算法可以在 HAProxy 配置文件中设定。支持配置多组后端服务组,每个组可以分别指定一种调度算法。以下是 HAProxy 支持的几种调度算法。
1.轮询
带有权重的轮询调度算法。支持权重的运行时调整,支持慢启动(在刚启动时缓慢接收大量请求),仅支持最大 4095 个后端活动主机。
2.静态轮询
静态轮询算法,不支持权重的运行时调整及慢启动,但后端主机数量无限制。
3.最少连接
带权重的最少连接调度算法,将访问请求动态调度至连接数较少的后端服务节点上。
4.源地址哈希
该算法保证在后端服务器组没有减少或增加的情况下,能将来自同一客户端 IP 的请求分配至同一个服务端,该算法适合在无法使用 cookie 插入的四层模式下使用。
5.URI 哈希
该算法保证访问同一 URI 请求分配至同一服务端,适用于后端为缓存服务器的情况,以提高缓存命中率。
6.URL 参数哈希
该算法对请求 URL 中的指定的参数的值作哈希计算。该算法适用于有用户识别参数的 URL ,例如保证同一用户 ID 的请求分配至同一服务节点。如果指定的参数没有值,则降级至轮询调度算法。
7.HTTP 首部哈希
该算法将 HTTP 首部中指定的字段取出做哈希计算。如果 HTTP 首部字段缺失,则降级至轮询调度算法。
3.3 安装与配置
3.3.1 安装
HAProxy 支持源码安装,同时也可以通过不同操作系统安装工具进行安装,本文以 CentOS 的 yum 工具为例进行安装介绍,分别在两台已安装并配置好 kkeepalived 的服务器上执行以下命令进行安装。
yum install -y haproxy
3.3.2 基本配置
yum 安装后,HAProxy 将生成配置文件:/etc/haproxy/haproxy.cfg,利用文本编辑器进行配置修改。
vi /etc/haproxy/haproxy.cfg
1.全局段定义(global)
全局参数配置将配置于所有 HAProxy 服务器上。
log 设置全局日志配置,语法为 log <address> <facility> <msglevel>,上例中指定使用本机上的 syslog 服务中的 local0 日志设备,记录日志等级为 info 的日志。chroot 设置 HAProxy 工作目录,pidfile 设置 HAProxy 的 pid 文件位置,maxconn 设置每个 HAProxy 进程可用的最大连接数,user 及 group 设置 HAProxy 进程所属的用户及用户组,daemon 关键字表示以守护进程方式运行 haproxy。
2.默认段定义(defaults)
默认段的作用是为后续前端代理及后端代理设置默认值。
mode 表示 HAProxy 的工作模式,设置 tcp 时为 4 层模式,设置 http 时为 7 层模式。log 设置日志输出方式,配置为 global 表示将采用全局段 log 的配置。
option httplog 关键字表示记录 HTTP 详细日志,包括 HTTP 请求、session 状态、连接数等。
option dontlognull 关键字表示日志中将不会记录空连接。所谓空连接就是在上游的负载均衡器或者监控系统为了探测该服务是否存活可用时,需要定期的连接或者获取某一固定的组件或页面,或者探测扫描端口是否在监听或开放等动作被称为空连接,官方文档中标注,如果该服务上游没有其他的负载均衡器的话,建议不要设置该参数,因为设置后互联网上的恶意扫描或其他动作就不会被记录下来。
option http-server-close 关键字表示每次请求完毕后主动关闭 HTTP 通道。
option forwardfor 关键字表示应用程序想记录发起请求的客户端的 IP 地址,需要在 HAProxy 上配置此选项,这样 HAProxy 会把客户端的 IP 信息发送给服务器,在 HTTP 请求中添加"X-Forwarded-For"字段启用 X-Forwarded-For,在 requests 头部插入客户端 IP 发送给后端的 server,使后端 server 获取到客户端的真实 IP。
option redispatch 关键字表示当使用了 cookie 时,HAProxy 将会将其请求的后端服务器信息插入到 cookie 中,以保证会话的持久性,如果后端的服务器服务不可用,但客户端的 cookie 是不会刷新的,设置此参数会将客户的请求强制定向到另外一个后端服务器上,以保证服务的正常。
retries 定义连接后端服务器的失败重连次数,连接失败次数超过此值后将会将对应后端服务器标记为不可用。
timeout 为前缀的关键字指定了一些关于请求、连接、响应的最大超时时间,单位默认为毫秒,也可以加入后缀 s(秒),m(分钟),h(小时),d(天)来指定。http-request 设置 HTTP 请求超时时长,queue 设置一个请求在队列里的超时时间,connect 设置最大与服务端建立连接的时长,client 设置客户端最大非活动时长,server 设置服务端最大非活动时长,http-keep-alive 设置最大等待新请求的空闲时长,check 设置检测超时时长。
3.前端代理定义(frontend)
前端代理配置定义一个服务监听,用于接收用户请求并将请求转发给后端代理,可以定义多个前端代理。
frontend 前端代理配置段定义一组前端服务并启动服务监听,同时设置代理名称。mode 设置工作模式,如果此参数未被设定则引用默认配置段配置的模式。bind 设置监听地址及端口,地址为空或者表示绑定至所有服务器的网络接口。default_backend 指定默认后端代理进行流量转发。
4.后端代理定义(backend)
用于接收前端代理请求并根据设置的负载均衡策略将流量转发至指定后端并对后端执行健康检查,一个前端可以指向多个后端;同时一个后端可以被多个调用。
backend 后端代理配置段定义一组后端服务器,同时设置代理名称。mode 设置工作模式如果此参数未被设定则引用默认配置段的模式。balance 设置后端负载均衡转发策略,策略取值请参考表 1。
表 1 balance 取值
server 配置了相应的后端服务集群地址,是真实的服务器,一个 backend 对应一个或者多个实体服务器。配置依次为节点名称、节点 IP 和端口、启用四层健康检查,在上述示例中 web1 服务器还设定了检查的相关参数表示每 3 秒(inter)检查一次,执行两次(fall)失败认为故障,执行一次(rise)成功即为服务可用。
3.3.3 启动
HAProxy 配置完成后,使用以下命令开启 HAProxy 服务。
systemctl start haproxy
如果需要设置开机启动,则执行以下命令。
systemctl enable haproxy
修改配置文件后可以通过刷新配置的方式热加载配置。
systemctl reload haproxy
3.3.4 会话保持
HAProxy 在会话保持功能上可以分为四层会话保持和七层会话保持。四层会话保持是基于源地址的会话保持,是指 HAProxy 在负载均衡时根据访问请求的源地址作为判断关联会话的依据,对于同一 IP 地址的所有访问请求在作负载均衡时均会被保持到后端的同一台服务器上。七层会话保持是基于 cookie 的会话保持,当客户端 HTTP 请求进入 HAProxy 时,根据负载均衡策略选择后端的一台服务器,后端服务器将 HTTP 响应返回 HAProxy,此时 HAproxy 会插入该服务器的 cookie 并将插入 cookie 的 HTTP 响应返回至客户端,当该客户端再次发出请求时,带有上次插入 cookie 的 HTTP 请求进入 HAProxy,HAProxy 解析出 cookie 中服务器信息并将请求发送至相同的后端服务器。
四层会话保持的配置方式实际只需要将配置文件中后端代理段的负载均衡策略设置为基于源地址哈希并将工作模式设置为 tcp 即可,配置文件如下。
七层会话保持配置方式则需要在配置文件后端代理段中设置 cookie 并确保工作模式为 http,配置文件如下。
以上配置文件中的 cookie 设置了以 WEBSRV 为名称的 cookie,然后在 server 配置中分别定义了不同的 cookie 值,通过浏览器访问 HAProxy 前端代理地址可以看到该 cookie,利用该 cookie 实现会话保持,如图 2 所示。
图 2 cookie 信息
3.3.5 SSL 卸载
利用 HAProxy 可以实现 SSL 卸载功能,从而使客户端到 HAProxy 的访问采用 SSL 封装后的 HTTPS,而 HAProxy 至后端服务器之间的通信则采用 HTTP(图 3),从而消除服务器端的 SSL 加密运算开销。
图 3 SSL 卸载
实现 SSL 卸载需要在配置文件全局定义段加入 SSL 参数调整,以及在前端代理段加入 SSL 配置,涉及的配置如下。
全局段配置中增加了 SSL 参数 tune.ssl.default-dh-param,设置值为 2048,表示使用 2048bit 加密,和 SSL 秘钥加密位数保持一致。
前端代理配置 bind 加入 443 端口、SSL 支持并绑定指定证书,证书文件内容为网站的证书和私钥通过命令(cat web.crt web.key | tee web.pem)拼接合成。配置段中还加入了 HTTP 到 HTTPS 的自动跳转功能(redirect scheme https if !{ ssl_fc }),在浏览器中输入域名或者 IP 地址,无需指定协议类型,如果导入根证书后的浏览器显示的状态是安全的则表示配置成功(图 4)。
图 4 开启 HTTPS
3.3.6 流量路由
HAProxy 可以为数据库、邮件、页面等服务提供四层负载均衡机制,也可以从 HTTP 请求报文中提取指定数据并通过特定的访问控制列表(ACL)提供基于七层的流量转发机制。
1.基于 URL 路径转发。HAProxy 可以根据请求的 URL 路径做路由,通过配置不同的路径将不同的 URL 路径分发至不同的后端服务器,在以下的例子中我们在两个页面服务器上分别配置了两个测试页面 test1.html、test2.html,页面内容简单标识了所在服务器的信息,并利用转发机制实现基于 URL 的路径分发,涉及的相关配置如下。
前端代理配置段中加入 acl 配置,设置的路由规则为匹配路径的前缀(path_beg)test1 及 test2,并配置 use_backend 参数将指定 acl 作用于指定后端服务器,is_test1 规则匹配后路由至 test1,is_test2 规则匹配后路由至 test2。
定义两组后端代理配置,分别配置 test1 及 test2 后端代理,指向相应的页面服务器。通过访问不同的路径 HAProxy 可以正确路由转发到指定后端页面服务器,没有命中 acl 的请求将转发至默认后端服务器,如图 5 所示。
图 5 URL 路径转发
2.基于 HTTP 首部信息转发。HAProxy 可以根据 HTTP 首部信息来执行路由分发操作,例如通过首部信息中的 User-Agent 来判断请求方的设备类型是 iPhone 还是 Android,以此作为依据进行路由分发至不同的后端服务器上,或者通过首部信息中的 Host 字段实现以域名为依据进行路由分发。以 Host 为例,涉及的相关配置如下。
前端代理配置段中加入 acl 配置,通过 hdr_beg(host)关键字设置的路由规则匹配 HTTP 首部信息中 Host 前缀 www.test1.com 及 www.test2.com,并配置 use_backend 参数将指定 acl 作用于指定后端服务器,is_test1 规则匹配后路由至 test1,is_test2 规则匹配后路由至 test2。
定义两组后端代理配置,分别配置 test1 及 test2 后端代理,指向相应的页面服务器。通过不同的域名访问可以正确路由转发到指定后端页面服务器,没有命中 acl 的请求将转发至默认后端服务器,如图 6 所示。
图 6 域名转发
4. 总结
负载均衡可以由专业硬件设备提供,由服务器集群服务节点之上架设专业负载均衡器来完成集群节点的负载均衡工作。硬件负载均衡优势明显,设备独立于操作系统、强大的性能、丰富的功能、多样化的负载均衡策略、智能化流量管理,由专业维护团队提供维护,缺点是价格昂贵、配置复杂,部署难度大时间长,不适于中小规模的网络服务。
软负载则在一台或多台服务器操作系统之上安装附加软件来实现负载均衡。采用软负载方案后系统构架内无需额外部署专用于负载均衡的硬件设备以降低成本,同时能够更好地根据系统与应用的状态来分配负载,无缝的嵌入系统架构中,也可以根据实际需求灵活扩展,互联网公司大多都有自己的软负载方案。相比硬件负载来说软件负载具有配置简单、快速部署、使用灵活、成本低廉、高性价比等诸多优势。
在建设某银行应用基础云 PaaS 平台的实践中,采用 Keepalived+HAproxy 组合搭建了高可用软负载方案,为平台内多组控制节点、多组工作节点、以及双副本镜像仓库提供服务接口聚合负载和高可用性保障。首先,平台的业务流量入口指向 Keepalived 高可用 VIP 地址,经过 Haproxy 负载调度至后端工作节点中,这样一旦其中任意一个负载均衡节点或者后端工作节点宕机,高可用 VIP 地址和剩余存活的后端工作节点仍可对外提供服务。其次,随着后期业务流量的上升,后端工作节点出现负载压力时,可以根据实际需要灵活配置 Haproxy,扩展后端工作节点数量,降低整体工作节点负载压力。从现有的实践经验来看,该软负载方案具备了良好的稳定性、灵活性和可扩展性。
版权声明: 本文为 InfoQ 作者【CTO技术共享】的原创文章。
原文链接:【http://xie.infoq.cn/article/0de8743541a595a46efc5c254】。未经作者许可,禁止转载。
评论