做基础设施的同行应该都听过这么一句话:互联网巨型流量入口,一半靠 DNS 在全局调度,另一半就靠 LVS 这类四层负载均衡在机房门口扛着。LVS,全称 Linux Virtual Server,本质是内置于 Linux 内核的负载调度模块,它把一组真实服务器打包成一个虚拟服务,对外只暴露一个 VIP。十多年过去了,云原生、容器化、Service Mesh 这些名词轮番登场,但你会发现真正承接入流量的第一道闸门里,LVS 依然牢牢占着位置。这篇文章想把 LVS 的转发原理、DR 模式细节、Keepalived 高可用搭建、亿级流量下的调优和排查思路,以及它在云原生场景中的变形记都捋一遍。刚接触负载均衡的人可以靠它建立完整体系;已经用了多年 LVS 但一直没把“回包为什么能绕过调度器”这种问题讲明白的人,也能当成一份对照手册。
1. 云原生这台戏,LVS 凭什么还是主角
1.1 先回答一个扎心问题:云原生到底还需不需要四层负载
很多人一说云原生,脑子里全是 Kubernetes、Ingress、Envoy、Istio,下意识觉得 LVS 这种“老古董”应该进博物馆了。但你在生产环境待过几年就会明白,四层负载和七层负载从来就不是替代关系,而是分工关系。Ingress 和 Service Mesh 解决的是 HTTP 层的路由、限流、认证、灰度问题,它们本质上是用户态进程,每来一个连接都要经过协议栈、用户态拷贝、事件循环,性能天花板肉眼可见。而流量入口那一道闸,要求的是每秒几十万甚至上百万的新建连接,以及极高的包转发稳定性,这时候内核态的 LVS 反而是最稳的选择。
我见过很多业务第一反应是“我用 Nginx stream 模块做四层转发不就行了吗”,确实可以,小流量没问题。但流量一旦到亿级,你就能体会到 Nginx 四层模式在 CPU 开销、文件描述符、内存分配上的压力。LVS 因为跑在内核态,不需要把每个包拷贝到用户态再转发,仅仅靠查哈希表和改写 MAC/IP 就能完成一轮调度,性能天然高出好几个量级。现在公有云的 SLB、各种云网关的底层转发引擎,很多思路也跟 LVS 同源。换句话说,你可以不用 LVS,但必须理解四层负载的原理,否则云时代出了问题根本不知道从哪里排查。
1.2 四层与七层分工:LVS 在云原生架构里的真实占位
架构上我习惯把流量看成两条链路。第一条是南北向链路,客户端从公网进来,先经过 DNS 解析到入口网关集群,入口网关用 LVS 做 VIP 和主备漂移,把流量分给后面的七层网关,七层网关再路由到具体服务。第二条是东西向链路,服务之间互相调用,这部分云原生里确实被 Service Mesh 和 kube-proxy 接管了,但 kube-proxy 的 IPVS 模式底层调用的依然是 LVS 的内核模块。也就是说,LVS 不只活在传统机房架构里,它还以 IPVS 的身份活在 Kubernetes 的每个 Node 上。
真正让我觉得必须懂 LVS 的原因,是一次线上事故。业务反馈“某个内部服务偶尔超时”,我们查了很久,最后定位到 Node 上 iptables 规则膨胀导致 netfilter 遍历太慢,改成 IPVS 模式后立刻缓解。那一刻我才意识到,Kubernetes 默认的 iptables 转发在规则少时没问题,规则一多就会拖累整机转发,而 IPVS 用哈希表代替链式遍历,复杂度完全不在一个级别。所以学 LVS 不是为了怀旧,是为了在云原生时代遇到问题时,你能一眼看穿底层到底发生在哪一层。
2. 原理不过关调优全白搭:LVS 数据包转发与三大模式
2.1 内核态转发的秘密:LVS 为什么这么快
LVS 的核心组件叫 IPVS,是集成在 Linux 内核 netfilter 框架里的模块。它的工作方式可以概括成一句话:在进入协议栈的处理路径上挂钩子,根据目标 IP 和端口查虚拟服务器表,选出一台真实服务器,然后改写数据包的关键字段再放出去。整个过程不经过用户态,不创建完整的 socket,没有上下文切换,也没有数据在用户态和内核态之间的反复拷贝,这决定了它的转发开销极小。
你可以把 LVS 想象成一个交通路口的安全岛。它不跟车辆一起走,只站在路口看一眼车牌,指挥车往哪条车道拐。Nginx 七层转发则像交警亲自上车开一段路,然后再下来,服务能力强但每辆车都要付出额外代价。理解了这一点,你就能明白为什么在超大并发下 LVS 单机能扛住、而用户态转发容易先耗尽 CPU。性能调优的逻辑也就清楚了:LVS 的瓶颈往往不在调度逻辑本身,而在网卡收包、软中断处理、哈希链表冲突这些外围环节。
2.2 DR、NAT、TUNNEL 三种模式的本质区别与选型表
LVS 有三种经典工作模式,网上资料一大把,但很多人背了概念还是不会选。我换个角度,从“回程流量走不走调度器”这个关键点去理解,一抓一个准。
NAT 模式,调度器改写目标 IP 为真实服务器 IP,后端把响应回给调度器,调度器再改源 IP 为 VIP 发给客户端,所以请求和响应都经过 LVS。优点是后端服务器只需要把默认网关指到调度器,不挑剔网络拓扑;缺点是调度器容易成为瓶颈,而且源地址转换逻辑复杂一些。TUNNEL 模式,调度器把原始包封装在 IPIP 隧道里发给后端,后端解封装后直接回包给客户端,不回调度器,因此能跨三层网络部署;代价是隧道封装带来额外带宽和 CPU 开销,且要求后端支持 IPIP。DR 模式,调度器只改写目标 MAC 地址为真实服务器的 MAC,后端绑定一个 VIP 在 loopback 口上接收流量,回包直接发给客户端。DR 不回调度器、没有隧道封装开销,是三种模式里性能最高、也最常用的一种。
用表格总结一下三种模式的差异:
| 对比维度 | NAT | TUNNEL | DR |
|---|---|---|---|
| 调度器改动 | 改目标 IP | IPIP 封装 | 改目标 MAC |
| 回程是否经过调度器 | 是 | 否 | 否 |
| 对后端网络要求 | 同网段或可路由 | 需支持 IPIP,可跨三层 | 必须与调度器同二层 |
| 后端是否需要绑定 VIP | 不需要 | 需要 | 需要,且要抑制 ARP |
| 性能表现 | 中等 | 中高 | 高 |
| 适用场景 | 小规模、混部环境 | 跨机房、跨地域调度 | 同机房大流量入口 |
生产环境里我最常用 DR 模式。同机房物理机、虚机混部,LVS 两台做主备,后端一堆 Nginx,全部二层互通,DR 模式压出来的并发非常可观。TUNNEL 模式我也见过有人搞跨机房调度,但如果只有两三个机房,很多时候直接每个机房各自一套 LVS 更简单,反而不用折腾隧道。
2.3 调度算法选择:生产环境里用得最多的几类
IPVS 支持的调度算法非常多,RR、WRR、LC、WLC、SH、DH 等。原理不复杂,关键在于不同场景怎么选。
RR 轮询适合后端性能完全一致、连接都很短的场景,比如临时测试环境。LC 最少连接适合长连接场景,但它不考虑后端权重,机器规格不一致时容易失衡。WLC 加权最少连接是生产环境里的万金油,它兼顾了后端权重和当前连接数,官方默认调度算法也是 WLC,我自己的 LVS 集群绝大多数时间就用它。SH 源地址哈希适合需要会话保持的场景,比如同一客户端 IP 一直打到一个后端做有状态服务,但这种做法在 NAT 和代理后面效果一般,用到时要注意客户端出口 IP 是否稳定。DH 目标地址哈希则适合后端是独立缓存集群时按请求目标做固定分发。
再补充一个很多人忽略的点:LVS 调度算法调整可以热生效,不用重启服务,也不用断开已有连接。线上如果发现某台后端连接数异常高,先用ipvsadm -Lnc看一下分发记录,再根据情况调整权重或者直接临时摘除节点,这个过程可以非常平滑。
3. 从零搭建 LVS-DR 高可用集群:Keepalived+LVS 完整实战
3.1 实验拓扑、角色划分与环境准备
纸上谈兵没意思,直接上一套可以在虚拟机里复现的实验环境。我用两台机器做 LVS 调度器,一主一备;三台机器做后端真实服务器 RS,跑 Nginx;一台客户端负责压测验证。VIP 规划为 192.168.100.100,后端业务端口用 80。
| 主机角色 | IP 地址 | 说明 |
|---|---|---|
| LVS-Master | 192.168.100.10 | 运行 Keepalived,MASTER |
| LVS-Backup | 192.168.100.20 | 运行 Keepalived,BACKUP |
| RS-1 | 192.168.100.11 | Nginx,页面标识 rs1 |
| RS-2 | 192.168.100.12 | Nginx,页面标识 rs2 |
| RS-3 | 192.168.100.13 | Nginx,页面标识 rs3 |
| Client | 192.168.100.200 | 验证访问 VIP |
操作系统用 CentOS 7 或更高版本,网卡名以实际机器为准,我下面统称 ens32。安装前先关闭 SELinux,把时间同步和主机名配置好,避免排查问题时出现干扰项。调度器和管理端不需要额外软件,RS 侧也只要一个 Nginx。整个集群需要保证二层互通,因为 DR 模式依赖 MAC 转发,实验环境里所有机器都在同一网段,天然满足条件。
3.2 Director 配置:用 Keepalived 托管 VIP 和 IPVS 规则
调度器上安装软件:
yum install -y ipvsadm keepalived先不急着写配置文件,我习惯把 LVS 规则手动敲一遍,确认转发逻辑没问题,再交给 Keepalived 托管。手动配置的意义在于让你看清每一步到底做了什么,避免后面出了问题怪 Keepalived。第一条是把 VIP 挂在物理网卡的子接口上:
ip addr add 192.168.100.100/32 dev ens32 label ens32:0注意掩码用 32 位,不要用 24 位。VIP 不应该广播出去,只作为本机的一个地址存在,这样能避免跟局域网内真正拥有该网段的设备产生 ARP 冲突。然后添加虚拟服务器和真实服务器:
ipvsadm -A -t 192.168.100.100:80 -s wlc ipvsadm -a -t 192.168.100.100:80 -r 192.168.100.11:80 -g -w 1 ipvsadm -a -t 192.168.100.100:80 -r 192.168.100.12:80 -g -w 1 ipvsadm -a -t 192.168.100.100:80 -r 192.168.100.13:80 -g -w 1-g表示 DR 模式,-i表示 TUNNEL 模式,-m表示 NAT 模式,一定要区分清楚。配置完执行ipvsadm -ln应该能看到虚拟服务器和 RS 列表。这里有个老手容易踩的坑:DR 模式不需要开启net.ipv4.ip_forward,因为调度器只是二层改写,不是三层转发;NAT 模式才必须开启。别一上来就照抄 NAT 教程把转发打开,DR 模式下这属于多余操作,虽然一般不会导致故障,但会让排查思路变乱。
确认手动模式正常后,把规则删除,改用 Keepalived 统一管理:
ipvsadm -CKeepalived 的 Master 配置如下,Backup 只需要改state和priority:
global_defs { router_id LVS_MASTER } vrrp_instance VI_1 { state MASTER interface ens32 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.100.100/32 dev ens32 label ens32:0 } } virtual_server 192.168.100.100 80 { delay_loop 6 lb_algo wlc lb_kind DR protocol TCP real_server 192.168.100.11 80 { weight 1 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } real_server 192.168.100.12 80 { weight 1 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } real_server 192.168.100.13 80 { weight 1 TCP_CHECK { connect_timeout 3 nb_get_retry 3 delay_before_retry 3 connect_port 80 } } }这个配置文件里有几个关键点。lb_algo和lb_kind是 Keepalived 生成 IPVS 规则的核心参数,lb_kind DR必须大写。TCP_CHECK 是后端健康检查,Keepalived 每 6 秒探测一次,三次失败就自动摘除 RS,恢复后自动加回来,这是线上摘流、挡故障的基础。如果配置里存在vrrp_strict且没有注释掉,很可能会把 VIP 之外的非 VRRP 流量过滤掉,导致健康检查和业务请求异常,建议先注释掉再重启服务。启动后执行ipvsadm -ln,你会发现规则已经被 Keepalived 自动下发,手动配置可以彻底放假了。
3.3 RS 侧配置:VIP 绑定与 ARP 抑止,这是 DR 模式的核心难点
DR 模式最容易翻车的地方不在 Director 侧,而在 RS 侧。因为 RS 收到的数据包目标 IP 是 VIP,如果 RS 上不绑定 VIP,操作系统会把包当作目的不可达直接丢弃;可一旦绑了 VIP,又会产生一个新的问题:RS 会响应局域网里对 VIP 的 ARP 请求,导致客户端或者交换机把本该发给 Director 的包发给某台 RS,整个负载均衡就没意义了。解决办法是绑定 VIP 的同时抑制 ARP 响应。
RS 上执行:
ip addr add 192.168.100.100/32 dev lo label lo:0然后修改内核 ARP 参数:
sysctl -w net.ipv4.conf.all.arp_ignore=1 sysctl -w net.ipv4.conf.all.arp_announce=2 sysctl -w net.ipv4.conf.lo.arp_ignore=1 sysctl -w net.ipv4.conf.lo.arp_announce=2为了保证重启后不失效,再把这个配置写进/etc/sysctl.conf。这里我建议不要只配 all 和 lo,生产环境里最好写一个初始化脚本,遍历所有非 lo 接口挨个设置。原因是all参数对某些内核版本和接口组合并不总能完整生效,而 RS 上接收外部请求的入口往往是物理网卡,不是 lo,稳妥起见全部设置一遍。
arp_ignore=1的意思是:只有 ARP 请求的目标 IP 是本机某个接口的 IP 时才响应。配置之前,RS 的 lo 上有 VIP,于是它对“谁有 192.168.100.100”的请求也抢答;配置之后,除非请求目标 IP 正好是物理网卡自己的 IP,否则不理会。arp_announce=2的意思是:发送 ARP 报文时优先使用能够路由到目标的最优本地地址,避免把自己的 VIP 当作源地址宣告出去。这两个参数配合,RS 就能安静地接收 Director 发来的数据包,同时对外保持“隐身”。
DR 模式下 RS 的默认网关不要指向 LVS Director,回包必须走正常的物理网络直接回给客户端。如果回程绕回 Director,就会形成环路或者单点瓶颈,这也是新手最容易搞错的地方。
3.4 联调验证与故障转移演练
配置完成后,在客户端访问:curl http://192.168.100.100/。反复执行几次,应该在 rs1、rs2、rs3 三个标签之间轮换。如果始终只有一台,先看ipvsadm -Lnc的连接表,确认调度算法和权重是否生效,再看那台 RS 的 Nginx 日志是否收到了请求。
在 Director 上看实时连接分发:
ipvsadm -Lnc输出会显示每条连接被分配到的 RS 和目标地址,配合ipvsadm -Ln --stats可以看累积流量。做故障演练时,把某台 RS 的 Nginx 停掉,Keepalived 会在几个探测周期后把它从 RS 列表中摘除,新的请求不会继续分给它;再把 Master 调度器停机,Backup 会在 VRRP 广告超时后接管 VIP,继续对外服务。整个过程建议用客户端持续循环 curl 观察丢包情况,你会发现切换时间通常在 1 到 2 秒内,业务无感。
这里补充一个数据面验证技巧:在 RS-1 上用tcpdump -i eth0 host 192.168.100.100抓包,你会看到来的包源 IP 是客户端真实 IP,目标 IP 是 VIP,但源 MAC 是 Director 的 MAC,目标 MAC 是 RS-1 自己的 MAC。这个特征能立刻确认 DR 模式的二层转发链路是否正常。
4. 亿级流量面前的性能调优与线上排查实录
4.1 内核参数、软中断与网卡:LVS 单机性能怎么压
LVS 本身调度非常轻,真正压垮单机的东西经常在“收包”环节。高并发下数据包到达网卡,CPU 要通过硬中断和软中断去处理,这部分如果只压在某个 CPU 核上,就会形成明显的热点。我常用的优化套路,第一是确认网卡多队列已开启,第二是让软中断均衡到多个 CPU 上。用ethtool -l eth0能看到网卡当前队列数量,如果只有一个队列,说明网卡把全部包都塞进一条队列,后面的核就是摆设。用ethtool -L eth0 combined 4之类的命令把队列数提上来后,再把对应中断号绑到不同 CPU 上。
内核参数方面,我给一套在 LVS 入口服务器上实测效果比较好的常见组合。net.ipv4.tcp_syncookies=1用来防 SYN Flood,入口服务器建议开启;net.core.somaxconn=65535和net.ipv4.tcp_max_syn_backlog=65536一起调整,避免高并发下握手队列被塞满;net.core.netdev_max_backlog=65536加大网卡队列的背压容量。如果你的 LVS 要用 NAT 模式,还要关注net.netfilter.nf_conntrack_max,连接跟踪表一旦打满,新连接直接被丢弃,这是最容易忽略的隐形故障点。
DR 模式因为不修改 IP,通常不依赖 nf_conntrack,我反而不建议在 Director 上额外开启不必要的 netfilter 逻辑。还有一个经验是,尽量别在 LVS 跟后端之间串 iptables 做过滤,iptables 规则会挂在 netfilter 链路上,跟 IPVS 抢路径,规则一多性能下降非常明显。实在需要安全策略,放到后端的七层网关做更合适。
4.2 线上问题排查:四个高频故障与排错思路
再稳定的集群,线上也会遇到奇怪的故障。我把自己踩过和帮别人处理过的典型问题整理成一张速查表:
| 故障现象 | 可能原因 | 排查思路与处理 |
|---|---|---|
| VIP ping 不通,业务全挂 | MASTER 宕机且 BACKUP 未接管,或 VIP 掩码配置错误 | 看两台 Director 的ip addr是否有 VIP;VRRP 是否正常;检查 VIP 配置掩码是否为 32 |
| RS 上绑了 VIP,但 DR 模式下始终收不到包 | ARP 抑制没生效或 lo 上 VIP 未绑定 | 检查 `sysctl -a |
| 后端看到的源 IP 全是 VIP | 实际配置成了 NAT 或 FULLNAT,而不是 DR | 查看ipvsadm -L的转发标志;确认 lb_kind 是否为 DR,-g会被错误写成-m |
| 连接能建立但业务超时,后端日志没请求 | 回程流量绕行 Director 或被交换机丢弃 | 在 RS 上traceroute到客户端出口 IP,确认回包没经过 Director;检查交换机端口安全策略 |
| 两台 Director 同时持有 VIP | Keepalived 脑裂,VRRP 心跳被阻断 | 两台都看ip addr;检查防火墙是否放行 VRRP 组播,或改用 unicast 方式指定对端地址 |
第三类故障值得多说一句。很多新手在配置 RS 时发现“流量进来了,但 RS 处理完就超时”,原因多半是回包路径错误。DR 模式下,RS 回包的目标是客户端 IP,默认网关必须指向物理网络的正常出口,绝对不能指向 LVS Director。一旦指向 Director,回包会回流到调度器,但 Director 并没有对应的用户态连接来接管这个包,最终陷入一种奇怪的超时状态。
第四类脑裂问题,线上往往比表里写的更隐蔽。VRRP 组播默认走 224.0.0.18,端口协议号为 112,如果交换机开启了 IGMP Snooping,或者两台 Director 之间配置了防火墙规则,都有可能导致心跳报文收不到,于是两台机器都认为自己是 MASTER,同时宣告 VIP。解决办法有两个方向:一是在防火墙上放行 VRRP,二是改成显式指定对端地址的 unicast 模式,避免依赖组播。配置完一定要在两端各执行一次tcpdump -i ens32 vrrp确认心跳在走。
4.3 横向扩展:单机有瓶颈时 LVS 集群怎么设计
再强的单机也有极限,网卡带宽或者说整机软中断处理能力到了瓶颈之后,就要考虑横向扩展。传统方案是再堆一组主备,但这样每组都是“一主一备两台机器只流出同一份流量”的模式,利用率不高。更现代的做法是把相同的 VIP 通过 BGP 宣告到接入交换机,利用路由器的 ECMP 等价多路径把流量分散到多台 LVS 上,每台 LVS 之间不再抢占同一个 VIP,而是同时工作,故障时通过 BGP 撤销路由来自动摘除。
这种“LVS 集群 + ECMP + BGP”的架构,本质上跟云厂商负载均衡的分布式网关很像。它要求你懂一点 BGP,需要独立维护一个 AS 号和一套网络设备联动策略,复杂度比 Keepalived 单主备高不少。中小规模没必要上,但真正走到每秒百万级以上的入口流量时,这是最成熟、最不依赖云厂商的扩展路径之一。云原生时代,很多公司表面上在用云 LB,但内网入口依然保留着这一套自建四层集群,原因就是可控性和成本。
5. 云原生落地:LVS 在 Kubernetes 和容器栈里的变形记
5.1 Kube-proxy IPVS 模式:大规模 Service 转发的更优解
Kubernetes 的 Service 默认转发模式是 iptables。规则少时一切正常,可集群规模一大,问题就出来了:每个 Service 和每个 Endpoint 都会生成多条 iptables 链,请求从节点进来到最后转发出去,netfilter 要沿着链一条一条匹配,规则一多延迟和 CPU 消耗全部上来。我自己维护的集群在 Service 数量超过几百个之后,已经能明显感觉到某些节点的转发开销异常。把 kube-proxy 切成 IPVS 模式后,规则数量骤减,因为 IPVS 用的是哈希表加内核态调度,查找复杂度接近 O(1),规则多少对单包匹配的影响远小于 iptables 的链式遍历。
切换方式说穿了也很简单:修改 kube-proxy 的 ConfigMap,把mode字段从iptables改成ipvs,然后滚动重启 kube-proxy。切换之后,你可以用ipvsadm -Ln看到每个 ClusterIP 对应的后端列表,调度算法默认是 rr,需要会话保持的话可以改成lc或者sh。这算是云原生场景里最直观的 LVS 复现,换个名字叫 IPVS,内核里干的还是那套虚拟服务器调度的事。
5.2 入口网关组合拳:LVS+Keepalived+Nginx/Envoy
容器化之后,南北向入口的经典架构并没有翻天覆地,而是从“LVS -> Nginx -> 后端物理机”变成了“外界 -> LVS -> Nginx/Envoy -> Kubernetes NodePort -> Pod”。最外面依然是一对或一组 LVS 加 VIP,后面挂 Nginx 或 Envoy 集群做七层路由。为什么不用 NodePort 直接对外暴露?因为 NodePort 本质是在每台 Node 上开一个随机端口做 DNAT,流量经 iptables 分发到 Pod,既要处理负载均衡又要承担七层业务的压力,规则复杂又缺少统一入口的会话保持能力。用 LVS 把 VIP、主备切换、四层分发这些事包住,后面的七层网关集群无论是扩缩容还是灰度发布,都自由得多。
这套组合里,LVS 的 TCP_CHECK 健康检查要特别用心。它探测的是后端的 80 或 443 端口,如果七层网关进程挂起但端口还活着,LVS 会一直转发流量过去造成业务方“间歇性超时”。生产上我习惯把健康检查脚本化,在 Keepalived 的 MISC_CHECK 里写脚本,检查不只是 TCP 端口,还要做一次真实 HTTP 请求,状态码不合预期就直接把节点摘掉。这个细节在云原生架构里尤其重要,因为 Envoy 这类网关自身有多线程和健康检查状态机,单纯端口探测很容易漏判。
5.3 MetalLB 和云负载均衡背后的 LVS 思路
云原生里还有一个经常跟 LVS 联系在一起的项目叫 MetalLB,它负责给裸金属 Kubernetes 集群里的 LoadBalancer 类型 Service 分配外部 IP。很多人没意识到,MetalLB 的 Layer2 模式,本质上就是让集群中的某个节点把 Service VIP 通过 ARP/NDP 宣告到二层网络,由这一个 Leader 节点接收流量并分发给后面的 Pod。你可以把它理解成一个“用户态的 Keepalived VIP 漂移”,选举机制类似,ARP 宣告类似,连“谁是 Leader 谁响应”的思路都完全一致。它跟 LVS 的唯一区别是:不靠内核协议栈改写 MAC,而是靠节点接入后把流量导进集群网络。
MetalLB 的 BGP 模式就更明显了,把 Service VIP 前缀通过 BGP 宣告给交换机,路由器用 ECMP 把流量分到多个节点,故障时撤销路由,这跟前面说的多台 LVS 加 ECMP 横向扩展是同一套思想。云厂商的 SLB 底层虽然是一大堆商业芯片和自研网关,但对外模型依然还是“一个 VIP,一组后端,健康检查自动摘除,调度算法支持加权轮询和最小连接数”,这些概念跟 LVS 如出一辙。所以我在带新人的时候常说一句话:把 LVS 吃透,你再看云负载均衡、再看 MetalLB、再看 Kube-proxy IPVS,全部是同一个模型套着不同的皮。
我做了这么多年基础架构,最大体会是转发协议会迭代,工具会换名字,但架构思想往往是延续的。哪一天你在云控制台发现某个负载均衡行为诡异,或者在 Kubernetes 里遇到 IPVS 转发的超时,回头想想这套“虚拟服务 + 真实服务器 + 调度算法 + VIP 漂移”的模型,很多坑都能解释通。这篇文章里那套 Keepalived+LVS 的配置,拿到今天的生产环境依然能直接闭合使用,它未必是最时髦的方案,却是最稳定的底座之一。希望你能把这块基石踩实,后面再往前走就不容易晃了。