ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

LVS负载均衡全解析:DR模式部署与生产实践避坑指南

LVS负载均衡全解析:DR模式部署与生产实践避坑指南 在Linux上做负载均衡你迟早会撞上LVS这个名字。我最早接触它是在一组4核8G虚拟机要扛每秒上万请求的项目里业务方问“Nginx不就行了为什么还要用LVS”我只能把架构图摊开慢慢讲客户端请求先进LVS这一层由内核直接选一台后端转发Nginx只处理静态资源和反向代理逻辑两者各干各的。LVS全称Linux Virtual Server核心思路是把负载均衡功能做进Linux内核数据包不需要反复拷贝到用户态性能天然占优。这篇文章我会把LVS的原理、三种工作模式、调度算法和一套可直接抄作业的DR模式部署流程完整地讲一遍顺带把我在生产环境踩过的坑、排查手段都记录下来适合正在选型负载均衡方案、或者已经在用LVS但总感觉“知其然不知其所以然”的读者参考。1. LVS到底在做一件什么事LVS解决的是一个很朴素的问题多台服务器组成一个服务集群对外只暴露一个虚拟IPVIP用户请求到达VIP后由调度器决定转发给哪台真实服务器真实服务器把响应返回给用户。这套东西放在今天来看思路不复杂但LVS特殊之处在于它不是常见的用户态进程而是一套内核级的框架配合名为ipvsadm的用户态管理工具使用。用户态工具负责把增删改查的规则通知内核真正干活的是内核里的IPVS模块。1.1 和Nginx、HAProxy比LVS特殊在哪现在做负载均衡大家第一时间想到的往往是Nginx、HAProxy这类七层代理它们工作得更“高级”能根据URL、Cookie、HTTP头部做智能化分发。LVS则是工作在四层传输层甚至更靠下的位置它看到的是IP和端口拿到的是数据包不解析应用层内容。这种位置带来两个直接好处一是转发效率高。Nginx转发请求要经过“网卡→内核→用户态进程→内核→网卡”这条路径上下文切换不可避免LVS则直接在内核的netfilter钩子上做转发决策数据包走完一圈不需要进用户态吞吐量和延迟都有优势。在一个大流量场景里同样一台机器LVS能扛的并发连接数常常是Nginx的数倍。二是转发手段灵活。LVS有三种工作模式NAT模式改写目标IPDR模式改写MAC地址TUN模式走IP隧道。这意味着它不只是“代理”更像一个高速交换机或者路由器可以把流量用一种近乎物理层的方式分发出去。反过来它的劣势也很明显不支持基于内容的路由同端口只能绑定一套算法精细化控制能力弱。所以LVS和Nginx、HAProxy从来不是非此即彼的关系。我在实践中习惯把LVS放在最前面作为流量入口后面挂一组Nginx做七层业务路由再后面才是应用节点。LVS解决“这波连接发给谁”的问题Nginx解决“这个请求该怎么处理”的问题两者配合省心得多。1.2 哪些场景值得选LVS如果你在做小规模业务一台Nginx完全扛得住真的没必要引入LVS增加运维复杂度。但下面几类场景LVS的价值会非常明显高并发入口单机Nginx扛不住的量或者不想让七层代理成为瓶颈需要一台性能更强的四层分发器。TCP/UDP通用接入不只是HTTPMySQL、Redis私有协议、甚至某种自定义TCP服务LVS都可以通过端口做转发不需要关心上层协议。需要会话保持的集群四层调度可直接按源IP散列到固定后端简单粗暴。生产环境对稳定性要求高LVS是内核模块只要规则正确运行态非常稳定不容易被应用层Bug拖垮。我自己见过不少团队用Nginx硬扛总入口流量到了大促就疯狂扩机器其实换成“LVSNginx”的分层结构后瓶颈一下子解开了。所以我的建议是先想清楚流量规模再决定要不要上LVS。2. NAT、DR、TUN三种模式怎么选LVS最容易劝退新手的地方不是命令而是三种模式NAT、DR、TUN。我以前带过不少新人第一次看到三种模式的定义都以为很简单真到配置时发现数据包路径、ARP问题、跨网段能力都不一样才意识到这里面水很深。我把三种模式从头讲一遍。2.1 NAT模式像路由器一样改地址NAT模式的全过程可以概括为“请求进来改目标IP响应回来改源IP”。Director此刻扮演的就是一个透明网关客户端先把请求发到VIPDirector地址Director查IPVS表把数据包里的目标地址改成选中的Real Server地址再把包转发到内网Real Server处理完后把响应包交回给DirectorDirector再把源地址改回VIP原路返回给客户端。NAT模式最大的优势是对后端节点要求低Real Server只需要把网关指到Director、监听自己的真实IP即可不需要额外绑定VIP也不需要修改内核参数。操作系统也不用局限于LinuxWindows、容器里的节点理论上都能接入。代价是代价非常明显进出流量都绕DirectorDirector的网卡带宽、CPU处理能力迟早成为瓶颈。响应数据一般比请求数据大得多这个模型里Director要转发全部响应所以NAT模式更适合请求多、响应小、后端数量不多的场景比如一些API网关入口。我很少在生产核心链路用NAT模式但它在异构环境里真的方便。如果你后端有非Linux机器或者不想在每一台上配置VIP的ARP抑制NAT模式是无脑选择。2.2 DR模式最常用的高性能方案DR模式全称Direct Routing原理是Director收到客户端请求后不修改目标IP只把数据帧的目标MAC地址改写为Real Server的网卡MAC再通过二层网络发出去。Real Server收到这个帧后会发现“IP确实是VIP目标MAC也是我”于是正常处理业务响应时直接以自己的真实IP和网卡把包发回给客户端完全绕开Director。这样设计的关键在于所有Real Server都要在自己的回环接口lo或某个隐藏接口上配置VIP地址但不能对外宣告这个VIP。否则一旦ARP广播询问VIP对应哪个MAC所有Real Server都会抢答流量就乱套了。所以DR模式下每台RS必须配合调整ARP参数告诉内核“VIP这个地址我收但遇到ARP请求别说出去”。DR模式的优点是性能和吞吐量都是三种模式中最高的因为响应流量不过Director解决了NAT模式最头疼的瓶颈。缺点是需要Director和Real Server在同一个二层网络同一VLAN/广播域内因为改写MAC地址依赖以太网广播。如果业务已经跨机房、跨VLAN直接套DR模式就会遇到数据帧到不了RS的问题。实际生产环境里DR模式是最常用、最能体现LVS价值的部署方式后面第4节我会给出完整配置。2.3 TUN模式跨网段的隧道方案TUN模式是在Director把原请求包再用一层IP封装通过IPIP隧道发送给远端Real Server。Real Server解开隧道后拿到原始请求处理后同样直接把响应发回客户端。它解决了DR模式对二层网络的限制问题让LVS可以跨机房、跨网段工作。但TUN模式不是免费的午餐。IPIP封装会增大数据包MTU问题很常见隧道本身也消耗一定的CPU资源。Real Server还要求内核支持IPIP隧道模块并且系统网络配置比DR模式更复杂。我在跨地域容灾场景里使用过平时更倾向把机房内部调度用DR模式跨机房流量交给上层DNS或全局负载均衡处理这样整体复杂度更低。2.4 选型对比与实际判断三种模式的选择不复杂用一张表可以看得很清楚模式请求路径响应路径RS是否绑定VIP网络要求性能特点NAT客户端→Director→RSRS→Director→客户端否Director与RS可跨网段一般Director易成瓶颈DR客户端→Director→RSRS直接回客户端是需隐藏VIP并抑制ARPDirector与RS必须同一二层网络最高吞吐量突出TUN客户端→Director→RSRS直接回客户端是需支持IPIP隧道可跨网段中等封装有额外消耗我的选择逻辑很简单后端都在同一个机房、同一个VLAN直接上DR模式有异构系统、后端数量少或者不想折腾ARP用NAT必须跨网段但又要响应直连考虑TUN如果跨机房我会先把流量按区域切分再在每个区域内都用DR模式而不是跨区域强行封装。3. 调度算法别再只会用rr了规则写好后LVS还要回答一个问题这一批连接到了到底转发给谁。解决方案是调度算法LVS原生支持的算法非常多但很多人从头到尾只用轮询rr这其实浪费了LVS一半的功力。3.1 静态算法不看状态只看配置静态算法是指调度器不关心后端的实时负载和连接数只根据既有策略做决定。最基础的是轮询rr请求按顺序挨个发给后端相当于“轮流吃饭”适合后端能力完全一致的场景。加权轮询wrr在此基础上给每台后端配权重权重高的被分配得更多适合机器规格有差异的集群。再往下是两种哈希算法源地址散列sh和目标地址散列dh。sh会把同一个客户端的请求总是发到同一台后端相当于四层会话保持dh则把同一目标地址的请求发到同一后端。哈希算法的特点是分布结果稳定不随后端状态波动缺点是无法感知后端负载某台机器压力大了也不会自动少接流量。sh在高并发场景下能有效减少后端Session同步的压力我经常在网关层接到需要保持登录态的后端服务时启用它。3.2 动态算法会根据实时状态调整动态算法会读取连接数等实时指标做决策。最少连接lc把新连接发给当前活跃连接数最少的那台后端加权最少连接wlc在lc基础上叠加权重是LVS默认的调度算法复杂度不高但实战效果很好。一个常见场景是有两台后端权重相同但其中一台因为长连接占着大量连接数wlc会主动把新连接优先发给另一台避免冷热不均。还有一些进阶算法sed最短期望延迟在wlc基础上考虑权重与连接数的比例适合处理请求处理时间不稳定的服务nq永不排队会让空闲节点第一时间被使用避免“抢得到连接却一直排队”的尴尬。lblc、lblcr则适用于Cache集群通过局部性原理优先把请求发到最近访问过的缓存节点。3.3 生产环境算法选型建议我的默认选择通常是wlc它的稳定性足以覆盖绝大多数无状态HTTP服务。但有几个反例要说清楚后端有内存级Session而且不共享用sh靠算法保命。后端是缓存集群希望相同内容的请求打在同一节点用dh。请求处理时间差异极大有的1毫秒、有的1秒用sed或nq比wlc更贴合实际情况。多台后端规格差异明显无论什么算法都要配合权重使用别嫌加权重麻烦。选型的关键是你得知道“这台服务真正消耗的资源是什么”。只看CPU、不看连接数wlc也不一定准。我习惯把算法选型和后端监控指标联动起来连接数对算法调整的参考价值远大于“听说xx算法好用”。4. 生产级部署DR模式从零落地现在把DR模式完整跑一遍。我以最简单的架构为例一台Director、两台Real ServerVIP是192.168.1.200Director网卡地址192.168.1.100RS1地址192.168.1.11RS2地址192.168.1.12。后端端口都是80用wlc算法权重分别配1和2。4.1 环境规划与前置准备先把三台机器的系统准备好都装LinuxDirector确认内核加载了IPVS模块。检查方法很简单lsmod | grep ip_vs如果输出为空执行modprobe ip_vs modprobe ip_vs_wlc modprobe ip_vs_sh modprobe ip_vs_sed想开机自动加载就在/etc/modules-load.d/ipvs.conf里写上模块名一行一个。生产环境建议把常用调度模块都加载上后面切换算法不用临时加载模块。接着确认防火墙不影响转发。DR模式下Director要把收到的请求按二层转发给RS不能让本机防火墙把包拦截掉但也不要习惯性关掉firewalld而是为VIP的流入流量放行。最简单的方式是确保firewalld中出现了VIP所在区域的接受规则否则后面排查会非常痛苦。我见过太多人把防火墙一关了之结果LVS规则全对就是流量不通最后发现是firewalld规则的问题。4.2 Real Server的ARP抑制与VIP绑定这一步是DR模式的重中之重。RS上需要把VIP配置到loopback接口上因为VIP不通过物理网卡对外通信不能配到eth0上。传统命令是ifconfig lo:0 192.168.1.200 netmask 255.255.255.255 broadcast 192.168.1.200 up新一点的系统也可以这样ip addr add 192.168.1.200/32 dev lo子网掩码一定要是255.255.255.255目的是让VIP成为仅本机可见的32位主机路由不广播任何网络段信息。配上IP后立即修改ARP参数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_announcearp_ignore设为1表示本机收到ARP请求时只响应该接口自身的IP不跨接口响应。arp_announce设为2表示本机发出ARP请求时优先使用目标网络匹配的接口地址。这两个参数一配合RS上的VIP就成了“能收包但不出声”的隐藏IP。如果只在all上设置个别内核版本对lo接口的行为不完全一致所以我也总在lo上再设置一遍双保险。为了让配置重启后依然生效把这些参数写入/etc/sysctl.confnet.ipv4.conf.all.arp_ignore 1 net.ipv4.conf.all.arp_announce 2 net.ipv4.conf.lo.arp_ignore 1 net.ipv4.conf.lo.arp_announce 2执行sysctl -p让配置立即生效。此时在本机ping VIP会通但从外部ping VIP大概率不通这是正常的因为VIP是隐藏的外部Ping包不会得到RS响应真正流量是通过Director转进来的不影响业务访问。4.3 Director上的VIP与IPVS规则Director这边同样要绑定VIP。与RS不同Director的VIP通常配置在物理网卡上因为Director需要对外响应ARP、接收客户端流量。执行ip addr add 192.168.1.200/32 dev eth0然后手动配置IPVS规则ipvsadm -A -t 192.168.1.200:80 -s wlc 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、IP和端口-s指定调度算法wlc。后两条-a添加Real Server-r指定真实地址-g表示DR模式-w设置权重。查看规则ipvsadm -Ln如果输出正常能看到IP Virtual Server version 1.2.1 Prot LocalAddress:Port Scheduler Flags - RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 192.168.1.200:80 wlc - 192.168.1.11:80 Route 1 0 0 - 192.168.1.12:80 Route 2 0 0Forward列是Route说明两条规则是DR模式。此时用客户端直接访问http://192.168.1.200请求会按wlc算法分发到两台RS。可以多刷新几次页面看两台RS的访问日志确认流量是否均衡。4.4 验证与压测简单验证后最好做一轮压测。我习惯用ab做短时间压测比如ab -n 5000 -c 200 http://192.168.1.200/压测的同时在Director上执行ipvsadm -Ln --stats这个命令会打印累计的连接数和流量统计。关注ActiveConn、InActConn和流量字节数确认两台RS都有连接、权重高的RS分到更多请求。如果压测过程中Director的CPU占用过高注意检查是不是没加载相应调度模块或者防火墙规则太复杂正常DR模式下Director的CPU占用应该极低因为数据包基本是硬转发。4.5 持久化配置与生产高可用手动敲的ipvsadm规则重启后会消失生产环境肯定不能这么干。最稳妥的做法是配合keepalived它既能管理VIP的漂移实现高可用又能通过LVS配置文件自动生成IPVS规则。当然如果不想引入keepalived也可以先用ipvsadm -S /etc/sysconfig/ipvsadm保存规则开机通过ipvsadm服务恢复。但这只解决了规则持久化解决不了Director单点故障。生产环境我强烈建议用DR模式的Director跑一主一备两台借助keepalived的VRRP协议把VIP绑定在MASTER上MASTER挂了VIP漂移到BACKUP。keepalived配置里直接写virtual_server段落它启动时会自动调用ipvsadm创建规则比手动维护脚本靠谱得多virtual_server 192.168.1.200 80 { delay_loop 6 lb_algo wlc lb_kind DR protocol TCP real_server 192.168.1.11 80 { weight 1 TCP_CHECK { connect_timeout 3 } } real_server 192.168.1.12 80 { weight 2 TCP_CHECK { connect_timeout 3 } } }有keepalived的健康检查后后端RS的摘除和恢复都是自动的非常省心。但要注意两台Director都要配置相同的VIP网卡信息BACKUP上的VIP在正常情况下不响应ARPMASTER故障后才由keepalived接管。5. 故障排查与避坑实录LVS出了问题最让人头疼的不是规则错误而是“看似一切都对但流量就是不对”。我经历过不下十次这样的折腾把典型问题和排查思路整理出来。5.1 VIP访问失败现象客户端访问VIP超时或者提示连接拒绝。第一步在Director上确认IPVS规则存在ipvsadm -Ln规则不存在时手动添加。第二步确认VIP确实绑定在网卡上ip addr show eth0第三步在Director本机curl一下VIP看能不能通。如果Director本机通但外部不通多半是防火墙问题查看firewalld或iptables规则确认VIP所在端口没有DROP。第四步如果Director本机也不通排查RS是否都处于不可用状态IPVS中后端全挂时VIP自然访问失败。一个很容易踩的坑是DR模式下Director本机访问VIP流量会直接走loopback转发和外部用户路径不一样。所以Director本机能通不代表外部能通必须以外部客户端的视角去验证。5.2 流量不均现象明明设置了权重某台RS还是承接了大量流量另一台却“空闲”。几个常见原因一是调度算法选了rr没有真正用wlc先查规则的Scheduler列。二是RS的长连接too多wlc统计的是当前连接数当HTTP keepalive或者数据库长连接长时间保活新连接很快会堆到空闲端这是算法机制决定的不是说它错了。三是权重设置成一样但两台后端规格不同明显需要调权重。针对长连接引起的流量不均纯靠算法已经很难解决。我建议如果后端是HTTP服务可以把长连接放在后端的Nginx层由Nginx与上游保持长连接而LVS看到的始终是大量短连接这样wlc算法就能重新发挥作用。这个技巧听起来简单实际能解决很多“看起来不均衡”的问题。5.3 连接超时或新建连接成功率低现象少量用户能访问大量用户超时或者时好时坏。这种情况我首先怀疑的是RS之间的ARP抑制不一致。有些机器是conf/all/arp_ignore生效了但lo接口的值还是0导致VIP在公告阶段泄漏出去。此时在RS上执行arping -I eth0 -c 5 192.168.1.200观察网络里是否出现多个MAC地址响应。如果有非Director的MAC在响应VIP说明RS的ARP抑制没有彻底生效。另一种可能是directed到RS的三层路径不通。DR模式要求Director与RS同一二层网络如果中间隔了VLAN或者路由包虽然能发到RS的MAC但RS回包却走错了网关用户体验就是时断时续。确认的命令是在Director上ping RS的真实IP在网络层面先确认二层三层都通。5.4 排查命令速查表我把平时用得最多的排查命令整理成一个表遇到问题直接按表操作疑似原因排查命令预期结果IPVS规则缺失ipvsadm -Ln能看到VIP和RS列表防火墙拦截firewall-cmd --list-all或iptables -L -nVIP端口被放行RS ARP泄漏arping -I eth0 -c 5 VIP只有Director响应VIP调度算法不对ipvsadm -LnScheduler列显示wlc连接分布跟踪ipvsadm -Ln -c连接表按预期分配到各RS节点健康状态ipvsadm -Ln --statsActiveConn持续增长还有一个常规套路是抓包。在RS的eth0上抓包看有没有来自Director、目标MAC指向本机、目标IP是VIP的帧tcpdump -i eth0 host 192.168.1.200 -nn如果抓不到任何帧多半是Director的网络层发送有问题或者二层链路被隔离如果抓到了但没有正常应答问题就在RS自己的协议栈处理上。5.5 我踩过的一次“诡异”故障印象最深的一次是升级内核后所有RS突然“失联”VIP完全不可用。当时IPVS规则、keepalived配置全部无误后来发现是内核升级后ip_vs相关模块没有自动加载IPVS服务处于“空转”状态。keepalived能够正常浮动VIP但底层没有转发能力流量进来直接被丢弃。这个坑提醒我两件事升级内核或重启系统后第一件事检查lsmod | grep ip_vs第二件事把模块加载固化到initramfs或systemd启动流程里而不是靠keepalived启动时临时加载。生产环境不要小看这种基础细节一次升级就能让你积累的经验全部失灵。6. 一些我长期坚持的LVS运维习惯最后分享几条我个人在项目里长期坚持的做法算不上高深但真的能少踩坑。第一规则变更先备份。任何对IPVS规则的修改先执行ipvsadm -S /tmp/ipvs_backup_$(date %Y%m%d%H%M%S)有备份随时能回滚比凭记忆恢复规则安稳得多。第二把监控和连接表结合起来。LVS本身没有完整状态但ipvsadm -Ln --stats能输出累计连接数和流量。我在监控上会同时看Director的网络吞吐、RS的TCP连接数和RS的响应时间任何一个指标偏离基线都需要排查。真正的瓶颈往往不在LVS而在后端某一台机器上LVS只是把问题放大给你看。第三规划IP地址时给LVS留出独立网段。VIP不要和后端真实IP挤在同一段至少分一个明确的子网段后续DR模式、防火墙规则、监控告警都会好写很多。VIP单独一个网段还能避免有人误把后端服务器IP当作对外发布时间。第四勤做连通性测试但要区分内外。DR模式中VIP的对外可达性与Director所在网段有关不要拿RS上访问VIP的结果评判整个链路。我用脚本定时从外部网络访问VIP检测状态码和延迟这才是用户真正感受到的可用性。第五不要迷信默认参数。LVS默认的wlc算法适合绝大多数情况但一定要根据业务特征微调。最少连接数、目标散列、会话保持这些参数的背后都对应着不同的业务模型选型时结合Session机制、缓存策略和后端连接规格综合判断。LVS本身是一套非常古典的技术内核代码几乎没什么变化但正是这种稳定让它在大流量场景中依然有不可替代的位置。把原理吃透把部署细节处理好它会在架构里安安静静地帮你扛住流量好多年都不用再动它。
返回列表