拓冰建站拓冰建站
首页 / 资讯中心 / 正文

LVS-DR模式负载均衡实验:原理、配置与keepalived高可用实践

每次看到“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帧头后端直接把响应发给客户端后端与调度器同一二层网络且绑定VIPDR模式的核心思路就一句话只动二层不碰三层。调度器收到客户端的请求后把数据帧的目标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和keepalivedRS1rs-1192.168.10.11/24192.168.10.100/32(lo)运行Nginx监听80RS2rs-2192.168.10.12/24192.168.10.100/32(lo)运行Nginx监听80Clientclient192.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对应的MACeth0收到这个广播请求时会发现目标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_vsipvsadm是用户态管理工具真正干活的是内核模块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] DescriptionSetup LVS VIP on loopback Afternetwork.target [Service] Typeoneshot ExecStart/sbin/ip addr add 192.168.10.100/32 dev lo ExecStop/sbin/ip addr del 192.168.10.100/32 dev lo RemainAfterExityes [Install] WantedBymulti-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的NginxDirector上的规则依然存在它依然会把请求分给RS2结果就是客户端时不时超时因为请求被送进了一个没有进程监听的端口。生产环境解决这个问题的主流方案是使用keepalived做的事情有两件一是给调度器集群做VRRP主备保障也就是Director本身挂了备用Director能接管VIP二是对后端真实服务器做健康检查发现失败就自动从IPVS转发池里摘除恢复后自动加回。这也是LVS在生产环境真正可用、可运维的关键。4.2 keepalived 主备配置与 VRRP 行为在Director上写/etc/keepalived/keepalived.confvrrp_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并持有VIPBACKUP处于监听状态。实验里只用单台Directorstate写MASTER就能顶上生产环境搭双机时两台都要跑keepalivedvirtual_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 -nRS1就会被从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.100VIP但目标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协议放行否则安全基线这关过不去后面运维会很难受。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门