构建基于Keepalived与LVS的高可用四层负载均衡集群

本文旨在为中高级工程师与架构师提供一份深入的、基于生产环境实践的指南,剖析如何利用 LVS (Linux Virtual Server) 和 Keepalived 构建一个高性能、高可用的四层负载均衡集群。我们将跳过基础概念的罗列,直击其内核工作原理、架构设计中的关键权衡(Trade-off)、配置实现的工程细节,以及在真实场景中可能遇到的“坑”与应对策略,最终勾勒出一条从简单到复杂的架构演进路径。

现象与问题背景

在任何有一定规模的在线服务架构中,单点故障(Single Point of Failure, SPOF)是可用性的天敌。一个典型的 Web 服务集群,流量入口通常由 Nginx 或 HAProxy 等反向代理/负载均衡器承担。然而,这个入口本身如果是一台物理机或虚拟机,它就构成了整个系统的“阿喀琉斯之踵”。一旦这台机器宕机、网络中断或软件崩溃,整个服务将对外不可用,造成业务中断和用户流失,这在金融交易、实时通信等场景中是不可接受的。

为了解决入口的单点问题,我们自然会想到引入冗余。最直接的方案是部署两台或多台负载均衡器,但新的问题随之而来:流量如何知道该发往哪台“活着的”负载均衡器?客户端通常只认一个固定的 IP 地址。这就引出了对一个“浮动 IP”(Floating IP)或“虚拟 IP”(Virtual IP, VIP)的需求。这个 VIP 可以在多台物理服务器之间漂移,当主服务器失效时,备用服务器能迅速接管 VIP,从而对客户端透明地完成故障切换。

Keepalived + LVS 的组合正是解决这一经典问题的高性能、高可靠性的开源方案。LVS 负责提供内核级别的、高效的四层负载均衡能力,而 Keepalived 则通过实现 VRRP (Virtual Router Redundancy Protocol) 协议,为 LVS Director 提供了主备冗余和 VIP 自动漂移的能力,共同构筑了一个健壮的流量入口。

关键原理拆解

要真正驾驭 LVS 和 Keepalived,我们必须深入其工作原理,这涉及到网络协议栈、操作系统内核以及分布式系统中的心跳检测机制。这部分我将切换到“大学教授”的声音,从计算机科学的基础原理出发。

  • LVS 的内核存在:Netfilter 与 IPVS
    LVS 的高性能源于其作为 Linux 内核模块(IPVS – IP Virtual Server)的存在。它工作在 TCP/IP协议栈的 INPUT 链之后,PREROUTING 链之前,通过 Netfilter 框架注册钩子函数,截取发往 VIP 的网络数据包。与运行在用户空间的 Nginx/HAProxy 不同,LVS 的转发决策完全在内核态完成,避免了用户态与内核态之间频繁的上下文切换和数据拷贝,这是其达到近乎线速转发能力的核心原因。
  • LVS 工作模式:DR 模式的精髓
    LVS 支持多种工作模式,如 NAT、TUN 和 DR (Direct Routing)。在绝大多数场景下,DR 模式是性能最佳的选择。其原理如下:

    1. 请求路径: 客户端的请求包(`Client_IP -> VIP`)到达 LVS Director。Director 在内核中通过 IPVS 模块,根据预设的负载均衡算法(如轮询、加权轮询)选择一台后端真实服务器(Real Server, RS)。关键操作在于:LVS Director 不修改 IP 包头部的目标 IP(依然是 VIP),而是修改二层以太网帧(Ethernet Frame)的目标 MAC 地址,将其改为选定 RS 的 MAC 地址,然后将数据帧重新发到局域网中。
    2. 响应路径: 交换机根据 MAC 地址将数据帧送达 RS。RS 的网络设备接收到数据帧后,解包发现 IP 包的目标 IP 是 VIP。为了让 RS 能够合法地处理这个 IP 包,我们必须在 RS 的一个不会对外响应 ARP 请求的设备(通常是 loopback 接口 `lo`)上配置 VIP。RS 处理完请求后,构造响应包(`VIP -> Client_IP`),然后直接通过自己的默认网关将响应包发送给客户端,完全绕过了 LVS Director

    这种非对称的流量路径,使得 LVS Director 只处理入站流量,而出站流量由 RS 直接响应,极大地减轻了 Director 的负载,使其成为整个集群性能的瓶颈的可能性大大降低。

  • Keepalived 的心跳与选举:VRRP 协议
    Keepalived 的核心是实现了 VRRP 协议(RFC 5798)。VRRP 是一种容错协议,它将一组路由器(在这里是 LVS Director)组织成一个虚拟路由器(Virtual Router)。

    • 角色: 在一个 VRRP 组中,有且仅有一个 MASTER 路由器和多个 BACKUP 路由器。MASTER 负责拥有并响应 VIP 的 ARP 请求。
    • 心跳: MASTER 节点会周期性地(默认为 1 秒)向一个特定的组播地址(224.0.0.18)发送 VRRP 通告报文,宣告自己的存活状态和优先级。
    • 选举与抢占: 所有 BACKUP 节点监听这个组播地址。如果在指定时间内(`Master_Down_Interval`,通常是 3 倍的通告间隔)没有收到 MASTER 的通告,优先级最高的 BACKUP 节点会认为 MASTER 已失效,自行切换为 MASTER 状态,并立即发送一个免费 ARP(Gratuitous ARP)广播,宣告自己接管了 VIP,从而更新整个局域网内其他设备的 ARP 缓存,实现流量的重新定向。这个过程即“故障转移”(Failover)。

系统架构总览

一个典型的基于 Keepalived+LVS 的双机热备集群架构可以这样描述(无需图示,用文字即可清晰呈现):

组件列表:

  • 客户端 (Clients): 服务的最终用户。
  • 虚拟 IP (VIP): 对外暴露的统一服务地址,例如 `192.168.1.100`。
  • LVS Director 主节点 (LVS-Master): 运行 Keepalived (MASTER 状态) 和 IPVS。持有 VIP。
  • LVS Director 备节点 (LVS-Backup): 运行 Keepalived (BACKUP 状态) 和 IPVS。平时不持有 VIP,但实时监控主节点。
  • 后端真实服务器集群 (Real Servers, RS1, RS2, …): 例如 `192.168.1.11`、`192.168.1.12` 等。它们是真正提供应用服务的节点(如 Nginx Web 服务器)。
  • 内部网络: 所有 LVS Director 和 Real Server 必须在同一个二层广播域内,以便通过 MAC 地址进行转发。

工作流程:

  1. 正常情况下,LVS-Master 持有 VIP。客户端对 VIP 的 DNS 解析请求最终都将指向这个 VIP。
  2. 客户端向 VIP 发起 TCP 连接请求(如访问网站)。请求流量通过物理网络到达 LVS-Master。
  3. LVS-Master 的 IPVS 模块根据负载均衡策略(如 `wrr` 加权轮询)选择一台健康的 RS(如 RS1),将请求数据包的目标 MAC 地址修改为 RS1 的 MAC,然后发往内部网络。
  4. RS1 收到数据包,处理后直接将响应数据返回给客户端。
  5. 同时,LVS-Master 上的 Keepalived 进程持续发送 VRRP 心跳包。LVS-Backup 上的 Keepalived 进程则安静地监听。
  6. 故障场景:如果 LVS-Master 宕机或网络故障,LVS-Backup 在超时后未收到心跳,其 Keepalived 进程状态切换为 MASTER。它会立即配置网卡接管 VIP,并发送免费 ARP,通知交换机更新 ARP 表,将指向 VIP 的流量全部引导到自己这里。整个切换过程对客户端是透明的,通常在秒级完成。

核心模块设计与实现

现在切换到“极客工程师”模式。理论都懂了,动手干才是关键。坑都在细节里。

Keepalived 配置 (`/etc/keepalived/keepalived.conf`)

主备节点的配置只有两个地方不同:`state` 和 `priority`。主节点 `priority` 要高于备节点。

主节点 (LVS-Master) 配置示例:


! Configuration File for keepalived

global_defs {
   # 必须设置一个唯一的 router_id,通常用主机名
   router_id LVS_MASTER_01
}

# VRRP 实例定义
vrrp_instance VI_1 {
    # 初始状态,MASTER 比 BACKUP 优先级高,所以它会成为主
    state MASTER
    # 监听的网络接口
    interface eth0
    # 虚拟路由 ID,主备必须一致
    virtual_router_id 51
    # 优先级,MASTER > BACKUP
    priority 101
    # 心跳间隔,单位秒
    advert_int 1
    
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    
    # VIP 地址,可以有多个
    virtual_ipaddress {
        192.168.1.100/24 dev eth0
    }
}

# LVS 定义
virtual_server 192.168.1.100 80 {
    # 健康检查间隔
    delay_loop 6
    # 负载均衡算法: Weighted Round Robin
    lb_algo wrr
    # LVS 模式: Direct Routing
    lb_kind DR
    # 会话保持时间(秒),对于需要登录状态的 Web 应用很重要
    persistence_timeout 600
    protocol TCP

    real_server 192.168.1.11 80 {
        weight 100
        TCP_CHECK {
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
            connect_port 80
        }
    }

    real_server 192.168.1.12 80 {
        weight 100
        TCP_CHECK {
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
            connect_port 80
        }
    }
}

备节点 (LVS-Backup) 配置: 只需修改 `vrrp_instance` 块中的 `state` 为 `BACKUP`,`priority` 为一个较小的值(如 `100`),并修改 `global_defs` 中的 `router_id` 即可。其他部分完全一样,保证配置同步是运维的关键。

工程坑点:`nopreempt` 选项。默认情况下,如果一个高优先级的节点恢复,它会“抢占”当前 MASTER 的角色。在频繁网络抖动的环境中,这可能导致 VIP 频繁切换。配置 `nopreempt` 在 `vrrp_instance` 块内,可以让当前 MASTER 即使在有更高优先级节点恢复后也继续保持 MASTER 角色,除非自己宕机。这是一种更稳健的策略,避免了不必要的切换风暴。

Real Server 配置 (ARP 抑制)

这是 LVS DR 模式配置中最容易出错的地方。Real Server 必须在 `lo` 接口上配置 VIP,并且要抑制其对该 VIP 的 ARP 响应。否则,RS 可能会“抢答”网络中的 ARP 请求,造成所谓的“ARP 欺骗”,导致流量直接打到某台 RS 上,绕过了 LVS Director,负载均衡就失效了。

在所有 Real Server 上执行的脚本:


#!/bin/bash

VIP=192.168.1.100

# 在 loopback 接口上配置 VIP
ifconfig lo:0 $VIP netmask 255.255.255.255 broadcast $VIP up
route add -host $VIP dev lo:0

# ARP 抑制配置 (最关键的部分)
# sysctl -p /etc/sysctl.conf 来持久化
echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce
echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce

echo "Real Server configured."

极客解读:

  • `arp_ignore=1`: 当接收到 ARP 请求时,如果请求的目标 IP 地址是本机配置在非该接收接口的 IP 地址,则不予响应。我们的 VIP 配置在 `lo` 接口,而 ARP 请求是从 `eth0` 进来的,所以这条规则生效,RS 不会响应。
  • `arp_announce=2`: 当本机需要发送 ARP 请求时(例如,本机作为源 IP 通信),总是使用最适合该目标 IP 的本地地址作为 ARP 请求的源 IP 地址,避免使用 `lo` 上的 VIP 地址作为源地址向外宣告。

这两个内核参数的组合,完美解决了 DR 模式下的 ARP 冲突问题。忘记配置它们,你的集群绝对会工作不正常。

性能优化与高可用设计

我们不仅要让集群跑起来,还要让它跑得快、跑得稳。

性能权衡:LVS vs. Nginx/HAProxy

一个常见的架构争论是:既然 Nginx 也能做负载均衡,为什么还要用 LVS?

  • 性能维度: LVS 是四层负载均衡,工作在内核,只做 IP 和端口的转发,不做任何应用层内容的解析。其吞吐量巨大,CPU 消耗极低,一个普通的服务器可以轻松处理数百万甚至上千万的并发连接。Nginx/HAProxy 是七层负载均衡,需要解析 HTTP 等应用层协议,可以根据 URL、Header 等信息做更精细的流量分发。这个解析过程在用户态完成,涉及大量的 CPU 计算和内存拷贝,性能上限远低于 LVS。
  • 功能维度: LVS 功能单一纯粹。Nginx/HAProxy 功能丰富,可以做 SSL 卸载、HTTP 压缩、URL 重写、灰度发布等复杂逻辑。
  • 典型组合: 最佳实践通常是组合使用。用 LVS+Keepalived 在最前端做四层负载均衡,分发流量给一个 Nginx/HAProxy 集群。Nginx/HAProxy 集群再做七层负载均衡,分发流量给后端的应用服务器集群。这样既利用了 LVS 的高性能,又利用了 Nginx 的灵活性。

高可用设计的“魔鬼”:脑裂 (Split-Brain)

脑裂是所有主备/集群架构的噩梦。在 LVS+Keepalived 场景下,如果主备 LVS Director 之间的心跳网络中断(比如连接它们的交换机故障),但它们各自到外部网络和 RS 的网络都正常,就会出现问题:

备节点因为收不到主节点的心跳,会认为主节点宕机,于是自己切换为 MASTER,并接管 VIP。此时,网络中出现了两个 MASTER,都声称自己拥有 VIP。这会导致交换机层面严重的 MAC 地址漂移,网络时通时断,服务处于一种“混沌”的不可用状态,比单点故障更可怕。

对抗脑裂的策略:

  1. 冗余心跳网络: 为主备 Director 之间提供多条物理心跳链路,例如通过 bonding 技术将两块网卡绑定,或者使用不同的交换机连接。这是最直接有效的物理层解决方案。
  2. 增加仲裁机制: 引入一个第三方的“裁判”。例如,要求节点在切换为 MASTER 之前,必须能 ping 通某个关键的外部网关地址。如果连网关都 ping 不通,说明自己可能被隔离了,就不应该进行切换。这可以通过 Keepalived 的 `track_script` 机制实现。
  3. Fencing(隔离): 当检测到可能发生脑裂时,采取极端措施。例如,通过带外管理接口(如 IPMI)强制重启或关闭其中一个节点,确保只有一个“幸存者”。这种机制相对复杂,通常在对一致性要求极高的存储或数据库集群中使用,但在 LVS 场景中也可以作为终极保障。

架构演进与落地路径

一个成熟的架构不是一蹴而就的,而是逐步演进的。对于 LVS 集群的落地,可以遵循以下路径:

第一阶段:单 LVS Director + Real Server 集群
在业务初期,如果对入口的可用性要求不是极端严苛,可以先只部署一台 LVS Director。这可以让你首先享受到 LVS 带来的横向扩展后端服务的能力。此时,LVS Director 是一个单点,但相比于将所有服务部署在一台机器上,已经有了很大的进步。运维团队需要做好监控和快速恢复预案。

第二阶段:LVS + Keepalived 主备(Master/Backup)集群
这是本文介绍的标准架构。当业务发展到一定阶段,对可用性有了明确的 SLA 要求时,引入第二台 LVS Director 和 Keepalived,构建主备高可用集群。这是投入产出比最高的方案,解决了入口单点问题,能满足绝大多数业务场景的需求。

第三阶段:LVS + Keepalived 双主(Active/Active)集群
为了充分利用两台 LVS Director 的硬件资源,可以配置双主集群。这通常通过划分多个 VIP 实现。例如,VIP1 由 Director A 作为 MASTER,Director B 作为 BACKUP;VIP2 则由 Director B 作为 MASTER,Director A 作为 BACKUP。这样两台 Director 同时都在工作,承载不同的业务流量。这种架构增加了配置和管理的复杂度,需要更精细的容量规划和监控。

第四阶段:多地多活与全局负载均衡
当业务扩展到多个数据中心时,单个 LVS 集群就无法满足需求了。此时,需要在每个数据中心内部署一套完整的 LVS+Keepalived 集群。而在数据中心之间,则需要通过更上层的全局负载均衡技术(如 DNS 轮询、基于地理位置的智能 DNS 解析,或专用的 GSLB 设备)来分发流量。这构建了一个多地域、多活的、具备容灾能力的服务体系。

总结而言,LVS+Keepalived 虽是“上古神器”,但其简单、高效、稳健的特性,使其在云原生和微服务大行其道的今天,依然是构建高性能四层负载均衡的基石之一。深刻理解其内核原理与工程实践中的权衡,是一个架构师在设计高可用系统时必备的底层能力。

延伸阅读与相关资源

  • 想系统性规划股票、期货、外汇或数字币等多资产的交易系统建设,可以参考我们的
    交易系统整体解决方案
  • 如果你正在评估撮合引擎、风控系统、清结算、账户体系等模块的落地方式,可以浏览
    产品与服务
    中关于交易系统搭建与定制开发的介绍。
  • 需要针对现有架构做评估、重构或从零规划,可以通过
    联系我们
    和架构顾问沟通细节,获取定制化的技术方案建议。
滚动至顶部