1. 从零开始:为什么你需要这套“黄金组合”?

做运维的朋友,尤其是负责线上业务的,最怕听到的两个词可能就是“单点故障”和“流量洪峰”。我经历过好几次,半夜被电话叫醒,一看监控大屏一片飘红,核心服务挂了,原因可能只是一台负载均衡器的网卡松动或者系统更新后没启动服务。那种手忙脚乱、血压飙升的感觉,真的不想再体验。所以,搭建一个既能把流量合理分摊、又能在某台机器宕机时自动顶上的高可用集群,就成了保命符。

今天要聊的LVS+Keepalived+Nginx,就是我用了很多年,觉得特别稳的一套组合拳。简单来说,它把三样东西的优势拧成了一股绳:

  • LVS:工作在Linux内核层,像个不知疲倦的“交通指挥”,性能极高,专门负责把网络请求分发给后端的服务器。但它自己是个“哑巴”,不会说话,如果自己挂了,整个路口就瘫痪了。
  • Keepalived:这就是给LVS配的“贴身保镖”和“秘书”。它通过VRRP协议搞出来一个“虚拟IP”(VIP),对外就一个地址。它时刻监控着LVS的健康状态,一旦主“指挥”累趴下(故障),备用“指挥”立刻接过VIP和指挥权,用户完全无感知。这就是高可用。
  • Nginx:放在真实服务器上。LVS只管四层(IP和端口)转发,到了后端,Nginx可以处理七层(HTTP/HTTPS)的复杂规则,比如根据URL转发到不同服务、做缓存、限流等,功能非常灵活。

这套架构特别适合中小型企业的Web服务、API网关,或者任何需要对外提供稳定HTTP/HTTPS访问的场景。你不用一开始就上几十万的硬件负载均衡设备,用普通的Linux服务器就能搭建出企业级的扛流量能力。接下来,我就手把手带你,用四台机器,从环境准备到最终测试,把这套系统跑起来。

2. 动手之前:理清架构与备好“食材”

在真正敲命令之前,咱们得先把厨房收拾好,菜谱看清楚。磨刀不误砍柴工,这一步理清了,后面能避开很多坑。

2.1 集群架构全景图

咱们这次要搭建的是一个经典的主备模式高可用负载均衡集群。你可以准备四台虚拟机或物理机,配置不用太高,CentOS 7或者Ubuntu 20.04以上都行。为了让你看得更明白,我画个简单的角色分工表:

角色主机名(示例)IP地址(示例)核心软件职责
主负载均衡器lb-master192.168.199.149LVS, Keepalived平时负责流量转发,是集群的“老大”。
备负载均衡器lb-backup192.168.199.150LVS, Keepalived平时待命,监控老大状态,随时准备接班。
虚拟IP (VIP)-192.168.199.148-对外提供服务的唯一IP,用户只访问这个地址。由Keepalived管理,在主备机之间漂移。
真实服务器1web-01192.168.199.155Nginx实际处理用户请求的后端服务器,运行你的网站或应用。
真实服务器2web-02192.168.199.156Nginx同上,实现业务水平扩展。

核心工作流程:用户访问 http://192.168.199.148 -> 请求到达VIP -> 当前持有VIP的主负载均衡器(比如149) 上的LVS根据规则(比如轮询)将请求转发给后端的155或156 -> 155/156上的Nginx处理请求并返回结果。

如果主负载均衡器(149)宕机,Keepalived会检测到,备用机(150)会在秒级内抢占VIP(148),并接管LVS的转发工作。整个过程对用户透明,服务不中断。

2.2 基础环境统一与调优

登录所有四台机器,先把基础环境弄一致,这是保证集群稳定性的前提。

第一步:关闭防火墙和SELinux(生产环境请根据安全策略调整) 这是为了避免网络策略阻拦集群内部的健康检查和数据转发。在四台机器上分别执行:

# 关闭防火墙(CentOS 7)
systemctl stop firewalld
systemctl disable firewalld

# 关闭SELinux(立即生效+永久生效)
setenforce 0
sed -i 's/^SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

注意:生产环境中,更安全的做法是配置防火墙规则,开放必要的端口(如VRRP协议用的112,健康检查端口等),而不是直接关闭。这里为了演示简化处理。

第二步:配置主机名和hosts解析(可选但推荐) 给每台机器设置好主机名,并在/etc/hosts文件中添加所有节点的IP和主机名对应关系。这样在查看日志和配置时更清晰。

# 以lb-master为例,设置主机名
hostnamectl set-hostname lb-master

# 编辑所有机器的 /etc/hosts,添加如下行
192.168.199.149 lb-master
192.168.199.150 lb-backup
192.168.199.155 web-01
192.168.199.156 web-02

第三步:时间同步 集群内时间不一致可能导致日志分析混乱,甚至影响某些应用。务必配置NTP时间同步。

yum install -y ntpdate  # CentOS
# 或 apt install -y ntpdate  # Ubuntu

# 同步时间
ntpdate time.windows.com
# 可以配置cron定时任务,例如每小时同步一次
echo "0 */1 * * * /usr/sbin/ntpdate time.windows.com > /dev/null 2>&1" >> /var/spool/cron/root

3. 核心配置:一步步搭建负载均衡与高可用

基础打牢了,现在开始给每台机器安装“灵魂”软件。

3.1 配置主备负载均衡器(LVS + Keepalived)

我们的主备机(149和150)需要安装两个核心软件:ipvsadm(用于管理LVS规则)和keepalived。

安装软件包:

# 在 lb-master (149) 和 lb-backup (150) 上执行
yum install -y ipvsadm keepalived

ipvsadm是用户空间管理LVS内核模块的工具,keepalived则负责高可用和健康检查。

配置主负载均衡器(lb-master, 149): Keepalived的配置文件是 /etc/keepalived/keepalived.conf。我们先清空或备份原文件,然后写入以下配置。我会在关键地方加注释,你一定要理解。

vim /etc/keepalived/keepalived.conf
! 全局定义,主要定义路由器的ID,每个节点必须唯一
global_defs {
   router_id LVS_MASTER_149  # 标识本节点,我习惯用角色+IP尾数
}

! VRRP实例配置,这是实现高可用的核心
vrrp_instance VI_1 {
    state MASTER           ! 初始状态,这台机器是'主'
    interface ens33        ! 绑定VIP的网卡名称,用`ip addr`命令查看你自己的
    virtual_router_id 51   ! 虚拟路由ID,主备必须相同,范围0-255
    priority 100           ! 优先级,主节点要高于备节点
    advert_int 1           ! 主备之间心跳检查间隔,单位秒

    ! 认证信息,主备必须一致,防止非法设备加入
    authentication {
        auth_type PASS
        auth_pass 1111     ! 密码,建议修改
    }

    ! 虚拟IP(VIP),就是对外服务的那个IP
    virtual_ipaddress {
        192.168.199.148/24
    }
}

! 定义LVS的虚拟服务器(Virtual Server)
virtual_server 192.168.199.148 80 {
    delay_loop 6          ! 健康检查间隔
    lb_algo rr            ! 负载均衡调度算法,rr是轮询,还有wrr(加权轮询)、lc(最少连接)等
    lb_kind DR            ! LVS工作模式,DR(直接路由)模式性能最好,也是我们用的
    persistence_timeout 0  ! 会话保持时间(秒),0表示关闭。电商购物车场景可能需要设置
    protocol TCP          ! 转发协议

    ! 真实服务器池(Real Server Pool)
    real_server 192.168.199.155 80 {
        weight 1          ! 权重,值越大分配的请求越多
        ! TCP健康检查
        TCP_CHECK {
            connect_port 80
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }

    real_server 192.168.199.156 80 {
        weight 1
        TCP_CHECK {
            connect_port 80
            connect_timeout 3
            nb_get_retry 3
            delay_before_retry 3
        }
    }
}

保存退出后,启动并设置开机自启:

systemctl start keepalived
systemctl enable keepalived

检查VIP是否已经绑定到主机的网卡上:

ip addr show ens33

你应该能看到类似 inet 192.168.199.148/24 scope global secondary ens33 的行,说明VIP配置成功了。

配置备负载均衡器(lb-backup, 150): 备机的配置文件和主机绝大部分相同,只有三个关键参数需要修改:

  1. state 从 MASTER 改为 BACKUP。
  2. priority 从 100 改为一个较低的值,比如 90。
  3. router_id 要改成唯一的,比如 LVS_BACKUP_150。

把修改好的配置文件传到备机,或者直接在备机上编辑。同样启动服务:

systemctl start keepalived
systemctl enable keepalived

此时,备机不会抢占VIP,它会监听主机的状态。你可以用 ip addr show ens33 确认备机上没有VIP 192.168.199.148。

3.2 配置后端真实服务器(Nginx)

现在配置干活的两台机器,web-01(155)和web-02(156)。

安装并启动Nginx:

# 在两台Web服务器上执行
yum install -y nginx
systemctl start nginx
systemctl enable nginx

为了测试时能区分开是哪台服务器响应的,我们简单修改一下Nginx的默认首页:

# 在 web-01 (155) 上执行
echo "This is Real Server 01 - 192.168.199.155" > /usr/share/nginx/html/index.html

# 在 web-02 (156) 上执行
echo "This is Real Server 02 - 192.168.199.156" > /usr/share/nginx/html/index.html

配置LVS DR模式的关键——回环接口(Loopback) 这是LVS DR模式最容易出错的一步。原理是:请求通过LVS转发到真实服务器时,目标IP还是VIP(148)。为了让真实服务器能处理这个以VIP为目标地址的请求,并且不让它用VIP地址往外回应(回应必须走LVS),我们需要在真实服务器上配置一个特殊的回环接口。

# 在 web-01 和 web-02 上分别创建配置文件
vim /etc/sysconfig/network-scripts/ifcfg-lo:0

写入以下内容(注意DEVICE名和IPADDR):

DEVICE=lo:0
IPADDR=192.168.199.148
NETMASK=255.255.255.255
ONBOOT=yes
NAME=loopback

然后,需要抑制ARP响应,避免真实服务器宣告自己拥有VIP,造成IP冲突。创建ARP抑制的配置文件:

vim /etc/sysctl.conf

在文件末尾添加:

# 抑制ARP响应,对于LVS DR模式至关重要
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.default.arp_ignore = 1
net.ipv4.conf.default.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2

使配置生效:

sysctl -p

最后,启动回环接口并添加路由:

ifup lo:0
# 添加一条主机路由,确保访问VIP的包从lo:0进来
route add -host 192.168.199.148 dev lo:0

重要:这条路由重启后会消失,你需要把它加到 /etc/rc.local 文件中以实现开机自启(记得给rc.local文件加执行权限 chmod +x /etc/rc.local)。

4. 功能验证与深度调优

配置都完成了,是骡子是马,拉出来遛遛。

4.1 基础功能测试

打开你的浏览器,访问 http://192.168.199.148。疯狂刷新页面,你应该能看到页面内容在“This is Real Server 01...”和“This is Real Server 02...”之间交替出现。这说明LVS的轮询(rr)调度算法生效了,负载均衡搭建成功!

高可用故障模拟测试: 这才是检验“高可用”成色的时刻。在主负载均衡器(lb-master, 149)上,执行:

systemctl stop keepalived

或者更狠一点,直接关闭这台虚拟机。然后快速(几秒内)刷新浏览器,或者用curl命令测试:

curl http://192.168.199.148

你会发现,服务依然可以访问!此时,立刻登录到备机(lb-backup, 150)上,执行 ip addr show ens33,你会惊喜地看到,VIP(148)已经飘移到了这台机器上。同时,备机上的Keepalived会接替LVS的转发工作。整个切换过程,对于前端用户来说,可能只是感受到一次轻微的网络抖动或短暂的延迟,服务本身没有中断。

恢复主节点服务后(systemctl start keepalived),VIP通常会因为主节点更高的优先级而自动抢回来,这取决于你的nopreempt等参数设置。

4.2 性能与稳定性调优

基础功能跑通只是第一步,要让它在生产环境扛住压力,还得做些精细调整。

调整Keepalived参数:

  • advert_int:心跳间隔。网络环境好可以保持1秒,如果网络有抖动,可以适当调大(如2或3),减少误切换。
  • authentication:生产环境务必使用更复杂的auth_pass密码。
  • delay_loop:LVS健康检查间隔。太短会增加负载,太长则故障发现慢。6秒是个折中的起点。

调整LVS调度算法: lb_algo rr(轮询)是最简单的。根据业务场景可以选择:

  • wrr(加权轮询):如果web-01性能更强,可以设置weight 2,web-02设置weight 1,这样155会接到大约两倍的请求。
  • lc(最少连接):将新请求发给当前连接数最少的服务器,更公平。
  • sh(源地址哈希):同一个客户端的请求总是发给同一台服务器,适合需要会话保持但又没做集中Session管理的场景。

关于persistence_timeout的坑: 原始文章最后提到了一个“负载均衡效果不明显”的问题,指的就是这个参数。它定义了会话保持时间。如果设置为50,那么同一个客户端IP在50秒内发来的所有请求,都会发给同一台真实服务器。这在测试轮询效果时是个干扰项!因为你用同一个电脑刷新,可能一直访问到同一台后端。所以,在测试负载均衡分发效果时,务必将其设为0。等正式上线后,如果业务需要(如购物车),再根据Session有效期来设定这个值。

开启LVS连接跟踪: 对于FTP、视频会议等有状态服务,可能需要开启LVS的连接跟踪功能。这需要在真实服务器内核加载ip_vs模块时启用相关参数,或者在Keepalived的virtual_server段中为特定协议配置persistence_granularity等。

5. 实战排坑与运维心得

这套体系虽然稳定,但我在实际部署和维护中也踩过不少坑。分享几个典型案例,希望能帮你提前避雷。

坑一:健康检查失败,真实服务器被误踢 有一次,后端Nginx服务明明正常,但Keepalived的日志里一直报TCP_CHECK超时,导致真实服务器被从池子里移除。排查后发现,是后端服务器的本地防火墙(iptables)没开80端口。教训:确保LVS的健康检查端口(在TCP_CHECK块里定义的connect_port)在后端服务器的防火墙上是放行的。可以用telnet <real_server_ip> <port>从LVS主机上测试连通性。

坑二:DR模式下的ARP冲突导致VIP访问异常 这是最经典的问题。表现为VIP时而能通时而不通。根本原因就是ARP抑制没做好,导致多台机器同时响应了对于VIP的ARP请求。务必检查:

  1. 真实服务器上的arp_ignore和arp_announce参数是否配置正确并生效(sysctl -p)。
  2. 回环接口lo:0的掩码必须是255.255.255.255(主机掩码),而不是255.255.255.0。
  3. 使用arping命令在局域网内测试,只有当前持有VIP的负载均衡器应该响应VIP的ARP请求。

坑三:脑裂(Split-Brain) 主备两台负载均衡器都认为自己是Master,都绑定了VIP。结果就是数据包来回窜,服务彻底混乱。这通常是因为主备之间的心跳线(网络)不通。解决:

  1. 确保主备机之间网络通畅,防火墙开放了VRRP协议使用的IP协议号112(或你自定义的)。
  2. 在Keepalived配置中,可以启用vrrp_strict模式,或配置额外的track_interface来监控上行链路,如果网卡down了,自身优先级降低。
  3. 使用第三方脚本,通过多一条网络路径(如通过后端交换机)进行二次仲裁。

日常运维建议:

  • 日志是关键:多关注/var/log/messages(CentOS)或/var/log/syslog(Ubuntu)中Keepalived的日志,以及journalctl -u keepalived的输出。
  • 监控状态:使用 ipvsadm -Ln 命令可以清晰看到当前LVS的虚拟服务器、调度算法以及各个真实服务器的连接数、权重和状态(Forward代表健康)。
  • 优雅上下线:在重启或下线某台真实服务器前,可以先用ipvsadm命令手动将其权重设为0,等连接排空后再操作,实现流量无损迁移。

这套LVS+Keepalived+Nginx的组合,我经手过的项目里,支撑过日PV百万级别的网站,稳定性非常可靠。它的优势就在于层次分明、各司其职,用开源软件的成本达到了商业硬件的效果。希望这份超详细的指南,能帮你顺利搭建起自己的高可用堡垒,睡个安稳觉。

更多推荐