恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
LVS TUN隧道模式详解:原理、配置与跨机房负载均衡实战
首页
资讯中心
/
LVS TUN隧道模式详解:原理、配置与跨机房负载均衡实战
LVS TUN隧道模式详解:原理、配置与跨机房负载均衡实战
发布时间:2026/10/13 11:51:28
企业级负载均衡集群LVS—TUN隧道模式做运维这几年我接触过的负载均衡方案不算少从硬件F5到软件Nginx、HAProxy再到LVS的DR模式和NAT模式基本都用过一轮。但说实话真正让我在面试和实际项目中都觉得这玩意儿有点东西的还是LVS的TUN隧道模式。之前帮一个客户搭视频点播集群业务流量大得吓人NAT模式扛不住DR模式又受限于物理网络拓扑最后就是靠TUN隧道模式把跨机房的几十台后端服务器统一调度起来效果立竿见影。先说人话解释一下TUN隧道模式到底干了啥。LVS一共有三种工作模式NAT、DR、TUN。NAT模式像公司前台所有进出都得过它DR模式像直接给员工发快递回程不经过前台了而TUN模式更像是给每个后端服务器发了一个虚拟工作证请求进来时负载均衡器把数据包重新封装一下通过IP隧道直接丢给后端服务器后端处理完直接把响应返回给客户端连负载均衡器都不用绕。这篇文章适合谁看刚接触LVS想搞懂三种模式区别的运维新人被DR模式跨VLAN问题卡住的老手以及正在做大规模视频、下载、流媒体类业务架构选型的技术负责人。我会把TUN隧道模式的原理拆开揉碎配上我实际搭建集群的完整过程、参数解释、踩坑记录以及和DR/NAT模式的对比选型建议争取让你看完就能照着落地。1. 为什么偏偏是TUN模式它解决的核心痛点1.1 NAT和DR模式的先天局限性先说NAT模式。LVS-NAT模式下负载均衡器就是整个集群的流量中枢客户端请求进来要改目的地址响应出去要改源地址。看起来逻辑简单但问题也很明显进出流量都走这一台机器带宽瓶颈迟早会卡死你。我见过一个生产环境后端吞吐明明有4Gbps前端NAT模式的均衡器跑到1.5Gbps就开始丢包加带宽又得花钱升硬件非常被动。DR模式倒是解决了回程流量的问题它通过改写数据帧的目标MAC地址让请求直接送到后端的VIP上后端服务器回包时源IP就是VIP客户端直接收到完全绕开了均衡器。听起来很完美但是DR模式有一个硬性前提负载均衡器和所有后端服务器必须处于同一个二层网络里也就是同一台交换机或者做了二层互通。可现实中很多企业机房不止一个网段或者后端服务器分布在两个数据中心DR模式就彻底没戏了。TUN模式的价值就在这里。它不依赖二层网络核心思想是把客户端的请求包通过IP隧道重新封装内层是原始数据包外层新加了一个IP头目的IP是后端服务器的真实IP。这样后端服务器不管在哪个网段、哪个机房只要IP能通就能接收隧道包并处理处理完直接把响应返回给客户端。四两拨千斤把跨网段、跨机房的大规模调度问题直接解决。1.2 什么样的业务场景最需要TUN模式从我的经验看以下三类场景非常适合TUN模式大流量下载和视频点播类业务响应数据量远大于请求数据量回程流量绕过负载均衡器是刚需TUN模式天然满足。后端服务器跨网段、跨机房部署公司有多个可用区或者业务容灾需要把集群分散在不同物理位置TUN是比DR更现实的选择。后端服务器数量大、需要横向扩展理论上只要网络可达加机器就是改一下配置文件的事不会受二层设备端口和MAC表容量限制。当然TUN模式也不是没有成本它要求后端服务器支持IP隧道协议Linux内核里对应模块就是ipip还需要额外配置tunl0隧道网卡。这些后面实操部分我会一步步拆。1.3 一句话总结TUN模式和DR、NAT的本质区别用一张表格做对比方便你选型时快速定位对比项NAT模式DR模式TUN模式后端要求任意操作系统需要VIP绑定在回环接口通常Linux需要支持IPIP隧道通常Linux需配置tunl0网络要求后端和均衡器二层或路由可达必须是同一二层网络仅要求IP路由可达可跨网段回程流量必经均衡器后端直接返回客户端后端直接返回客户端扩展性受均衡器带宽瓶颈限制受二层网络规模限制理论可跨机房无限扩展性能短板进出都过单点需要处理ARP问题隧道封装有额外CPU开销2. 隧道模式的前置知识图解IPIP封包与VIP的必要性2.1 IPIP隧道的封包与解包过程TUN模式最核心的机制是IPIP隧道。所谓隧道说白了就是在原本的IP数据包外面再套一层IP头。你想象一下寄快递内层是你原本的信件客户端发往VIP的请求包外层是快递包装袋从均衡器发往后端真实IP的隧道包头后端收到后拆开外层包装取出里面的信件一看目的地址是VIP就知道这请求是发给自己的。具体封包结构是这样变化的原始客户端请求包源IP客户端IP目的IPVIP比如192.168.10.100。均衡器收到后不修改这个包的任何内容而是直接在外面封装一个新的IP头源IP均衡器IP目的IP后端服务器的真实IP协议号设置为4IPIP封装。后端服务器的tunl0隧道接口收到这个外层包发现协议号是4且自己是目的地址就自动解封装把内层包交到协议栈继续处理。这里有个关键认知误区很多人以为TUN模式需要修改内层包的目的IP其实完全不用正是因为没有改动内层包后端才必须把VIP配置到自己身上否则内层包到了协议栈发现目标不是本机IP直接就给丢了。2.2 为什么后端必须绑定VIP以及为什么不会冲突TUN模式下每台后端服务器都要在自己的回环接口通常叫lo:0上绑定VIP。这是很多新手最不理解的地方多台机器配置同一个IP不会IP冲突吗答案是不会因为VIP的地址只在本地协议栈内部使用而且必须配合内核参数rp_filter反向路径过滤和arp_ignore/arp_announce调整。TUN模式之所以对ARP要求没那么苛刻是因为隧道包的外层目的IP是后端真实IPARP解析只发生在这个真实IP上VIP不会被广播到网络里。你可以把VIP理解为本地斗篷只有隧道解封装后才会看到它。但为了稳妥我依然会在每台后端机器上做两个事情在lo:0配置VIP并设置net.ipv4.conf.all.arp_ignore1和net.ipv4.conf.all.arp_announce2防止后端机器对VIP的ARP请求做出响应。设置net.ipv4.conf.all.rp_filter0避免反向路径过滤把隧道包判定为非法路由而丢弃。这两步我后面会给出完整的sysctl.conf写法直接抄作业就行。2.3 隧道模式下数据包进出完整路径为了让你脑子里有一个清晰的链路图我按时间线把整个流程走一遍客户端发起请求目标地址是VIP例如10.0.0.100。路由器把请求送到负载均衡器Director的VIP网卡上。Director查看自己的IPVS调度表根据调度算法rr、wrr等选中一台后端服务器真实IP假设是172.16.1.20。Director在原包外层封装IPIP隧道头新包的源IP是Director的IP比如172.16.0.10目的IP是172.16.1.20协议号4。隧道包经过路由和交换机到达后端服务器172.16.1.20。后端服务器的tunl0接口收到外层包解封装露出内层请求包目的IP仍是10.0.0.100。因为后端已经在lo:0上绑定了VIP 10.0.0.100协议栈接受这个包交给Web服务进程处理。后端处理完响应包直接以VIP作为源IP发送给客户端完全不经Director。整个链路中Director只在请求阶段出现一次响应阶段完全隐身。这对大流量场景的意义怎么强调都不过分。3. 手把手搭建LVS-TUN集群环境规划到完整配置3.1 环境规划与网络拓扑我在实际项目中用三台服务器搭建过最小可用的TUN集群这里我用一套模拟环境来演示。所有IP都是规划出来的测试地址你替换成自己的生产IP即可。角色主机名IP地址说明负载均衡器lb01192.168.1.10安装ipvsadm配置VIP和IPVS规则后端服务器1rs01172.16.1.101部署Nginx绑定VIP到lo:0后端服务器2rs02172.16.1.102部署Nginx绑定VIP到lo:0VIP-192.168.1.100客户端访问的虚拟IP注意一个关键点TUN模式下均衡器和后端服务器不需要在同一网段甚至可以跨互联网部署。我这里故意把后端放在172.16网段就是为了演示路由可达即可的效果。3.2 负载均衡器端配置第一步安装IPVS管理工具。CentOS/RHEL系的命令是yum install -y ipvsadmDebian/Ubuntu系则是apt install -y ipvsadm接下来创建VIP。我的习惯是先用命令验证效果确认没问题再写成开机自启脚本ip addr add 192.168.1.100/32 dev eth0这里必须强调VIP一定要配成32位掩码也就是只匹配单个IP不要让它参与路由广播。否则会出现一些奇怪的ARP问题。然后打开IP转发功能echo net.ipv4.ip_forward1 /etc/sysctl.conf sysctl -pTUN模式虽然不像NAT模式那样强依赖iptables转发但打开转发仍然是一个保险动作。接下来配置IPVS规则ipvsadm -A -t 192.168.1.100:80 -s rr ipvsadm -a -t 192.168.1.100:80 -r 172.16.1.101 -i ipvsadm -a -t 192.168.1.100:80 -r 172.16.1.102 -i这里关键参数是最后那个-i它代表隧道模式IPIP encapsulation。如果没有这个参数默认会是NAT模式后端服务器就会因为找不到VIP而抓狂。-s rr代表轮询调度算法生产环境一般用wrr加权轮询或者lc最少连接看业务来。验证规则是否生效ipvsadm -L -n输出里你会看到两行后端服务器的记录转发策略显示TUN就算配置成功了一半。3.3 后端服务器的隧道网卡配置这是TUN模式最容易出错的地方。后端服务器需要加载IPIP内核模块并创建tunl0隧道接口。第一步加载模块并确认modprobe ipip lsmod | grep ipip如果你用的是较新的内核可能会发现模块名变成了tunnel4或者被编译进内核不用太纠结只要能创建tunl0接口就行。第二步启动tunl0接口并添加VIPip link set tunl0 up ip addr add 192.168.1.100/32 dev tunl0这里我要多说一句很多教程会让你把VIP加在lo:0上这其实也没有大问题因为协议栈只看目的IP是否属于本机。但我实测下来加在tunl0上更直观因为tunl0是隧道包的接收口VIP配置在这里逻辑上更顺。两种做法都可行你选一种保持一致就好。如果想开机自动生效写入配置文件cat /etc/sysconfig/network-scripts/ifcfg-tunl0 EOF DEVICEtunl0 BOOTPROTOnone ONBOOTyes IPADDR192.168.1.100 PREFIX32 EOF第三步调整内核参数。这是后端正确接收隧道包的关键我直接用完整配置cat /etc/sysctl.d/99-lvs-tun.conf EOF net.ipv4.conf.all.rp_filter 0 net.ipv4.conf.tunl0.rp_filter 0 net.ipv4.conf.all.arp_ignore 1 net.ipv4.conf.all.arp_announce 2 net.ipv4.ip_forward 1 EOF sysctl --system逐一解释一下rp_filter反向路径过滤它默认会检查收到的数据包源IP是否能在路由表里找到对应路径隧道包解封装后内层包的源IP是客户端IP后端可能没有到客户端IP的路由所以必须关掉过滤否则直接丢包。arp_ignore和arp_announce防止后端向网络宣告自己的VIP避免和均衡器VIP冲突。3.4 验证整条链路是否跑通后端两台服务器都部署好Nginx并启动后先在均衡器上做连通性测试ping -c 3 172.16.1.101 ping -c 3 172.16.1.102接着在客户端另一台机器上连续访问VIP多次观察是否轮询到不同后端curl http://192.168.1.100/如果后端返回的内容不同说明调度正常。我习惯在每台后端的Nginx首页写上机器名便于确认echo This is rs01 /usr/share/nginx/html/index.html echo This is rs02 /usr/share/nginx/html/index.html最后在均衡器上看连接统计ipvsadm -L -n --stats如果ActiveConn在增长且两个后端都有流量恭喜你TUN隧道集群已经跑通了。4. 实测中的坑隧道通了但响应丢包问题竟在内核参数4.1 第一次搭建时的完整排查过程第一次搞TUN模式时我按照教程一步步配完结果客户端能ping通VIPcurl却总是超时或者偶尔成功一次。当时真是被折磨得不轻这里把排查过程完整写出来价值比配置本身大得多。我当时的处理顺序是这样的先看均衡器上IPVS统计发现转发计数一直在涨说明调度器确实把包发出去了。接着看后端Nginx访问日志结果日志里一条记录都没有这说明请求根本没到Nginx问题出在内核协议栈。然后我在后端服务器上用tcpdump抓包tcpdump -i tunl0 -n结果发现tunl0接口上完全没有流量。这就奇怪了隧道包到底去哪了我立刻换成抓物理网卡tcpdump -i eth0 -n ip proto 4这次有发现eth0上确实收到了协议号4的包。说明隧道包到达了服务器但没被转交给tunl0接口。问题就出在rp_filter上。系统默认的rp_filter是宽松模式值为1它会校验反路由而我的后端路由表里并没有到客户端IP的明细路由于是内核直接判定为非法包悄悄丢弃。找到原因后我立刻应用了前面那份sysctl配置把rp_filter置0再试curl秒开。这个坑我后来在其他项目里又见到有人踩过大家平时用DR模式习惯了完全想不到TUN模式会栽在反向路径过滤上所以建议你在配置后端时第一时间就把rp_filter关掉不要等出了问题再去抓包。4.2 隧道MTU引发的分片问题第二个坑跟MTU有关出现频率也很高。IPIP隧道会在原包外面增加20字节的新IP头这样一来如果客户端发出的包本身已经是1500字节以太网最大传输单元封装后就变成1520字节超出物理链路MTU就会触发分片。分片带来的恶果是部分防火墙和中间设备会直接丢弃带分片标志的包导致大型请求或下载业务正常但一些交互请求时好时坏非常诡异。我的解决方案是在均衡器上适当调低对外通告的MSS值让TCP握手时协商一个更小的段大小iptables -A POSTROUTING -t mangle -p tcp --dport 80 -j TCPMSS --set-mss 1400也可以在后端服务器上直接降低隧道接口MTUip link set tunl0 mtu 1400两种方式结合使用效果最好。我建议你把tunl0的MTU稳定设置在1400能有效避开发和分片相关的大部分问题代价是每个包多一点点头部开销但换取稳定性完全值得。4.3 keepalived对TUN模式支持的一些细节生产环境肯定不能让均衡器单点所以要配合keepalived做VIP的HA。keepalived对LVS-NAT和DR模式支持得很好TUN模式也一样支持但有一个细节要留意。keepalived的配置文件中real_server那一行需要加上tun关键字否则keepalived会用NAT模式去健康检查后端健康检查就会失败。正确写法是virtual_server 192.168.1.100 80 { delay_loop 6 lb_algo rr lb_kind TUN persistence_timeout 20 protocol TCP real_server 172.16.1.101 80 { weight 1 TCP_CHECK { connect_port 80 connect_timeout 3 } } real_server 172.16.1.102 80 { weight 1 TCP_CHECK { connect_port 80 connect_timeout 3 } } }注意lb_kind TUN这个对应ipvsadm里的-i参数。keepalived把转发模式声明为TUN后健康检查请求会走隧道机制后端回包直接返回客户端整个链路才是完整的。我遇到过一个问题配置好keepalived后主备切换一切正常但后端的健康检查总是超时。后来排查发现是keepalived所在主机的防火墙拦了出方向的TCP_CHECK包。解决方法是放行健康检查源IP或者改用HTTP_GET方式并指定健康检查的URL。调整后一切正常。如果你后面也遇到健康检查不通过的诡异问题可以先看看是不是防火墙的问题而不是急着怀疑tunnel配置。5. 调度算法选型与性能调优经验5.1 常见调度算法适用场景分析IPVS自带的调度算法有十几种生产环境我常用的就三个rr、wrr、lc。简单对比一下rr轮询请求均匀分配给所有后端适合后端性能基本一致的场景配置最简单。wrr加权轮询给性能强的机器分配更大的权重适合后端配置参差不齐的集群。lc最少连接记录当前活跃连接数把请求分给当前负载最小的后端适合长连接业务比如WebSocket、数据库中间层。我自己的视频点播项目用的是wrr因为后端机器新旧不一新机器的CPU和网卡性能明显强很多统一轮询反而让老机器成为瓶颈。wrr配合权重调整新老机器都能发挥各自能力。如果你在后端同时提供HTTP和HTTPS服务记得把443端口的VIP规则也加上ipvsadm -A -t 192.168.1.100:443 -s wrr ipvsadm -a -t 192.168.1.100:443 -r 172.16.1.101 -i -w 3 ipvsadm -a -t 192.168.1.100:443 -r 172.16.1.102 -i -w 15.2 连接超时参数调整IPVS默认有一些连接超时时间比如TCP空闲超时默认900秒。对于长连接业务这个值往往不够客户端连接被服务端默默断开业务数据丢失表现就是一会好一会坏。调整方法ipvsadm --set 120 60 600参数含义分别是TCP空闲超时120秒、TCP FIN等待60秒、UDP空闲超时600秒。具体数值根据业务来调不是固定死的。我的经验是如果HTTP请求之间间隔不会太长120秒空闲超时足够如果是长轮询或流媒体播放建议把这个值调大到600秒以上避免播放中断。如果你用keepalived管理IPVS规则那超时参数需要在配置文件里通过ipvsadm-extra传递否则重启keepalived后会恢复默认值。这个坑我也踩过特别提醒一句。5.3 后端真实服务器数量与收敛性TUN模式理论上可以挂几十台甚至上百台后端但实际项目里我建议你控制在一个合理范围比如20到30台以内。原因不是性能不够而是运维复杂度指数级上升。每台后端都要配置VIP、调整内核参数、维护健康检查规模越大越容易在某台机器上遗漏配置。有一个比较实用的做法是把后端的tunl0配置和内核参数做成一个统一的初始化脚本新机器上线时自动执行从根源上避免人为遗漏。我用的脚本简化版大概是这样的#!/bin/bash VIP192.168.1.100 MTU1400 modprobe ipip ip link set tunl0 up ip addr add ${VIP}/32 dev tunl0 2/dev/null || true ip link set tunl0 mtu ${MTU} || true cat /etc/sysctl.d/99-lvs-tun.conf EOF net.ipv4.conf.all.rp_filter 0 net.ipv4.conf.all.arp_ignore 1 net.ipv4.conf.all.arp_announce 2 EOF sysctl --system配合自动化工具分发执行后端扩容从半小时缩减到一分钟以内。6. 安全与高可用生产架构需要额外考虑的事6.1 rsync和防火墙配合确保后端配置一致后端服务器多了以后配置文件漂移是个非常常见的问题。我们用配置管理工具或脚本把初始化内容统一推送到所有后端再配合定时校验确保每台机器的VIP、MTU、内核参数完全一致。我的校验思路是把VIP和tunl0状态写入一个文本文件通过定时任务对比各机器的输出差异。不用写太复杂的逻辑一个diff脚本就够了。出现差异时告警人工介入处理而不是放任它看起来能用就行。6.2 后端服务器异常时IPVS的自动摘除生产环境一定要配置健康检查。keepalived的TCP_CHECK可以检测端口是否存活但有些场景下端口活着不代表服务正常比如处理线程全部阻塞、数据库连接池连不上等。这种情况下TCP_CHECK照样通过但流量打过来就会502。我的建议是配合HTTP_GET或外部监控来自定义更精细的健康检查。比如在后端放一个简单的健康检查URL返回状态码200才算通过如果接口响应超过3秒keepalived会把它摘除恢复后自动加回。这种机制在运维大流量集群时非常有用能避免很多后端半死导致的上层故障。6.3 VIP的HA与整体架构拓扑生产环境中均衡器建议至少两台一主一备。VIP通过keepalived的VRRP协议在主机和备机之间漂移。注意VIP的漂移本身不依赖TUN模式它只是IP层面的高可用。切换后新的主均衡器会接管IPVS规则后端完全无感知。TUN模式的高可用还有一个比DR模式舒服的地方由于后端不需要和均衡器在同一二层网络主备均衡器完全可以在不同的机房或网段VIP通过VRRP跨三层宣告配合单播VRRP物理故障隔离能力更强。当然跨机房的主备切换延迟会略高但对中小规模的容灾场景已经很实用。7. 三种模式混用与最终选型建议7.1 能否三种模式混用很多人问过一个问题TUN模式和DR模式能不能在一个集群里混用答案是能但不建议新手一开始就这么干。IPVS本身支持每个后端real server单独指定转发模式所以可以在同一个VIP下把一部分后端配成DR、一部分配成TUN。这种混用场景通常出现在业务迁移期部分机器在同一交换机下用DR效率高另一部分机器在远端机房只能用TUN。实际操作时你只需要在ipvsadm命令中对不同后端分别使用-gDR模式和-iTUN模式即可。但请务必记得混用不同模式的机器不能有相同的VIP广播行为。DR模式后端和TUN模式后端对ARP的处理方式不一样配置错了会互相干扰。我一般只在迁移窗口期临时混用稳定后尽量统一到一种模式降低运维脑负担。7.2 按业务规模推荐选型路径如果你是一个刚开始做负载均衡的团队我建议按下面的路径思考后端机器在同一个交换机下流量百万级QPS以内优先考虑DR模式因为它性能最好配置相对简单。后端跨网段、跨机房或者需要快速横向扩展直接上TUN模式。不要犹豫这就是它的主场。后端机器数量少且没有性能要求可以考虑NAT模式比如企业内部管理系统几十个用户那种。关于LVS和Nginx/HAProxy的对比我多说一句LVS工作在四层性能极高但不识别应用层内容Nginx/HAProxy可以做到七层路由、灰度发布、路径转发。实际架构中最合理的组合往往是LVS做入口流量调度后端的Nginx集群做七层处理各干各的。TUN模式作为LVS大流量入口的承载价值就在这。7.3 我自己的最终选择建议就我目前遇到的多数场景而言TUN模式确实不是最常用的DR模式在日常运维中出场率更高。但如果你做的业务带有流媒体、大文件下载、跨地域容灾等特点TUN模式几乎就是唯一选项。有一点我想劝大家不要因为TUN配置比DR多几个步骤就绕开它多花半小时把IPIP隧道原理搞清楚后面排查问题能省下好几个小时。我见过太多人等到线上流量打过来才临时抱佛脚那时候踩坑的成本可就大了。8. 写在最后一点实操心得与扩展方向从第一次配置TUN模式时被rp_filter狠狠教育到后来能熟练规划跨机房的视频集群我对这个模式最大的体会就是LVS的三种模式没有绝对的优劣只有适不适合当前网络拓扑。TUN模式牺牲了一定的封装CPU开销换来了跨越二层的自由这笔账在大规模分布式场景下非常划算。最后分享一个小技巧在排查TUN模式故障时我习惯在均衡器上用ipvsadm -L -n --rate看每秒转发速率在后端上用tcpdump -i tunl0 -n看隧道解包后的流量两边一对比问题出在发送端、网络中间还是后端接收基本一目了然。这套组合拳帮我定位过好几次线上疑难杂症。如果你正准备搭建LVS-TUN集群建议先从最小三节点开始跑通后再加节点、加调度算法、加高可用一步一步来千万别一上来就追求大规模。把隧道封包流程在脑子里跑通一遍再动手配你会发现整个集群就像一台精密的调度机器每个包都按你设计好的路径走。