LVS(Linux Virtual Server)是国内使用非常广泛的开源负载均衡方案,它工作在传输层,性能极高。LVS提供三种工作模式:NAT、TUN和DR,其中DR(Direct Routing)模式因为响应流量不经过调度器直接返回客户端,吞吐量最大,也是生产环境里最常见的选择。本文围绕DR模式的核心原理和完整搭建过程展开,重点讲清楚VIP配置、ARP抑制这些容易踩坑的地方。

一、DR模式的工作原理
DR模式的全称是Direct Routing,也叫直接路由模式。它的核心思路是:客户端发来的请求包到达Director(调度器)后,Director不修改IP头部,只把数据帧的目标MAC地址改成某一台RealServer的MAC地址,然后把包丢进局域网。对应的RealServer收到包后,发现目标IP是自己网卡上绑定的VIP,就正常接收处理,处理完成后直接把响应发给客户端的网关,整个过程不再经过Director。
这个设计带来一个关键特性:请求流量走Director,响应流量走RealServer自己的出口。由于Web服务中响应数据量通常远大于请求数据量,这种模式能把调度器的压力降到最低,一台普通的Director就能支撑很大的并发。但DR模式也有前提条件:所有节点必须在同一个物理网段,因为Director的转发依赖二层MAC寻址,跨网段就无法工作了。
还有一点需要理解,为什么RealServer上要绑定VIP但又不能让外界通过ARP发现它。因为局域网内多个机器都有同一个VIP时,交换机收到ARP请求会随机把VIP映射到其中一台机器,Director的转发就乱了。所以RealServer上的VIP要配置ARP抑制,这是DR模式配置中最核心也最容易出错的部分。
二、环境准备与Director配置
先准备环境。假设内网网段是192.168.10.0/24,网关192.168.10.2,Director内网IP为192.168.10.11,两台RealServer分别是192.168.10.21和192.168.10.22,VIP统一使用192.168.10.100。三台机器都要能互相通信,操作系统以CentOS 7为例。
在Director上安装管理工具ipvsadm,并开启内核转发(DR模式下Director只做二层转发,其实不需要ip_forward,但开启不影响):
# 安装ipvsadm yum install -y ipvsadm # Director上绑定VIP到网卡(eth0按实际情况替换) ifconfig eth0:0 192.168.10.100 netmask 255.255.255.255 broadcast 192.168.10.100 up # 添加集群服务,-t表示TCP,-s rr为轮询算法 ipvsadm -A -t 192.168.10.100:80 -s rr # 添加两台RealServer,-g表示DR模式(gatewaying) ipvsadm -a -t 192.168.10.100:80 -r 192.168.10.21:80 -g -w 1 ipvsadm -a -t 192.168.10.100:80 -r 192.168.10.22:80 -g -w 1 # 查看规则 ipvsadm -Ln
注意子网掩码那一行写的是255.255.255.255,也就是/32。这是有讲究的:如果写成255.255.255.0,Director会认为整个网段都在本机直连路上,跟网关通信时ARP可能出问题。VIP单IP绑定/32掩码是规范做法。调度算法除了rr轮询,还可以用wlc(加权最小连接)、sh(源地址哈希,可用来做会话保持),按业务需要选择。
三、RealServer配置与ARP抑制
每台RealServer同样要绑定VIP,但方式不同,要绑定在lo回环接口的别名上,同时调整几个ARP相关的内核参数:
# 绑定VIP到lo:0,掩码必须是255.255.255.255 ifconfig lo:0 192.168.10.100 netmask 255.255.255.255 broadcast 192.168.10.100 up # 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_announce # 让RealServer访问本网段时使用自身物理IP,路由指定 route add -host 192.168.10.100 dev lo:0
arp_ignore设为1表示:系统只响应目标IP是流入接口上配置的地址的ARP请求。也就是说,当ARP请求从eth0进来问谁是VIP时,由于VIP配置在lo上,eth0不予回应,外界就发现不了RealServer的VIP。arp_announce设为2表示:发送ARP请求时,只使用对应接口自身的地址作为源,避免在eth0的ARP通告中泄露lo上的VIP。这两个参数一个管收、一个管发,缺一不可,只配一个ARP抑制就是无效的。
最后那条route命令也常被忽略。它告诉内核:访问VIP走lo:0这个接口。这样RealServer自己访问VIP时,请求包从lo发出再回到lo,内核才能正确处理目标地址为VIP的包。如果不加,有些场景下RealServer本地访问VIP会直接走路由表找网关,导致失败。建议把以上命令写进启动脚本,或者用systemd unit和rc.local保证重启后配置仍在。
四、验证与常见问题排查
配置完成后先做三步验证:第一步在Director上执行ipvsadm -Ln确认规则存在;第二步从客户端反复curl 192.168.10.100,观察两台RealServer的访问日志是否轮换出现;第三步在Director上执行ipvsadm -Lnc查看连接表,确认连接被分发到了不同的RealServer。
常见问题有几个典型情况。如果客户端完全连不上VIP,先在Director上ping 192.168.10.100确认VIP已绑定,再检查ipvsadm规则和80端口后端服务是否正常。如果连接时通时断,大概率是ARP抑制没配对,可以在RealServer上用arping -I eth0 192.168.10.100从别的机器探测,正常情况下只有Director应答;若RealServer也应答,说明arp_ignore没生效。如果所有请求都落到同一台机器,检查是不是某台RealServer的ARP抑制没配,导致它抢答了VIP的ARP请求,流量根本没经过Director。另外别忘了持久化:ifconfig和ipvsadm的配置重启都会丢失,需要写脚本开机执行,ipvsadm可以用ipvsadm --save > /etc/sysconfig/ipvsadm保存。
如果后续要做高可用,可以在Director这一层引入Keepalived,它会自动管理VIP的漂移和ipvsadm规则,还能对RealServer做健康检查,后端挂掉时自动摘除,这是生产环境最常见的组合方案,有兴趣可以在跑通手工配置之后继续深入研究。