LVS-DR模式负载均衡实验:原理、配置与keepalived高可用实践
2026/9/16 2:53:57 网站建设 项目流程

每次看到“DR”这个词,不同圈子的人都能引申出完全不同的含义。搞网络的人想到OSPF里的指定路由器,做导航定位的人想到航位推算Dead Reckoning,医院设备科的人第一反应是数字化X射线摄影设备。而在运维圈,尤其在一线处理高并发业务的工程师看来,“DR”十有八九指LVS的直接路由模式(Direct Routing)。这篇我就围绕LVS-DR实验展开,把这个经典四层负载均衡方案从原理、实验环境规划、配置细节,到抓包验证、健康检查和高可用特性,按实际操作过的顺序从头过一遍。适合刚接触LVS的运维工程师,也适合准备搭建高可用负载均衡架构、需要先厘清原理的系统架构师。

1. 先把 LVS-DR 放进整个负载均衡体系里看

1.1 三种工作模式的横向对比

LVS的底层是Linux内核里的IPVS模块,它工作在四层,通过netfilter框架在数据包进入协议栈时拦截并改写关键字段,把请求转发给后端真实服务器。用户态通过ipvsadm命令管理规则,内核替你完成转发。整个体系里最常用的有三种转发模式:NAT、TUN和DR。

模式转发机制响应报文路径后端要求
NAT调度器同时修改目的地址和源地址响应必须再回到调度器后端默认网关必须指向调度器
TUN调度器把请求封装进IP隧道后端解封装后直接回包后端需要支持隧道设备
DR调度器只改写二层MAC帧头后端直接把响应发给客户端后端与调度器同一二层网络,且绑定VIP

DR模式的核心思路就一句话:只动二层,不碰三层。调度器收到客户端的请求后,把数据帧的目标MAC改成某台真实服务器的网卡MAC,再把帧发出去。真实服务器看到目标IP是VIP,而且自己lo接口上确实绑着这个VIP,于是接受处理。处理完之后,响应报文直接以VIP为源地址发给客户端,完全不回调度器。

打个比方:调度器像个前台接待,只负责把访客分配到工位。工位上的同事做完活,直接把结果送到客户手上,前台完全不介入回程。这和NAT模式那种"所有进出都必须经过前台"的模式有本质区别。

1.2 DR 模式的优势、限制和适用场景

DR模式最大的好处就是响应路径短。调度器只处理入站请求,不用承担回程大流量,CPU、带宽和连接跟踪的压力都比NAT小很多。对于"入站小、出站大"的典型读多写少业务,比如图片服务器、视频点播、静态资源网关,DR能把吞吐量拉到非常高的水平,这是生产环境大量选择LVS-DR的首要原因。

代价也相当明确。第一,所有真实服务器必须和调度器处于同一个二层广播域,跨机房、跨VLAN部署会比较麻烦,得靠VLAN或VXLAN把二层拉通。第二,真实服务器必须把VIP绑到lo接口上,并且压制ARP响应,否则整个网段的VIP归属会乱掉。第三,DR模式不能做端口映射,调度器转发时不改端口,所以后端服务必须监听和VIP服务一致的端口。你在ipvsadm里写8080,后端就也得监听8080。

适用场景上,DR模式特别适合支撑公司内部的高并发API网关、文件下载集群和CDN源站。NAT模式虽然配置直观,但回程全走调度器,流量一上来调度器就成了瓶颈;TUN模式能跨网段,但隧道封装有一定CPU开销,而且很多系统默认不开IPIP模块。DR均衡了性能和复杂度,是性价比较高的方案。

1.3 顺手纠正几个“DR”误区

搜索LVS-DR时很容易被联想词带偏,我在这里统一澄清。LVS的DR是Direct Routing,和OSPF里的DR/BDR指定路由器没有关系。有人搜“OSPF协议每个区域都有DR吗”,这个问题得看网络类型,只有广播型多路访问网络里才需要选举DR/BDR,点对点链路不需要,所以答案是"不是每个区域都必然有"。也有人搜“ADC->DR是什么”,这通常出现在自动化采集或医疗影像设备的数据转换流程里,跟在服务器上做负载均衡也是两条路。至于“航位推算”Dead Reckoning,更多是定位导航领域的概念。缩写撞车不是新鲜事,但做实验时认准方向和上下文,能少走很多弯路。

2. 实验环境规划:拓扑、IP 与 ARP 关键点

2.1 最小可验证拓扑与角色分配

我这次用的是VMware Workstation创建的三台CentOS 7虚拟机,系统层面换成Ubuntu 20.04或22.04也完全没问题。实验要保证调度器和后端真实服务器之间只有一台二层交换机,或者干脆就接在同一个虚拟交换机上,所以VMware网络模式建议选择桥接或仅主机模式,不要用NAT模式,因为VMware自带的NAT会多一层地址翻译,干扰对DR转发路径的判断。

角色主机名物理IPVIP说明
Directorlvs-dir192.168.10.10/24192.168.10.100/24(eth0)安装ipvsadm和keepalived
RS1rs-1192.168.10.11/24192.168.10.100/32(lo)运行Nginx,监听80
RS2rs-2192.168.10.12/24192.168.10.100/32(lo)运行Nginx,监听80
Clientclient192.168.10.20/24发请求做验证

注意看表里的VIP掩码,调度器上写/24,真实服务器上写/32。这个差异不是随手写的,是DR模式能不能跑通的关键之一。调度器作为VIP的实际持有者,必须让同网段的客户端和真实服务器能通过ARP找到它,所以掩码要和物理网段一致;真后端服务器把VIP挂在lo上时,如果也写/24,会产生一条指向前端物理网段的路由,容易干扰Linux路由决策,写/32才能把VIP的影响范围限制在环回接口内。

2.2 VIP 到底该挂在哪台设备的哪个接口

初做LVS实验的人最容易犯的错误,是给所有机器都只配物理IP,忘了VIP该往哪儿放。Director一侧必须持有VIP,否则客户端没有目标地址可以发请求;后端真实服务器也必须持有VIP,否则它收到目标IP为VIP的数据包时,会认为这个包“不是发给我的”,然后在路由表里找不到匹配项,直接丢弃。

那为什么后端要把VIP挂到lo而不是eth0呢?因为如果每台RS的eth0都绑定了192.168.10.100,它们会用自己的物理MAC地址响应ARP请求,客户端和交换机都会蒙圈:这个VIP到底属于谁?把VIP放在lo上,再配合ARP抑制参数,后端就能“收包但不应答”。这里用到了Linux弱主机模型:系统判断一个包是不是发给本机的依据,是本地是否存在目标IP,而不管它从哪个接口进来。所以即使VIP配置在lo上,eth0收进来的数据包一样能被正常处理。理解这一点,DR模式“所有机器都有VIP、但只有调度器宣称自己拥有VIP”的机制就通了。

2.3 ARP 抑制参数:理解两个内核参数的工作逻辑

后端RS在lo接口配置VIP之后,必须调整两个ARP相关内核参数:arp_ignore和arp_announce。ARP抑制是整个DR模式里最容易出问题、也最考验基础原理的部分。

  • arp_ignore = 1:只回应“目标IP等于本接口IP”的ARP请求。因为VIP只配置在lo接口,如果有人查询192.168.10.100对应的MAC,eth0收到这个广播请求时会发现目标IP不是eth0的IP,于是选择不响应。
  • arp_announce = 2:发送ARP报文时,使用最适合当前出口接口的地址作为源IP,避免把VIP当作源地址发送ARP通告,防止后端主动宣告自己拥有VIP。

每台RS上执行:

cat >> /etc/sysctl.conf <<'EOF' net.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 EOF sysctl -p

配置完成后用sysctl -a | grep arp_检查实际生效值。不同内核版本对all和lo的继承逻辑略有差别,我建议all和lo两个维度都写,宁可多想一步,也不要为了少几行配置埋坑。这个参数组合的意义不是让VIP“不可达”,而是让VIP“只被调度器宣告,后端只默默接收”。

3. 实操步骤:一个下午搭出一套完整环境

3.1 Director 安装并在内核里添加 IPVS 规则

先装工具,再加载模块:

yum install -y ipvsadm keepalived modprobe ip_vs lsmod | grep ip_vs

ipvsadm是用户态管理工具,真正干活的是内核模块ip_vs。lsmod能看到ip_vs说明模块加载成功。初次实验建议先手动添加规则,不要一上来就上keepalived。手动规则能让你把“转发层”单独跑通,之后再叠加高可用,出问题时定位范围会小很多。

手工规则如下:

ipvsadm -A -t 192.168.10.100:80 -s rr ipvsadm -a -t 192.168.10.100:80 -r 192.168.10.11:80 -g ipvsadm -a -t 192.168.10.100:80 -r 192.168.10.12:80 -g ipvsadm -L -n

-A是添加一个虚拟服务,-a是往虚拟服务里添加真实服务器,-t指定TCP协议和地址端口,-r指定后端RS,-g表示DR模式,-s rr表示轮询调度算法。可见的迹象是ipvsadm -L -n输出里出现了两条RealServer记录,每条后面都有Route标记,代表DR模式。

3.2 RS 的 Nginx 与 lo 接口 VIP 配置

每台RS上先装Nginx,然后写一个独立页面,方便后面确认请求到底落在了哪台机器:

yum install -y nginx echo "RS1" > /usr/share/nginx/html/index.html # RS2上改成RS2 systemctl start nginx

接着配置lo接口VIP。直接执行ip addr add 192.168.10.100/32 dev lo立刻生效,但重启会丢,所以我习惯写成一个systemd unit文件,方便开机自启和统一管理:

# /etc/systemd/system/vip.service [Unit] Description=Setup LVS VIP on loopback After=network.target [Service] Type=oneshot ExecStart=/sbin/ip addr add 192.168.10.100/32 dev lo ExecStop=/sbin/ip addr del 192.168.10.100/32 dev lo RemainAfterExit=yes [Install] WantedBy=multi-user.target

启动并设置开机自启:

systemctl daemon-reload systemctl enable --now vip.service

在没关keepalived之前,手工规则在Director上跑着,RS上的VIP也配好了,ARP抑制参数也已经生效,这时候可以先做一轮最基础的请求验证。

3.3 从 Client 发请求,验证轮询和连接表

在Client机器上连续发起请求:

for i in $(seq 1 6); do curl -s http://192.168.10.100/; sleep 1; done

正常情况下会交替输出RS1和RS2,说明IPVS按轮询算法把请求分发到了两台后端。同一时间在Director上执行:

ipvsadm -Lnc

可以看到当前连接表里的条目,每次curl请求都会产生一条新的TCP连接记录,这条记录会指向其中一台RS。能出现这个现象,说明从调度规则到后端收包再到回包路径,整条链路已经基本打通。

如果某个请求超时,优先检查三件事:后端Nginx是否监听80端口、后端能否直接访问自己的VIP、ARP抑制是否生效。这个顺序是我在多次排障里固定下来的,效率最高。

4. 叠加 keepalived,给实验补上健康检查能力

4.1 为什么生产环境不会让 IPVS 规则裸奔

只靠手工ipvsadm规则,转发本身能跑通,但有个致命问题:IPVS不检查后端是否存活。如果你手动停掉RS2的Nginx,Director上的规则依然存在,它依然会把请求分给RS2,结果就是客户端时不时超时,因为请求被送进了一个没有进程监听的端口。

生产环境解决这个问题的主流方案是使用keepalived,做的事情有两件:一是给调度器集群做VRRP主备保障,也就是Director本身挂了,备用Director能接管VIP;二是对后端真实服务器做健康检查,发现失败就自动从IPVS转发池里摘除,恢复后自动加回。这也是LVS在生产环境真正可用、可运维的关键。

4.2 keepalived 主备配置与 VRRP 行为

在Director上写/etc/keepalived/keepalived.conf:

vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 123456 } virtual_ipaddress { 192.168.10.100/24 dev eth0 } } virtual_server 192.168.10.100 80 { delay_loop 6 lb_algo rr lb_kind DR protocol TCP real_server 192.168.10.11 80 { weight 1 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } real_server 192.168.10.12 80 { weight 1 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 } } }

这段配置里vrrp_instance负责虚拟IP管理和主备切换,virtual_server负责虚拟服务和真实服务器群组。需要注意,DR模式下keepalived把VIP加到eth0时掩码写/24,和手工RS上lo接口的/32不冲突,因为一个物理IP需要响应ARP,一个环回地址只是收包不响应ARP,语义完全不同。如果这里写错掩码,keepalived起来后可能不会正常宣告VIP,客户端会一直找不到网关。

VRRP协议默认基于组播报文通信,优先级高的成为MASTER并持有VIP,BACKUP处于监听状态。实验里只用单台Director,state写MASTER就能顶上;生产环境搭双机时,两台都要跑keepalived,virtual_router_id要一致,priority要不同,还要确保防火墙放行VRRP协议(协议号112)。

4.3 健康检查失败时的摘除与恢复机制

配置里delay_loop 6表示每6秒做一轮健康检查。TCP_CHECK的意思是对真实服务器的80端口发起TCP连接,连接超时3秒,失败重试3次,每次间隔3秒。这套参数很常用,但要注意:如果后端服务本身响应很慢,比如高峰期部分接口要等5秒才返回,那么connect_timeout和nb_get_retry要适当放宽,否则健康检查会误判,把正常节点摘掉,反而破坏可用性。

启动keepalived后,原来的手工ipvsadm规则其实会被keepalived覆盖管理。可以直接用ipvsadm -L -n观察,会看到两条RealServer记录。此时手动停掉RS1的Nginx,等最多十几秒,再执行ipvsadm -L -n,RS1就会被从IPVS转发池里摘除;再启动Nginx,它会自动加回。这个摘除和恢复的循环,就是生产环境后端扩容、缩容、发版时经常依赖的机制。

5. 用抓包和故障注入验证 DR 的完整工作过程

5.1 tcpdump 抓包看“请求进、响应出”的二层细节

实验做完不能只看到“curl能通”就收工,我强烈建议用tcpdump把包抓出来看一遍,你会发现DR模式的真相藏在二层帧头里。在RS1上执行:

tcpdump -i ens33 host 192.168.10.100 and host 192.168.10.20 -nn

然后从Client访问一次VIP。观察抓包结果,入方向可以看到客户端的请求包到达RS1的ens33,目标IP是192.168.10.100(VIP),但目标MAC是RS1网卡的MAC。这个细节说明Director已经完成了MAC地址改写,包不是广播收到的,而是被精确送到了RS1。源IP还是客户端的IP,源MAC是Director的MAC。也就是说,三层地址没变,二层路径变了。

出方向更明显:RS1发出的响应包源IP是192.168.10.100,目标IP是192.168.10.20,但直接发给了下一条网关或客户端侧交换设备,完全不会经过Director。如果你在另一种模式里看到响应包又折返回Director,那就是NAT模式的回程特征。抓一次包,DR与NAT的本质区别就刻在脑子里了。

5.2 停止一台 RS,观察调度与恢复

在keepalived已经接管配置的基础上,做一次故障注入。登录RS2执行:

systemctl stop nginx

在Director上持续观察ipvsadm -L -n,几秒钟后RS2从列表消失。这时候再从Client连续curl,会发现所有请求都由RS1响应,不再出现超时或连接拒绝。然后把RS2的Nginx再启动,等健康检查窗口过去,RS2自动回到转发池,流量重新变为轮询分配。

这个操作模拟的就是生产环境里某台后端服务发版失败、进程挂掉、再重启恢复的完整过程。真正有价值的不是看到它恢复,而是理解掉线窗口期里调度器做了什么、健康检查周期是多少、失败重试参数怎么影响摘除速度。把这些参数记熟,遇到故障时才不会手忙脚乱。

5.3 一套可反复用的验收清单

检查项命令/方法预期结果
客户端访问VIPcurl http://192.168.10.100交替输出RS1/RS2
连接表查看ipvsadm -Lnc能看到发往两台RS的TCP记录
ARP抑制生效arping -I eth0 -c 5 192.168.10.100只有Director的MAC响应
健康检查摘除systemctl stop nginx后观察ipvsadm对应RS从转发池移除
健康检查恢复systemctl start nginx后观察ipvsadm对应RS自动加回
回包路径tcpdump在RS上抓包响应包不经过Director

这套清单几乎可以直接当作给新环境做交付验收时的标准动作,每一条都能帮你快速定位DR模式的哪一环出了问题。

6. 常见问题速查与避坑心得

6.1 高频问题与排查顺序

现象常见原因处理建议
VIP能ping通但curl超时后端Nginx未监听80,或防火墙拦截先在后端curl 127.0.0.1验证服务,再放行80端口
curl返回内容始终来自同一台RS轮询算法被改成持久算法,或健康检查只保留一台检查ipvsadm算法参数和keepalived配置
客户端ARP表中VIP的MAC来回跳ARP抑制没有生效重新检查sysctl.conf,确认lo和all两个维度均已配置
多台Director同时持有VIPVRRP参数不一致或防火墙封了组播确认virtual_router_id和priority,放行协议112
请求被分到RS但RS不处理RS上未配置lo的VIP在RS上ip addr确认,并检查vip.service是否启动
换端口访问失败DR模式不能做端口映射把调度器和后端服务配置在同一端口

前一节提到的故障定位顺序也放在这里:先查服务监听,再查VIP是否存在,最后抓包看ARP和回包路径。照着顺序来,基本不会排查到一半迷路。

6.2 几份实操习惯,能少踩很多次坑

第一,先手工ipvsadm验证,再上keepalived。手工规则让你直接面对内核转发的原始状态,出了问题更容易定位;一上来就叠keepalived,所有故障都会混合在一起。第二,每次调整ARP参数都重新用arping验证一遍,别只信sysctl输出。sysctl显示参数生效只说明内核接收了配置,不能说明网络行为符合预期,抓包和arping才是真相。第三,生产环境选调度算法时,别只看rr和wrr,还要考虑会话保持。比如带有登录态的业务,如果客户端请求在不同RS之间飘,会出现频繁掉登录的问题。LVS可以按源IP做sh(源地址哈希)或持久连接,这点做架构方案时一定要提前想清楚。

最后提醒一句,实验环境里可以随手关闭firewalld和selinux来降低干扰,生产环境则必须用最小放行策略把需要的端口和VRRP协议放行,否则安全基线这关过不去,后面运维会很难受。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询