Keepalived + LVS 搭建高可用负载均衡及支持 Websocket 长连接
一、项目概述
本教程旨在助力您搭建一个基于 Keepalived 和 LVS(Linux Virtual Server)的高可用负载均衡环境,同时使其完美适配 Websocket 长连接场景,确保您的 Web 应用能够高效、稳定地运行,从容应对高并发访问,并且在服务器遭遇故障时实现自动无缝切换,为服务的连续性保驾护航。
二、环境准备
- 服务器规划
- 准备至少 3 台服务器,推荐选用 CentOS 7 或以上版本的 Linux 操作系统,且在安装系统时确保已勾选基础网络工具与开发包。本教程中服务器角色及对应示例 IP 地址分配如下:
- LVS 负载均衡器(MASTER):192.168.1.100
- LVS 负载均衡器(BACKUP):192.168.1.101
- Real Server 1:192.168.1.102
- Real Server 2:192.168.1.103
- VIP:192.168.1.200
- 所有服务器需处于同一局域网内,务必保证相互之间能够通过 ping 命令顺畅连通,并且具备访问互联网的能力,用于后续软件安装及更新操作。
- 准备至少 3 台服务器,推荐选用 CentOS 7 或以上版本的 Linux 操作系统,且在安装系统时确保已勾选基础网络工具与开发包。本教程中服务器角色及对应示例 IP 地址分配如下:
- 网络配置检查与调整
- 在每台服务器上,执行
ifconfig
或ip addr show
命令查看网卡配置信息,确保网卡正常工作且 IP 地址配置准确无误。例如,在 LVS MASTER 服务器上运行ip addr show eth0
(假设网卡名为 eth0),应得到类似如下输出:2: eth0: <BROADCAST,MULTICAST,UP,LOWER_RETURNS> mtu 1500 qid 10000 link/ether 00:11:22:33:44:55 inet 192.168.1.100/24 brd 192.168.1.255 scope global noprefixroute eth0 valid from Sat, 01 Jan 2022 00:00:00 UTC valid until Sun, 01 Jan 2023 00:00:00 UTC
- 若发现网络配置有误,使用
vi /etc/sysconfig/network-scripts/ifcfg-eth0
(以 eth0 为例)编辑网卡配置文件,按需修改 IP 地址、子网掩码、网关等参数,修改完成后执行systemctl restart network
重启网络服务,使新配置生效。
- 在每台服务器上,执行
三、安装软件
- 在 LVS 负载均衡器(MASTER 和 BACKUP)以及 Real Server 上,打开终端,通过 yum 命令安装所需软件:
yum install -y ipvsadm keepalived
ipvsadm
:这是配置 LVS 规则的核心工具,利用它能够灵活地定义虚拟服务器、关联 Real Server 并指定负载均衡算法,是构建 LVS 功能体系的关键组件。keepalived
:一方面,它基于 VRRP(Virtual Router Redundancy Protocol)协议提供高可用保障,能将多台物理路由器虚拟化为一个 “虚拟路由器”,使得在主路由器出现故障时,备份路由器可迅速自动接管服务,有效规避单点故障风险;另一方面,它能够与 LVS 紧密协作,实现对 Real Server 的健康监测以及根据服务器状态动态调整负载均衡策略。
四、配置 Keepalived + Lvs(MASTER)节点
- 打开 Keepalived 的配置文件:
vi /etc/keepalived/keepalived.conf
,该文件是 Keepalived 的核心配置枢纽,所有与高可用、负载均衡及相关辅助功能的设定均在此文件内完成。 - 进行如下配置:
global_defs { notification_email { your_email@example.com # 务必替换为您真实有效的报警邮箱地址,其用途在于接收 Keepalived 运行过程中的异常报警信息,诸如主备切换失败、健康检查持续报错等突发状况。一旦出现问题,Keepalived 会自动向此邮箱发送详细通知邮件,以便系统管理员能够及时察觉并着手处理。 } notification_email_from keepalived@localhost smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id LVS1 # 路由器标识,在当前搭建的这个高可用环境所构成的 VRRP 域内,MASTER 和 BACKUP 的 router_id 必须不同,此处设定为 LVS1,它用于在 VRRP 协议数据包中标识不同的路由器实例,从而确保节点间能够准确无误地相互识别。 } vrrp_instance VI_1 { state MASTER # 明确此节点在 VRRP 实例中扮演“主”的角色,意味着在通常运行状态下,它将掌控对外提供服务的虚拟 IP(VIP),并肩负起主要的负载均衡重任。 interface eth0 # 根据服务器实际使用的网卡名称进行修改,该参数指定 Keepalived 用于收发 VRRP 数据包的网卡接口,务必确保与所在服务器的实际网卡保持一致,否则整个系统将无法正常运转。 virtual_router_id 51 # 虚拟路由 ID,在同一个 VRRP 域内,MASTER 和 BACKUP 的此项 ID 必须严格一致,它用于唯一标识一组虚拟路由器,取值范围通常为0 - 255,不同的 ID 代表不同的虚拟路由群组。 priority 100 # 优先级数值,在主备节点选举过程中起着决定性作用,MASTER 的优先级必须高于 BACKUP,数值越大优先级越高,本示例中设为 100,如此一来,当主节点遭遇故障时,备份节点将依据优先级高低判断是否接管服务。 advert_interval 1 authentication { type PASS password 1111 # 密码,MASTER 和 BACKUP 需确保一致,其主要功能是用于 VRRP 节点间的认证,确保只有授权的节点才能参与虚拟路由器的运作,防止非法节点接入。 } virtual_ipaddress { 192.168.1.200/24 # 虚拟 IP(VIP),依据实际网络网段进行合理设置,这是面向外部客户端提供服务的统一 IP 地址,客户端将通过访问此 IP 来获取相应服务。在主节点正常运行期间,此 VIP 会绑定在主节点的网卡之上,一旦主节点发生故障,VIP 将自动无缝切换至备份节点的网卡上。 } } virtual_server 192.168.1.200 80 { # VIP 和端口,与上述设置紧密对应,在此处定义了一个虚拟服务器,明确了对外服务的 IP 地址与端口号,后续的 Real Server 将挂载在此虚拟服务器之下,依照负载均衡策略接收并处理分发而来的请求。 lb_algo wrr # 加权轮询调度算法,您可根据实际需求进行灵活切换,如选用 rr(轮询)、sh(源地址散列)等其他算法。wrr 算法的优势在于能够依据 Real Server 的权重值来合理分配请求,不同权重的 Real Server 获取请求的机会不尽相同,权重越大则机会越多,相较于简单的轮询算法,它能更为精准地适配不同性能的 Real Server,进而实现更为优化、合理的负载分配效果。 lb_kind DR # 工作模式,DR(Direct Routing)模式在性能表现上较为出色,当然您也可根据实际情况选择 NAT 等其他模式。在 DR 模式下,客户端请求的数据包将直接发送至 Real Server,而响应数据包同样会直接返回客户端,LVS 负载均衡器在此过程中仅负责高效处理请求的分发与调度工作,极大地减轻了自身负担,显著提升了整体系统性能。不过,采用 DR 模式需要对 Real Server 进行一系列特殊配置(如设置 VIP 等操作),后续步骤会详细阐述。 persistence_timeout 3600 # 持久连接超时时间,单位为秒,考虑到 Websocket 长连接的特性,特意将此值设置得较长,您也可根据实际业务场景进行适当调整。该参数决定了源自同一源 IP 的请求在多长时间内会被持续转发至同一个 Real Server,对于 Websocket 长连接而言,充足的超时时间能够确保在连接存续期间,客户端后续发出的所有请求都能被精准导向最初建立连接的 Real Server,有效避免因负载均衡调度而意外导致连接中断的情况发生。 persistence_granularity SOURCE_IP # 以源 IP 实现持久连接,这一设置能够切实确保同一客户端的请求始终被定向到同一 Real Server。其原理是基于客户端的源 IP 进行哈希运算,只要源 IP 保持不变,后续所有请求都将被稳定送达最初建立连接的那台 Real Server,这对于维护 Websocket 长连接的稳定性起着举足轻重的作用。 protocol TCP real_server 192.168.1.102 80 { # Real Server 1 的 IP 和端口 weight 1 TCP_CHECK { connect_timeout 3 nb_get_replies 3 delay_loop 5 } } real_server 192.168.1.103 80 { # Real Server 2 的 IP 和端口 weight 1 TCP_CHECK { connect_timeout 3 nb_get_replies 3 delay_loop 5 } } }
- 保存并退出配置文件。
- 开启路由转发功能:
- 编辑
/etc/sysctl.conf
文件:vi /etc/sysctl.conf
- 添加或确认以下内容:
net.ipv4.ip_forward = 1
- 编辑
- 重启 Keepalived 服务:
- 执行命令
systemctl restart keepalived
,使 Keepalived 按照新配置运行,此时主节点会依据新配置尝试绑定虚拟 IP(VIP),并基于设定好的调度算法、健康检查机制等对 Real Server 进行负载均衡调度。
- 执行命令
五、配置 Keepalived + Lvs(BACKUP)节点
- 同样打开 Keepalived 的配置文件:
vi /etc/keepalived/keepalived.conf
- 修改如下内容:
global_defs { notification_email { your_email@example.com # 替换为真实的报警邮箱地址,作用与 MASTER 节点配置相同。 } notification_email_from keepalived@localhost smtp_server 127.0.0.1 smtp_connect_timeout 30 router_id LVS2 # 更改为与 MASTER 不同的标识,此处设为 LVS2,用于清晰区分主备节点。 } vrrp_instance VI_1 { state BACKUP # 表明此节点在 VRRP 实例中的角色为“备份”,正常运行时不承担对外服务职责,处于待命状态,一旦主节点出现故障,将立即接管服务。 interface eth0 # 根据实际网卡名修改,需与 MASTER 节点对应网卡保持一致。 virtual_router_id 51 # 与 MASTER 一致,同属一个虚拟路由组。 priority 99 # 低于 MASTER 的优先级,本示例中设为 99,当主节点发生故障且此备份节点在剩余备份节点中优先级最高时,将顺利接管主节点工作,成为新的主节点。 advert_interval 1 authentication { type PASS password 1111 # 与 MASTER 一致,用于节点间认证。 } virtual_ipaddress { 192.168.1.200/24 # 与 MASTER 一致的 VIP,当主节点故障时,此 VIP 将自动切换到该备份节点网卡上。 } } virtual_server 192.168.1.200 80 { # VIP 和端口,与上面设置对应,配置与 MASTER 节点类似,确保备份节点也能准确无误地对 Real Server 进行负载均衡调度。 lb_algo wrr # 加权轮询调度算法,可按需更换,如 rr(轮询)、sh(源地址散列)等。 lb_kind DR # 工作模式,DR 模式性能较好,也可按需选 NAT 等。 persistence_timeout 3600 # 持久连接超时时间,单位秒,为适应 Websocket 长连接设长些,可调整。 persistence_granularity SOURCE_IP # 以源 IP 实现持久,确保同一客户端请求到同一 Real Server。 protocol TCP real_server 192.168.1.102 80 { # Real Server 1 的 IP 和端口 weight 1 TCP_CHECK { connect_timeout 3 nb_get_replies 3 delay_loop 5 } } real_server 192.168.1.103 80 { # Real Server 2 的 IP 和端口 weight 1 TCP_CHECK { connect_timeout 3 nb_get_replies 3 delay_loop 5 } } }
- 保存并退出配置文件。
- 开启路由转发功能:
- 编辑
/etc/sysctl.conf
文件: - 添加或确认以下内容:
net.ipv4.ip_forward = 1
- 执行命令使配置生效:
sysctl -p
- 编辑
- 重启 Keepalived 服务:
- 执行命令
systemctl restart keepalived
,使 Keepalived 按照新配置运行,此时备份节点会依据新配置进入监听状态,时刻准备在主节点出现故障时接管服务,保障整个高可用负载均衡系统的正常运作。
- 执行命令
六、配置 Real Server
- 在 Real Server(以 192.168.1.102 和 192.168.1.103 为例)上:
- 编辑
/etc/sysctl.conf
文件:
- 编辑
# 防止 ARP 冲突,调整 ARP 相关内核参数
net.ipv4.arp_ignore = 1
net.ipv4.arp_announce = 2
net.ipv4.arp_ignore = 1
:当设置为 1 时,若接收到 ARP 请求,且目标 IP 为本地配置的 VIP,此时仅当请求的源 IP 与本机某一网卡的 IP 处于同一网段时,才会响应 ARP 请求,这样能够有效规避不必要的 ARP 响应,最大程度防止 ARP 冲突的发生。net.ipv4.arp_announce = 2
:设置为 2 时,当本机向外发送 ARP 宣告时,将始终使用本机的真实 IP 地址,而非 VIP,以此确保 ARP 信息的准确性与一致性,避免网络中的其他设备出现混淆情况。- 执行命令使配置生效:
sysctl -p
- 编写设置 VIP 的脚本,如
vi /etc/init.d/lvsrs
,内容如下:
#!/bin/bash
VIP=192.168.1.200
/sbin/ifconfig lo:0 $VIP broadcast $VIP netmask 256.256.256.255 up
/sbin/route add -host $VIP dev lo:0
- 该脚本的目的在于在 Real Server 的本地环回接口(0) 上设置 VIP。在 LVS 的 DR 模式下,Real Server 需要能够精准识别并妥善处理发往 VIP 的请求,将 VIP 绑定至本地环回接口,既便于统一管理,又能有效避免与真实网卡 IP 发生冲突。首先明确定义 VIP 的值,随后通过
ifconfig
命令将 VIP 绑定到 lo:0 接口,并设置相应的广播地址和子网掩码,最后利用route
命令添加一条指向 VIP 的的路由,确保发往 VIP 的数据包能够在本地得到有效处理。 - 赋予脚本执行权限:
chmod +x /etc/init.d/lvsrs
- 启动脚本:
/etc/init.d/lvsrs start
七、测试
在客户端上
- 使用
ping
命令测试能否连通虚拟 IP(VIP),例如在一台与搭建环境处于同一局域网且能正常访问网络的客户端机器上执行:
ping 192.168.1.200
- 如果能收到来自 VIP 的正常响应(不断显示类似
Reply from 192.168.1.200: bytes=32 time<1ms TTL=64
的信息),则说明客户端到 VIP 的网络链路是通畅的,初步表明负载均衡前端配置没有问题。
在 LVS 负载均衡器(MASTER 和 BACKUP)上
- 使用
ping
命令分别测试能否连通各个 Real Server 的 IP 地址,例如在 MASTER 节点上执行:
ping 192.168.1.102
ping 192.168.1.103
- 若都能正常收到回应,表明负载均衡器与后端 Real Server 之间的网络连接正常,不存在物理层面的网络故障,这是后续负载均衡功能能正常发挥的基础条件。
验证虚拟 IP(VIP)绑定情况
- 在 LVS 负载均衡器(MASTER)上
- 执行
ip addr show
命令查看网卡信息,检查 VIP 是否正确绑定在 MASTER 节点的网卡上,正常情况下应该能看到类似如下输出(假设网卡名为eth0
):
- 执行
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_RETURNS> mtu 1500 qid 10000
link/ether 00:11:22:33:44:55
inet 192.168.1.100/24 brd 192.168.1.255 scope global noprefixroute eth0
inet 192.168.1.200/24 brd 192.168.1.255 scope global secondary noprefixroute eth0
- 其中
inet 192.168.1.200/24
这一行就表示 VIP 已成功绑定在该网卡上,这意味着 MASTER 节点已经做好准备利用此 VIP 接收客户端请求并进行负载均衡处理。
- 手动停止 MASTER 节点的 Keepalived 服务(仅用于测试 VIP 切换)
- 在 MASTER 节点上执行
systemctl stop keepalived
命令。 - 接着迅速在 LVS 负载均衡器(BACKUP)上再次执行
ip addr show
命令查看网卡信息,此时应该能看到 VIP 已经切换绑定到 BACKUP 节点的网卡上,类似如下输出(同样假设网卡名为eth0
):
- 在 MASTER 节点上执行
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_RETURNS> mtu 1500 qid 10000
link/ether 00:11:22:33:44:55
inet 192.168.1.101/24 brd 192.168.1.255 scope global noprefixroute eth0
inet 192.168.1.200/24 brd 192.168.1.255 scope global secondary noprefixroute eth0
- 这就验证了 Keepalived 的高可用切换机制生效,VIP 能够在主节点故障时自动迁移到备份节点,保障服务持续可用。完成测试后,可以在 MASTER 节点上再次执行
systemctl start keepalived
恢复正常状态。