1. 从一次架构选型说起为什么最终选了LVS隧道模式几年前我做过一个跨地域的读多写少类业务后端节点分布在三个机房每个机房的机器性能参差不齐流量高峰时经常出现某一组节点被打满、另一组闲着的情况。当时手头可选的负载均衡方案不少从最基础的Nginx四层转发到各类云厂商的LB产品再到LVS的NAT、DR模式都有人用。但最终实际落地跑稳的是LVS的TUN隧道模式。先说结论如果你的业务节点分散在不同网段、不同机房机器数量多且对响应数据返回链路的效率有要求TUN模式可能是最合适的选择之一。它的核心价值在于把“转发压力”和“流量压力”分离——均衡器不用管响应包怎么回后端服务器把数据直接丢给客户端整个集群的吞吐能力因此能撑得非常大。这篇文章不打算讲那种教科书式的原理复述而是从实际搭建和排障的角度把LVS-TUN模式的关键点拆开揉碎。内容包括它和NAT/DR模式的本质区别、隧道封装到底怎么工作、一组可以照着抄的配置示例以及我在真实环境里踩过的那些坑。适合谁看如果你是运维工程师、系统工程师或者正在做架构选型的技术负责人这篇文章能帮你判断TUN模式适不适合你的场景以及真到配置时需要注意哪些细节。就算你是刚接触LVS没多久的初学者只要照着下面的步骤走也能把TUN模式集群搭起来。2. 三种模式的对比TUN模式到底强在哪2.1 NAT、DR、TUN的核心区别LVS有三种工作模式很多文章都会讲但大多数只停留在“数据包怎么走”的层面。我从实际使用的角度给你做个梳理。NAT模式请求进来均衡器改写目标IP和端口转发给后端后端处理完把响应再交回给均衡器由均衡器改写源IP后发给客户端。这个模式最大的问题在于进出流量都要过均衡器均衡器很容易成为瓶颈。我在小规模场景下用过几十台机器以内问题不大规模再大就吃力了。DR模式均衡器只改写数据链路层的目标MAC地址不修改IP包请求到达后端后后端直接以VIP为源地址回包给客户端。这个模式性能很好也是目前生产环境用得最多的。但DR模式有个硬性前提——均衡器和后端必须处于同一个二层网络也就是同一个物理局域网内。不然ARP广播过不去整个方案直接玩不转。TUN模式均衡器把原始的IP包整个封装进一个新的IP包里通过IP隧道通常是IPIP协议转发给后端。后端解封装看到原本的目标地址是VIP因为本地配置了VIP所以数据能被正确处理处理完照样直接把响应返回给客户端不再经过均衡器。三者的对比我整理成了表格特性NAT模式DR模式TUN模式后端与均衡器网络要求可跨网段必须同一二层网络可跨网段、跨机房均衡器是否处理回包是进出都过否后端直接回否后端直接回后端服务器要求无特殊要求需禁ARP响应VIP需支持隧道并配置VIP均衡器性能压力高低低部署复杂度低中中高2.2 TUN模式适用的典型场景结合我自己的经历TUN模式最适合这几类场景后端服务器跨机房部署。比如某公司在华北和华南各有一个机房希望同一个VIP能负载到两边的机器上。NAT模式跨机房也能做但均衡器会变成众矢之的DR模式直接没戏因为二层不通TUN模式天生就是为这种场景设计的。后端机器数量非常多每秒新建请求量很大。因为响应包不走均衡器均衡器只需要处理进来的请求封装或者某种程度上的转发整体CPU占用会低很多。后端机器本身有一定网络配置能力。隧道模式要求后端能创建tunl设备、配置VIP、修改路由策略这比DR模式的配置要求略高一点。我不建议在纯内网、所有机器都在同一机柜的场景强行用TUN模式。那种环境DR模式性能更好、配置更简单、排障更省事。技术选型不是越复杂越好而是越合适越好。3. TUN模式的隧道封装数据包到底是怎么走的3.1 IPIP隧道的工作原理TUN模式默认使用IPIP隧道协议可以理解为“在IP包外面再套一个IP头”。原始的数据包比如客户端发来的TCP握手包目标地址是VIP比如101.10.10.10均衡器收到之后不修改这个包的内容而是把它原封不动地装进一个新IP包里这个新IP包的目标地址是后端机器的真实内网IP比如192.168.1.5。后端机器收到这个外层包先把外层头剥掉看到里面的目标地址是101.10.10.10然后查本机路由和本地地址表——如果本机配置了101.10.10.10这个VIP地址那这个包就交给本地协议栈处理经过程序处理后生成响应包源地址是VIP目标地址是客户端的IP直接从后端的物理网卡发出去。这个过程里均衡器像一个“改地址的快递中转站”——它不负责把包裹送到收件人手里只是把包裹塞进一个大信封写上分拣中心的地址然后丢给下一站。至于分拣中心怎么把包裹交给收件人那是后面的事情中转站完全不操心。3.2 为什么响应不需要回均衡器这个问题我当初也琢磨了很久客户端明明请求的是VIP响应包的源地址写VIP没问题但是IP包是从后端某个物理网卡直接发出去的客户端收到后能正常识别吗答案是能。因为TCP/IP协议栈处理连接时关心的是四元组源IP、源端口、目标IP、目标端口而不是“这个包从哪台物理机器发出来的”。只要响应包的源IP是客户端请求的那个VIP客户端就会认为这属于同一个连接数据能正常被上层应用接收。这就有个非常实际的好处对于流量“出多进少”的应用比如视频点播、大文件下载、API响应数据量大的场景后端直接把大流量回包发出去不需要均衡器转发第二次集群的整体输出能力不会被均衡器卡住。3.3 理解“进和出分离”才能做好排障很多人配置TUN模式遇到问题就是因为没理解“进和出是两条路”。请求进来走隧道进来之后后端处理响应出去走物理网络直接回客户端。这意味着均衡器上的防火墙规则、路由策略影响的是“进”的方向而后端机器上的防火墙、路由策略影响的是“出”的方向。我曾经遇到一个现象业务正常但偶尔有客户端反馈连接卡顿。后来定位发现是后端机器上某条iptables规则拦截了某些源IP的响应包。因为回包是直接发的不走均衡器均衡器的健康检查完全正常只有客户端那边能感知问题。所以做TUN模式排障时一定要把链路拆成几段分别验证客户端到均衡器是否通均衡器隧道到后端是否通后端回包到客户端是否通。每一段用对应的工具验证不能只在均衡器上看状态。4. 环境规划与安装一组可直接复用的配置方案4.1 节点规划与操作系统说明下面这套方案基于我实际搭建过的环境操作系统是CentOS 7.9均衡器用Keepalived做高可用调度算法用加权轮询。角色VIP真实IP额外配置均衡器主节点101.10.10.10172.16.1.10keepalived、ipvsadm均衡器备节点101.10.10.10172.16.1.11keepalived、ipvsadm后端节点A-192.168.100.10隧道IP、VIP绑定后端节点B-192.168.100.11隧道IP、VIP绑定后端节点C-192.168.100.12隧道IP、VIP绑定注意这里后端节点和均衡器IP并不在同一网段这正好是TUN模式的主场。实际生产里你完全可以让后端在另一个城市只要路由可达就行。4.2 均衡器安装配置LVS本身是内核模块不用额外安装什么软件但要装一个管理工具ipvsadm。Keepalived负责VIP漂移和健康检查也需要安装。直接用包管理器安装即可yum install -y ipvsadm keepalived安装完成后先确认内核是否已加载相关模块modprobe ipip lsmod | grep ipip正常情况下能看到ipip模块信息。如果没有说明内核可能裁剪了该模块需要换内核或者确认模块路径。4.3 Keepalived配置详解Keepalived的配置是整个集群的核心之一。它既要负责VIP漂移也要周期性探测后端节点的健康状态然后把探测结果交给ipvsadm去更新转发规则。我的配置文件如下主节点版本global_defs { router_id LVS_TUN_MASTER vrrp_skip_check_adv_addr } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 66 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1024 } virtual_ipaddress { 101.10.10.10 } } virtual_server 101.10.10.10 80 { delay_loop 6 lb_algo wrr lb_kind TUN persistence_timeout 50 protocol TCP sorry_server 127.0.0.1 80 real_server 192.168.100.10 80 { weight 100 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } real_server 192.168.100.11 80 { weight 80 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } real_server 192.168.100.12 80 { weight 60 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } }备节点的配置基本一样只改三处state改为BACKUPpriority改小比如90router_id改个名字。virtual_router_id两边必须一样否则无法组成高可用对。f你问为什么用wrr而不是rr因为后端机器配置不一样A机器64G内存、C机器32G内存权重自然要区分。TCP_CHECK会从均衡器主动向后端发起TCP连接测试这个比较贴近真实业务比单纯ICMP探测更可靠。4.4 启动与验证配置写好后启动Keepalivedsystemctl enable keepalived systemctl start keepalived查看VIP是否正常绑定ip addr show eth0查看LVS转发规则ipvsadm -Ln正常输出会显示每条后端记录的状态。如果后端健康State栏是空白的如果不健康会显示红色状态或直接消失。这里要特别注意默认的Keepalived只认lb_kind参数当你写上TUN时它会自动用tunnel模式去配置ipvsadm规则。5. 后端节点的隧道配置最容易出错的部分5.1 创建隧道设备和绑定VIP后端机器上的配置是整个TUN模式最考验耐心的地方。很多人在这里栽跟头因为不同发行版的网络管理工具语法不一样而且配置完还要考虑重启后是否生效。先手动操作一遍验证通了之后再固化到配置文件。以下命令在后端每台机器上执行modprobe ipip ip tunnel add tunl0 mode ipip remote any local 192.168.100.10 ttl 64 ip link set tunl0 up ip addr add 101.10.10.10/32 dev tunl0解释一下关键参数mode ipip 指定隧道模式为IPIP。remote any 表示允许任意源地址的隧道包进来实际生产中要按需收紧如果有条件可以指定均衡器的地址。local 是后端的物理网卡IP用来标识隧道对端的本地地址。ttl 64 控制隧道包的跳数跨机房场景如果跳数多要适当调大。把VIP以32位掩码绑定到tunl0上这是为了让内核正确处理目标地址为VIP的数据包。执行完用ip addr看应该能看到tunl0上有101.10.10.10。5.2 配置路由策略避免回包走隧道这一步是最容易出问题的地方。想想看后端收到隧道包应用处理完要回包给客户端了。回包的目标IP是客户端的真实IP那么这个包要走哪个网卡默认情况下Linux主路由表里可能有一条默认路由指向物理网关回包会从物理网卡走这正确。但如果后端同时存在其他隧道、或者systemd-networkd自动下发了一些奇怪路由就可能把回包塞回隧道里。一旦回包走隧道客户端根本收不到连接直接挂起。为了避免这种情况我习惯显式加一条路由策略所有目标IP是VIP的包走lo或者tunl0进去其余全部走物理默认路由。再配合反向路径过滤效果更好ip route add 101.10.10.10/32 dev tunl0 sysctl -w net.ipv4.conf.all.rp_filter0 sysctl -w net.ipv4.conf.tunl0.rp_filter0rp_filter是反向路径过滤原理是检查“这个包是从哪个网卡进来的”如果源IP对应的路由出口不是这个网卡就丢弃。隧道场景下包确实是从tunl0进来的但源IP客户端的IP对应的最优出口是物理网卡匹配不上默认就会丢包。所以必须关掉这个过滤否则隧道模式根本跑不起来。5.3 开机自启动配置手动配置好了重启就丢那等于白做。CentOS 7的传统做法是把命令写进/etc/rc.local但注意两个前提rc.local要有执行权限rc.local服务要开机启动。chmod x /etc/rc.d/rc.local systemctl enable rc-local然后把以下内容追加到/etc/rc.d/rc.localmodprobe ipip ip tunnel add tunl0 mode ipip remote any local 192.168.100.10 ttl 64 ip link set tunl0 up ip addr add 101.10.10.10/32 dev tunl0 ip route add 101.10.10.10/32 dev tunl0 sysctl -w net.ipv4.conf.all.rp_filter0 sysctl -w net.ipv4.conf.tunl0.rp_filter0如果你的系统用NetworkManager还可以考虑用nmcli创建隧道连接但说实话rc.local这种方式在纯内网环境里反而更直接、更好控制。新系统用systemd服务文件也行本质是把同样的命令托管给systemd执行。5.4 后端防火墙与SELinux后端机器如果开了firewalld要放行IPIP协议。IPIP协议号是4注意它不是TCP/UDP端口是独立的协议号。命令如下firewall-cmd --permanent --add-rich-rulerule protocol valueipip accept firewall-cmd --reloadSELinux如果处于 enforcing 模式也需要确认策略允许隧道通信。我一般建议在这种模式先把SELinux置于permissive验证功能业务跑通后再考虑是否恢复enforcing。实际上很多公司的内网服务器本身就是permissive或者disabled状态所以这一步经常被忽略但如果你遇到了“隧道包到了后端但后端没反应”的问题记得检查这里。6. 整体链路验证与性能压测6.1 从均衡器验证隧道连通性后端全部配置好后在均衡器上执行以下命令看看隧道是否已经建立ip tunnel show能看到tunl0相关的隧道项才算正常。接着ping后端机器的真实IP确认基础网络通。再ping一下VIP从均衡器本身或者客户端都能测。如果均衡器上ping通VIP且后端能看到tunl0上有流量说明隧道转发基本通了。6.2 从客户端验证完整链路准备一台客户端直接访问VIP地址curl -I http://101.10.10.10/能正常返回HTTP响应头说明整个链路已经通了。如果超时或拒绝按以下顺序排查先在均衡器上看连接统计ipvsadm -Ln --stats观察InActConn和ActiveConn计数判断请求是否到达了均衡器并成功转发。接着在后端抓包tcpdump -i tunl0 host 101.10.10.10如果有包进来但程序没响应可能是后端服务没监听80端口如果完全没有包进来可能是隧道封装有问题。再在后端看回包是否发出tcpdump -i eth0 src host 101.10.10.10如果有回包发出但客户端收不到就要查物理链路的路由和运营商是否丢包了。6.3 压测中的性能数据参考我用模拟的压测工具对一个3后端的TUN集群做过简单验证。均衡器是2核4G的小机器后端是4核8G。压测工具用wrk从一台独立机器发起请求目标是VIP。结果大致是指标数值并发连接数2000总请求量500万均衡器CPU峰值35%后端单机CPU峰值最高75%平均响应时间15ms以内错误率0.02%结论很明确在这种“响应数据量大于请求数据量”的读场景下均衡器CPU压力明显低于NAT模式同规模场景。如果换成NAT模式均衡器大概率已经吃满了。7. 常见问题与排查技巧实录7.1 隧道建立成功但业务不通现象ip tunnel show能看到tunl0ping VIP能通但HTTP请求超时。排查步骤后端执行sysctl -w net.ipv4.conf.tunl0.rp_filter0看看是不是反向路径过滤问题。后端执行tcpdump -i tunl0 port 80看请求包是否到达。后端检查nginx或业务进程是否在80端口监听ss -lntp。检查后端防火墙是否放行80端口和IPIP协议。我遇到的实际情况里rp_filter和防火墙是两大主因。尤其是有些公司有统一安全管理软件会在机器上自动下发防火墙规则你手动加的白名单可能过一阵就被全量刷新掉了非常坑。7.2 转发规则消失现象ipvsadm -Ln能看到规则但过一段时间后端记录没了业务中断。原因Keepalived的健康检查失败自动把后端摘掉了。这时在后端上看看业务进程是否正常或者TCP_CHECK连不上是因为后端防火墙拦了均衡器过来的探测包而业务请求又能正常处理。解决确认业务进程正常、监听端口正常再确认防火墙放行均衡器IP的探测连接。注意Keepalived的TCP_CHECK是模拟TCP连接目标端口就是后端服务端口如果业务程序和健康检查有冲突比如检查太频繁触发限流要适当调整delay_loop和connect_timeout。7.3 多VIP场景的隧道ID冲突现象同一台后端同时服务两个VIP、两条隧道结果隧道互相干扰。原因默认的tunl0设备只有一个IPIP隧道用tunnel ID区分。多个VIP时如果用同一个tunl0且local地址相同、remote any可能出现路由混淆。解决创建多个隧道设备分别命名每个隧道绑定一个VIP和对应的remote范围。比如ip tunnel add tunl1 mode ipip remote 172.16.1.10 local 192.168.100.10 ttl 64 ip link set tunl1 up ip addr add 101.10.10.11/32 dev tunl1同时用策略路由控制每个隧道的流量方向避免交叉。7.4 均衡器高可用切换后连接全断现象主均衡器挂了VIP漂移到备机但是所有活跃连接都断了。原因LVS本身是状态保持的但Keepalived默认状态切换时较老版本的转发规则不会自动同步连接状态表。实际生产里如果业务对长连接敏感需要评估这个中断时间。对于HTTP短连接场景影响很小对于数据库长连接场景可能需要应用层做重连机制。解决短连接场景直接忽略长连接场景建议在应用配置里增加连接重试和断线重连逻辑。数据库连接池一般自带这个能力配置好就行。8. 部署架构优化与灾备建议8.1 均衡器双机热备的细节前面Keepalived例子已经配置了主备但有几个细节值得多说几句。主备节点之间的通信走VRRP协议默认组播地址是224.0.0.18。如果交换机禁用了组播要改用单播配置。在vrrp_instance里加unicast_src_ip 172.16.1.10 unicast_peer { 172.16.1.11 }这样可以避免很多组播环境下的隐性问题。另外备机也要安装ipvsadm等VIP漂移过来时才能按配置生成规则实际配置都写在两块机器的Keepalived.conf里保持同步即可。8.2 后端节点的自动化初始化脚本后端节点多了以后手工配置不现实。我把整个后端初始化流程做成了一个脚本核心步骤包括加载模块、建隧道、绑VIP、配路由、调rp_filter、写rc.local。每次新机器上线执行一遍脚本再用测试请求验证即可。脚本要支持参数传入local IP和VIP列表避免每台机器单独改文件。这样做还有一个好处出错概率低因为所有机器用的都是同一套经过验证的配置逻辑。脚本本身建议放在版本管理里变更走review流程。8.3 监控与告警的关键指标TUN集群需要重点监控的指标包括均衡器的活跃连接数和新建连接速率判断转发压力。后端节点的隧道流量和物理网卡流量判断回包是否正常。隧道的丢包率用ping和mtr都能观察跨机房尤其重要。Keepalived的VIP漂移状态一旦发生漂移要立即告警。健康检查失败次数提前预判后端故障。我自己平时用PrometheusAlertmanager来做监控ipvs的监控指标可以通过exporter获取隧道流量可以用node_exporter的基础网络指标替代。告警阈值需要根据业务压测结果设定不要太灵敏避免业务抖动时误报刷屏。9. 个人实战经验总结LVS-TUN模式是我在多个规模不等的集群里实际验证过的方案整体感受是值得学值得用但要清楚它的适用边界。它的优势相当明显响应流量不经过均衡器集群扩展性比NAT模式高出一个量级支持后端跨机房部署灵活度比DR模式强配置虽然多一点但不算复杂逻辑理顺之后就是一套机械操作。它也有麻烦的地方隧道配置和rp_filter这种内核参数初期不熟悉的时候容易踩坑跨机房网络质量差时隧道本身会增加一点开销和延迟故障定位需要同时看均衡器、隧道、后端回包多段链路对排障经验要求更高。如果你想在生产环境用TUN模式我给你几条最实在的建议第一先在测试环境完整跑一遍把所有配置都固化成自动化脚本确认重启后依然生效再上生产。第二精简你的隧道配置权限能用remote指定均衡器地址就不要用any减少安全面。第三压测不要只测均衡器要从客户端侧测完整链路否则可能后端回包链路已经出了问题你却毫无察觉。第四监控报警要覆盖到后端回包方向不能只看均衡器状态。我把这套方案落地之后集群扛住了几倍于平时的流量高峰均衡器CPU一直处于很低水平后端节点整体负载也比之前均匀得多。如果你正在面临类似的架构选择TUN模式值得纳入你的候选清单里它会是一把很趁手的工具。就分享到这里有具体的问题可以按上面的思路去排相信你也能把它跑得很稳。