资讯动态

LVS负载均衡集群:DR模式原理与CentOS 7.6部署实战

发布时间:2026/10/14 14:12:36 来源:尧图企业网站定制
做运维这几年几乎每个业务量上来的公司都要面对同一个问题一台服务器扛不住流量了怎么办加CPU加内存是条路但单机总有物理上限而且一挂全完。这时候大家第一反应就是搞群集而群集架构里最经典、最成熟、也是最常被拿出来讨论的一块就是LVS负载均衡。LVSLinux Virtual Server是在Linux内核层面实现的一套负载均衡方案它不依赖第三方软件在应用层转发而是直接由内核处理网络包性能损耗极小做得好能支撑到百万级别并发。这篇文章我打算把LVS的原理、三种工作模式、调度算法和CentOS 7.6下的DR模式完整部署全部过一遍适合刚接触群集架构的运维新手也给准备把LVS用在生产环境的老手一些避坑参考。1. LVS是什么从群集架构说起1.1 群集架构的基本形态群集就是把多台服务器组织起来对外看起来就像一台服务器在工作。一个标准的负载均衡群集通常由三部分组成前端调度器、后端服务器池、共享存储或数据库。调度器负责接收客户端请求再按照某种策略转发给后端某台服务器处理。我见过很多新手会混淆“群集”和“分布式”这里简单区分一下群集强调的是多台机器协同完成同一类任务对外是透明的一个整体分布式强调的是把一个任务拆成多个子任务交给不同机器并行处理。LVS属于前者它的职责很简单就是“分流”。它不关心你业务层跑的是PHP还是Java不关心数据库在哪它只做一件事把进来的网络请求高效地转发给后端服务器池中的某台机器。在CentOS 7.6这种老而稳的系统上部署LVS至今仍是不少生产环境的标配。原因很简单稳定、性能高、配置逻辑清晰而且一旦配合Keepalived做高可用整个入口层的可靠性会非常高。1.2 为什么选择LVS而不是别的方案市面上负载均衡方案很多光软件层面的就有Nginx、HAProxy、Traefik硬件的有各种负载均衡设备。那为什么还要用LVS我的看法是它解决的是“入口流量太大应用层软件扛不住”的问题。Nginx本身是七层转发要解析HTTP头、做反向代理单位时间能处理的并发连接数和LVS完全不是一个量级而LVS工作在四层直接在内核空间转发数据包不涉及用户态和内核态的频繁切换性能损耗极低。另一个关键优势是LVS不感知应用协议。它既能转发HTTP流量也能转发MySQL、Redis、TCP长连接等任意四层协议。我做过的项目里甚至有人在LVS后面挂了一组RDP网关效果也不错。相比之下Nginx做四层转发用的是stream模块性能和灵活性还是差一点。这几年云厂商的负载均衡产品确实很成熟但如果是在IDC自有机房、或者纯内网环境里做架构LVS仍然是性价比很高的选择。它不需要额外license不占太多资源CentOS 7.6自带的2.6.32内核里ipvs模块已经非常稳定用起来很省心。1.3 LVS的核心组件与工作角色LVS由两部分组成内核模块ipvs和用户态管理工具ipvsadm。ipvs是工作在Netfilter框架里的核心代码负责真正处理数据包ipvsadm是命令行工具用来增删虚拟服务、配置后端真实服务器、查看连接状态。从角色上看LVS群集里通常有三种角色调度器Director也就是LVS所在的主机负责接收外部请求并按算法转发。真实服务器Real Server简称RS真正干活的应用服务器比如Nginx、Tomcat。共享存储或数据库可选给后端服务器提供一致的数据源。理解这三个角色后再看LVS的配置就轻松了。我们在调度器上定义一个虚拟服务VIP把一堆RS挂在这个VIP下面设置好调度算法和转发模式一条命令就能完成基本配置。真正麻烦的不是敲命令而是搞清楚数据包在三种工作模式下分别是怎么走的以及为什么某一种模式在某种网络环境下绝对不能用。接下来我把三种模式逐一拆开讲。2. LVS的三种工作模式原理拆解2.1 NAT模式改地址最直观NAT模式的全称是Virtual Server via Network Address Translation翻译过来就是“通过网络地址转换实现的虚拟服务器”。它的流程可以用一句话概括客户端访问VIP调度器把请求的目的地址改成某台RS的IP再转发出去RS处理完把响应回给调度器调度器再把源IP改成VIP送回客户端。这个模式最大的优点是后端服务器只需要一个内网IP网关指向调度器即可安全性很好因为真实的RS地址不会暴露给客户端。但缺点也很致命所有进出流量都要经过调度器调度器很容易变成瓶颈。比如客户端的下行流量大RS的响应数据量大那么调度器的网卡和内核转发压力都会很大。实测经验是NAT模式在中小型业务、流量比较均衡的场景里完全够用但如果单台调度器的吞吐量逼近网卡上限就不要硬撑要么换DR模式要么做多调度器横向扩展。配置NAT模式时还有一个容易踩的坑必须开启内核的IP转发功能。很多人配置文件敲好了但忘了改net.ipv4.ip_forward结果流量进来就丢。这个参数我记得在生产环境里至少要确认两遍。2.2 DR模式改MAC性能之王DR模式的全称是Direct Routing直译为“直接路由”。它是我在生产环境里最推荐的模式也是大部分LVS集群采用的方式。原理上客户端访问VIP调度器收到请求后把数据帧的目标MAC地址改为某台RS的MAC地址然后直接把帧扔到交换机上RS收到后解封装发现目的IP是自己的VIP就正常处理。这里面最关键的一点是RS上必须把VIP绑定到回环接口并且要抑制对VIP的ARP响应否则整个交换机上的机器都会跟调度器抢“我是VIP”这个身份网络直接混乱。响应包不走调度器而是由RS直接回给客户端所以DR模式下的调度器只处理入站流量负载压力比NAT模式小太多。DR模式对网络环境有个硬性要求所有RS必须和调度器在同一个二层网络里至少路由上要允许帧直接到达RS。跨网段、跨机房就别想用纯DR这时候要么做TUN要么上云负载均衡产品。另外RS上通常还要把VIP绑在lo接口上并设置子网掩码为255.255.255.255这是为了让VIP的应答包不走默认路由出异常。我记得第一次做DR模式时最常犯的错误就是在RS上启动了一个监听VIP的httpd却忘了做ARP抑制结果整个交换机上所有机器时不时出现“arp缓存紊乱”的现象。所以这篇文章后面实操部分我会把ARP配置放到最高优先级去讲。2.3 TUN模式隧道封装跨机房必选TUN模式全称是Virtual Server via IP Tunneling简单说就是调度器把数据包封装在另一个IP包里面通过IP隧道发给RS。RS收到后解封装发现内部的VIP目的地址是自己就处理业务响应直接回给客户端。这种模式比DR强的地方在于RS可以不在同一个二层网络。比如调度器在北京机房RS在上海机房只要三层能通就能用TUN模式把请求转发过去。但同时它的代价也很明显封装和解封装都有CPU开销而且需要RS的内核支持隧道协议。实际生产中用TUN的远少于DR大部分情况下业务需要跨地域调度时大家更倾向于在两个机房分别部署LVS集群再用上层DNS或全局负载均衡做调度。我个人的建议是如果只是在一个数据中心内部做负载均衡优先选DR如果网络拓扑比较复杂、RS分布在多个网段可以考虑TUN但要做好性能测试别盲目上。三种模式的对比我整理成了一个表格方便对照模式调度器压力响应路径网络要求后端配置复杂度NAT入站出站都过调度器压力大必须回调度器RS网关指向调度器跨网段可以低DR只处理入站性能最好RS直接回客户端必须在同一二层网络中需VIPARP抑制TUN入站封装转发压力中等RS直接回客户端三层可达即可跨网段可用高需配置隧道3. 调度算法详解10种算法怎么选3.1 静态调度算法适合齐整场景LVS的调度算法分为静态和动态两大类。静态算法不会根据后端实时负载变化调整分配策略它们只看预设的权重和轮询顺序。RRRound Robin轮询把请求依次分配给每台RS1、2、3、1、2、3这样转。适合后端机器配置完全一样的场景。WRRWeighted Round Robin加权轮询给每台RS设置权重权重高的RS分到更多请求。比如两台机器一个权重2一个权重1那大概就是三份请求里两份给前者、一份给后者。DHDestination Hashing目的地址哈希按请求的目的IP做哈希把相同目的IP的请求固定发给同一台RS。这个场景常用于多级缓存配合一致性哈希能提高缓存命中率。SHSource Hashing源地址哈希按客户端源IP做哈希相同来源的请求固定发给同一台RS。适合做会话保持但不建议用在连接分布极度不均匀的场景因为容易把某台机器打爆。静态算法的特点是简单、可控、没有额外的计算开销。在后端机器配置均衡、每个请求处理时间差不多的场景里用RR或者WRR足够。但现实情况往往没这么理想有的RS跑了一个重接口慢有的RS磁盘快这时候就轮到动态算法上场。3.2 动态调度算法适配真实负载动态调度的核心是“看后端当前状态再决定转发给谁”。LVS会维护每个RS当前的连接数并结合活跃连接/非活跃连接来算出一个负载值。LCLeast Connections最少连接哪台RS当前连接数最少就把请求发给谁。但没考虑权重机器配置不一样时容易偏。WLCWeighted Least Connections加权最少连接在LC基础上引入权重这也是LVS默认的调度算法。计算公式里会把连接数除以权重再比较谁更小。SEDShortest Expected Delay最短预期延迟在WLC基础上再考虑“已经活跃的连接预计还要处理多久”对延迟敏感的场景更友好。NQNever Queue永不排队当所有RS都已有活跃连接时保证新请求一定被分发出去不会排到某台机器后面傻等。LBLCLocality-Based Least Connections基于局部性的最少连接这是针对后端缓存场景的它会尽量把相同目的IP的请求分到同一台RS提高缓存命中率。LBLCR带复制的基于局部性的最少连接比LBLC更进一步允许同一目的IP的请求在多台RS之间切换适合缓存经常被淘汰的场景。选动态算法不能只看字面意思得结合业务模型。我做过一个视频点播系统后端每台机器处理一个请求需要比较长的时间这时候SED就比WLC效果好因为SED会把新请求分给那些“预期完成时间最短”的机器而不是单纯看连接数。3.3 我的选型心得这里分享几条多年运维摸出来的经验后端机器能力完全一样请求处理时长也差不多用RR或WRR就够了别上动态算法徒增内核开销。后端机器能力有差异或请求处理时长波动大优先WLC它是默认值经过了最多的生产环境验证。有会话保持要求比如用户登录状态保存在本机用SH尽量保证同一客户端的请求固定到同一台RS。有缓存服务比如用户画像、公共配置可以考虑LBLC或SH具体哪个好要做压测看命中率。还有一个容易被忽略的点调度算法可以在不删除虚拟服务的情况下动态切换。比如线上正跑着WLC你想改成WRR只需要重新执行一次ipvsadm -E把-s参数改掉即可连接不会中断。这在调优时候特别方便不用重启服务、不用等流量淡季。4. 环境规划与部署准备4.1 集群拓扑与IP规划在CentOS 7.6上做LVS部署第一步不是装软件而是把IP规划和网络拓扑理清楚。我这里用一个最典型的DR模式拓扑举例LVS调度器一台CentOS 7.6服务器双网卡一个IP用于管理192.168.1.100一个VIP用于对外192.168.1.200。后端RS1192.168.1.11上面跑Nginx提供Web服务。后端RS2192.168.1.12上面跑Nginx提供Web服务。所有机器都接在同一个二层交换机下。IP规划表角色接口IP地址说明LVS-Directoreth0192.168.1.100/24管理及转发VIPeth0:0192.168.1.200/32虚拟服务地址客户端访问入口RS1eth0192.168.1.11/24后端真实服务器1RS1-LOlo:0192.168.1.200/32绑定VIP仅用于接收RS2eth0192.168.1.12/24后端真实服务器2RS2-LOlo:0192.168.1.200/32绑定VIP仅用于接收这里要特别注意RS上绑定的VIP子网掩码必须是32位也就是255.255.255.255。如果顺手填成24位RS会以为整个192.168.1.0/24网段都在自己的回环接口上路由表会变得非常奇怪连外网都可能丢包。4.2 基础环境配置先把所有机器的防火墙和SELinux状态确认一下。CentOS 7.6默认是firewalld管理防火墙生产环境建议按需开放端口而不是直接关防火墙。但在实验和学习阶段我会先把防火墙清掉避免排查半天才发现是防火墙丢包。SELinux推荐设为permissive或者直接disabled因为LVS本身不涉及SELinux标签问题但后端的Nginx或者业务程序很可能被SELinux限制提前关掉能省很多事。还需要确认内核模块ipvs已经加载。CentOS 7.6的内核默认编译了ipvs相关模块但有时没有自动加载。查看方式lsmod | grep ip_vs如果没有输出就手动加载modprobe ip_vs modprobe ip_vs_rr modprobe ip_vs_wrr modprobe ip_vs_sh然后安装ipvsadm如果内网没有挂载ISO源直接用yum就可以yum install -y ipvsadm安装完成后可以用ipvsadm -v看版本。实际测试里CentOS 7.6默认源的ipvsadm版本是1.27完全够用。如果你要更细粒度的连接状态查看建议装一下kernel-devel方便后续编译一些辅助工具。5. 实操部署DR模式完整过程5.1 配置LVS调度器登录到调度器192.168.1.100先配置VIP。VIP可以绑定在物理网卡上也可以绑定在子接口上。我习惯用子接口方便后面起多个VIPifconfig eth0:0 192.168.1.200 netmask 255.255.255.255 broadcast 192.168.1.200 up这里子网掩码写成32位是为了避免VIP广播地址影响交换机上的其他机器。配置完成后用ip addr show eth0:0确认一下。然后开始配置LVS虚拟服务。第一条命令创建对外的VIP和端口第二条命令把RS1挂上去第三条命令把RS2挂上去ipvsadm -A -t 192.168.1.200:80 -s wrr ipvsadm -a -t 192.168.1.200:80 -r 192.168.1.11:80 -g -w 1 ipvsadm -a -t 192.168.1.200:80 -r 192.168.1.12:80 -g -w 2解释一下这三个参数-A表示添加一个虚拟服务-t指定是TCP协议并给出VIP和端口-s wrr表示使用加权轮询算法-a表示添加真实服务器-r指定RS地址和端口-g表示使用DR模式Gatewaying直连路由模式-w设置权重。配置完成后用ipvsadm -L -n查看当前配置IP Virtual Server version 1.2.1 (size4096) Prot LocalAddress:Port Scheduler Flags - RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 192.168.1.200:80 wrr - 192.168.1.11:80 Route 1 0 0 - 192.168.1.12:80 Route 2 0 0这一步正常情况下没有任何报错就代表配置成功。但注意此时后端RS还没配置直接访问VIP是不通的。5.2 配置后端真实服务器后端服务器要做的第一件事是让本机认领VIP。注意不是配置在eth0上而是配置在回环接口lo:0上。这样做的目的是让本机能够接收目的地址为VIP的数据包同时不会把VIP广播到交换机上ifconfig lo:0 192.168.1.200 netmask 255.255.255.255 broadcast 192.168.1.200 up route add -host 192.168.1.200 dev lo:0第二行增加一条主机路由确保数据包进入回环接口时不会被当成普通网络包转发出去。很多人漏掉这条route结果请求能到RS但响应包从默认网关出去了客户端收到响应后发现源IP是RS的IP而不是VIP直接被拒。然后是最关键的ARP抑制。在RS上执行echo 1 /proc/sys/net/ipv4/conf/lo/arp_ignore echo 2 /proc/sys/net/ipv4/conf/lo/arp_announce echo 1 /proc/sys/net/ipv4/conf/all/arp_ignore echo 2 /proc/sys/net/ipv4/conf/all/arp_announcearp_ignore1的意思是只回答目标IP是本机某个接口IP的ARP请求。因为VIP虽然在lo上但IP是32位主机地址别的机器问ARP时本机不会抢答。arp_announce2的意思是本机在发送ARP响应时尽量使用能够与目标IP匹配的接口IP避免把VIP的MAC地址暴露到整个二层网络。如果不做ARP抑制会发生什么我在测试环境里亲眼见过调度器和RS同时响应VIP的ARP查询交换机上的ARP表不停抖动有的客户端请求到了调度器有的直接到了RS负载均衡完全不生效且网络变得非常不稳定。5.3 配置Nginx并验证后端服务在RS1和RS2上分别准备一个测试页面确保两台机器能分别正常访问。我这里用Nginx做一个简单的响应区分yum install -y nginx systemctl start nginx echo I am RS1 /usr/share/nginx/html/index.htmlRS2上就写I am RS2。先用curl直接访问两台RS的IP应该能分别看到对应内容。这一步能提前排除Nginx本身的问题后面做负载均衡验证时只要看到内容在RS1和RS2之间交替就说明LVS生效了。5.4 全局验证负载均衡效果在客户端机器比如另一台同网段的机器上多次访问VIPcurl http://192.168.1.200/如果前面的配置都正确你会看到输出在I am RS1和I am RS2之间交替出现。因为WRR算法权重是1:2理论上RS2被访问到的次数更多。多刷几次大概能感觉到RS2出现的频率明显高于RS1。再用ipvsadm -L -n --stats看统计数据IP Virtual Server version 1.2.1 (size4096) Prot LocalAddress:Port Scheduler Flags - RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 192.168.1.200:80 wrr - 192.168.1.11:80 Route 1 0 3 - 192.168.1.12:80 Route 2 0 7从这个输出能直观看到RS2的请求数差不多是RS1的两倍说明权重生效了。也可以按CtrlC退出实时状态。我还习惯用ipvsadm -L -n --rate查看每秒转发速率这个参数能告诉你当前调度器实际承担的入站流量大小对判断是否快达到瓶颈很有帮助。6. 常见问题与排障实录6.1 VIP ping不通ARP抑制配置没同步这是DR模式最经典的问题。表现是客户端ping VIP直接超时但RS自己ping通。排查思路是确认调度器上VIP是否绑定成功、是否所有RS都做了ARP抑制、交换机上的ARP表是否残留异常。我在某次生产变更中遇到过诡异现象某几台机器ping VIP通另几台不通。后来抓包发现是有一台老RS的arp_announce配置被优化脚本覆盖了导致它一直在对外宣告自己就是VIP。把配置重新改成2等了ARP表老化之后现象立刻消失。所以每一次变更后都要做两次确认sysctl -a | grep arp看看实际生效值再在所有机器上执行arp -d清一下本地ARP缓存。6.2 请求始终只转发到同一台后端权重和算法需要调整如果配置了WRR但所有请求都跑同一台RS优先怀疑权重是否配错。用ipvsadm -L -n看RemoteAddress那几行Weight列如果有一台是0那它就不会被分配请求。还有一种可能后端某台RS健康检查不过。LVS本身不参与健康检查你需要配合keepalived或者自研脚本把故障RS从集群里摘除。我推荐直接用keepalived它除了做调度器高可用还能通过HTTP健康检查实时摘除故障RS。配置里核心是real_server块检测端口、超时时间、失败次数都可以调。健康检查策略我一般设成每3秒探测一次失败3次摘除成功2次恢复。6.3 rs和调度器不在同一网段的部署问题DR模式要求二层可达如果你在测试时用虚拟机需要确保虚拟机网络模式是“桥接”而不是“NAT”。VMware或某虚拟化平台的NAT模式会让RS和调度器处于不同虚拟网段DR模式根本跑不起来。如果确实网络环境不支持DR那就切换到NAT模式。把调度器当成路由器用RS的默认网关指向调度器然后开启net.ipv4.ip_forward1。NAT模式下不用绑定VIP到RS的lo口也不用做ARP抑制配置反而更简单就是性能受限。6.4 高可用集群里keepalived与LVS的配合问题单台LVS调度器挂了整个集群就瘫痪了。所以生产级别一定要做双调度器加keepalived。keepalived的功能有两个提供VIP飘移以及提供健康检查。配置时两台调度器上都跑keepalived同一时间只有主节点持有VIP。有个极易踩的坑keepalived的lvs_sync_daemon如果不配合多播或单播配置状态同步可能失败导致主备切换后连接信息丢失。我建议在global_defs里关闭VRRP组播改用单播地址来指定对端这样可以避免交换机上没有开启多播引起的同步问题。另外keepalived探测后端RS时最好用TCP_CHECK而不是简单的HTTP_GET因为HTTP探测会消耗Nginx的CPU资源在高并发时反而给后端带来额外压力。TCP_CHECK只是建立连接然后就断开对后端最友好。6.5 连接跟踪与超时调优LVS会维护一张连接表记录每个连接分发到了哪台RS。如果业务里有大量短连接比如API接口你会发现ipvsadm -L -n --timeout看到的TCP超时时间默认是900秒。这个长超时会导致连接表膨胀影响性能。我常用的优化是把TCP超时调到60秒UDP调到300秒ipvsadm --set 60 300 900这三个值分别对应TCP空闲超时、UDP空闲超时、FIN_WAIT状态的超时。调完以后连接表回收速度明显加快调度器的内存占用也会降下来。7. 生产环境落地建议7.1 LVS与Nginx的分工LVS做入口层的四层转发Nginx在后端做七层反向代理这是我目前用下来最舒服的架构。客户端到LVSLVS把流量分给几台NginxNginx再根据域名或URL路径把请求转发到不同的应用服务器。这样LVS只干“粗活”Nginx干“细活”各司其职。举个例子某个电商项目峰值流量每秒上万请求如果让Nginx直接面对入口流量CPU会大量消耗在TCP连接处理上真正花在应用转发上的时间反而少了。而LVS在内核层面就把连接分开了Nginx只需要处理经过均衡器分过来的连接整个系统吞吐量能翻不少。7.2 会话保持怎么解决LVS的SH算法能按源IP做会话保持但现实是移动网络、NAT网关下很多用户会共享同一个出口IP导致某个用户的请求全被固定到一台RS上其他RS闲着。这种情况我一般建议把会话数据集中存储到Redis或Memcached而不是依赖负载均衡层做会话保持。比如在后端应用代码里把session存到Redis然后LVS层随便用哪种算法都没关系因为任何一台RS都能从Redis取到会话数据。这个方案在扩容时也更友好新加RS不用预热任何本地会话。7.3 监控与容量规划监控LVS最直接的指标是ipvsadm -L -n --stats里的连接数和转发字节数。我还会采集调度器的CPU、网卡丢包率、软中断分布。如果发现单个CPU核的软中断占比很高可以考虑启用网卡多队列或者把调度器的网卡从1G升级到10G。容量规划上一台普通配置的调度器跑DR模式处理小包转发能到几十万PPS跑大包HTTP流量吞吐量主要受网卡带宽限制。当网卡使用率超过70%时就该考虑横向扩容加一台调度器并配合keepalived做双活。这里有个实操心得LVS调度器一定要禁用不必要的服务像postfix、chronyd客户端这类不影响业务的东西该关就关。因为调度器一旦成为瓶颈任何额外的用户态进程都可能跟内核抢CPU。7.4 配置持久化与自动化ipvsadm敲进去的配置是临时的重启就没了。生产环境必须持久化。CentOS 7.6上用ipvsadm-save导出配置ipvsadm-save /etc/sysconfig/ipvsadm然后用systemd管理systemctl enable ipvsadm systemctl start ipvsadm如果是用keepalived管理LVS则不需要这个持久化因为keepalived会按配置文件重建LVS规则。但我仍然习惯把配置写进Git仓库用Ansible之类的工具分发到所有调度器确保主备节点的LVS规则一模一样。曾经出过一次事故就是人为漏同步了一条规则导致主备切换后有部分请求直接失败。最后再分享一个我自己的习惯每次配置完LVS我都会跑到客户端机器上连续执行几十次curl然后对比后端日志里的访问来源确认负载确实是按照预期分发的。这个过程看起来笨但能最快发现ARP配置、网卡绑定、路由策略这些看起来和LVS“无关”的坑。LVS本身不复杂复杂的是它所在的那张网络大网只要把网络细节管住了这个方案能稳稳跑很多年。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑