5.8 负载均衡进阶——LVS + Envoy 代理实战
预计阅读时间:14 分钟
📖 目录
当业务规模突破单机瓶颈后,四层负载均衡 LVS + 七层代理 Envoy 的组合成为高并发架构的标配方案。本文从 LVS 三种工作模式的原理出发,结合 Keepalived 实战配置,再到 Envoy 代理架构与 API 网关能力,最后横向对比主流负载均衡技术选型。
学习目标
- 理解 LVS 的 NAT、DR、TUN 三种工作模式的转发原理、性能差异与适用场景
- 能部署 LVS DR 模式 + Keepalived 实现 VIP 漂移与后端健康检查
- 能编写 Envoy 静态配置,并理解 xDS 动态配置与热重启机制
- 能利用 Envoy 的路由、熔断(Outlier Detection)、全局限流构建 API 网关
- 能根据业务规模在 LVS、HAProxy、Nginx、Envoy 之间做出选型决策
- 能排查 VIP 漂移、ARP 配置、健康检查误切换等典型故障
前置知识
- 5.7:HAProxy 负载均衡 HAProxy 负载均衡——四层/七层负载均衡与健康检查概念基础
- 5.5:防火墙实战 防火墙实战——Netfilter 框架与 NAT 原理是理解 LVS 内核态转发的前提
- 6.15:HA 集群 HA 集群——Keepalived/VRRP 漂移与仲裁机制是 LVS 高可用的核心
- 3.4:Nginx Web服务器 Nginx Web 服务器配置与管理——upstream 负载均衡与七层代理的对比参照
LVS 三种模式原理与对比
LVS(Linux Virtual Server)是运行在内核态的四层负载均衡器,工作在 Netfilter 框架之上,通过修改数据包目标地址或封装新报文实现流量分发。
NAT 模式(Network Address Translation)
LVS 作为网关,将客户端请求的目标 VIP 地址替换为后端 Real Server 的 RIP 地址。响应报文必须经过 LVS 回传给客户端。
| 特性 | 说明 |
|---|---|
| 工作层次 | 四层,修改目标 IP |
| 响应路径 | 必须回经 LVS(瓶颈所在) |
| 后端网络 | RIP 可以是私网地址,无需公网 |
| 性能瓶颈 | LVS 出口带宽成为整个集群上限 |
| 适用场景 | 小规模集群,后端数量 < 20 |
DR 模式(Direct Routing)
LVS 仅修改请求报文的目标 MAC 地址为 Real Server 的 MAC,响应报文由 Real Server 直接发回客户端,不经过 LVS。
| 特性 | 说明 |
|---|---|
| 工作层次 | 二层,修改目标 MAC |
| 响应路径 | Real Server 直接回复客户端 |
| 后端网络 | 所有节点必须在同一二层网络 |
| 性能 | 最优,LVS 仅处理入方向流量 |
| 适用场景 | 同机房大规模集群的首选方案 |
TUN 模式(IP Tunneling)
LVS 将原始报文封装在新 IP 报文中发给 Real Server,Real Server 解封装后直接回复客户端。支持跨网段、跨地域部署。
| 特性 | 说明 |
|---|---|
| 工作层次 | 三层,IP 隧道封装 |
| 响应路径 | Real Server 直接回复客户端 |
| 后端网络 | 支持跨网段、跨机房 |
| 限制 | Real Server 需支持 IP 隧道 |
| 适用场景 | 跨地域的全局负载均衡 |
三种模式对比总结
| 对比维度 | NAT | DR | TUN |
|---|---|---|---|
| 修改层级 | 目标 IP | 目标 MAC | IP 隧道封装 |
| 响应是否回经 LVS | 是 | 否 | 否 |
| 网络拓扑要求 | LVS 做网关 | 同一二层 | 支持隧道 |
| LVS 瓶颈 | 出方向带宽 | 几乎无 | 几乎无 |
| 可扩展性 | 低 | 高 | 高 |
| 生产推荐度 | 低 | ★★★★★ | ★★★★ |
最佳实践:绝大多数生产环境使用 DR 模式。它性能最优、实现最成熟,是 LVS 官方推荐的默认模式。只有在无法保证二层互通时才考虑 NAT 或 TUN。
LVS + Keepalived 配置实战
Keepalived 提供 LVS 的健康检查和故障自动切换,通过 VRRP 协议实现高可用。
安装与基础配置
# 两台 LVS 节点均执行
yum install -y ipvsadm keepalived
# 启用内核参数(所有 LVS 节点)
cat >> /etc/sysctl.conf <<EOF
net.ipv4.ip_forward = 1
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
EOF
sysctl -p
Keepalived 主节点配置
# /etc/keepalived/keepalived.conf(MASTER 节点)
global_defs {
router_id LVS_MASTER
script_user root
enable_script_security
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.100/24
}
}
virtual_server 192.168.1.100 80 {
delay_loop 3
lb_algo rr
lb_kind DR
persistence_timeout 0
protocol TCP
real_server 192.168.1.201 80 {
weight 1
HTTP_GET {
url {
path /health
status_code 200
}
connect_timeout 3
retry 3
delay_before_retry 1
}
}
real_server 192.168.1.202 80 {
weight 1
HTTP_GET {
url {
path /health
status_code 200
}
connect_timeout 3
retry 3
delay_before_retry 1
}
}
}
Keepalived 备节点配置
# /etc/keepalived/keepalived.conf(BACKUP 节点)
# 与主节点差异仅两处:
# state BACKUP
# priority 90
# 其余配置完全相同
后端 Real Server 配置
# 每台 Real Server 执行:绑定 VIP 到 lo 并抑制 ARP
ip addr add 192.168.1.100/32 dev lo
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
注意:Real Server 上的 VIP 绑定在 lo 接口,使用 /32 掩码。arp_ignore=1 和 arp_announce=2 是 DR 模式正常工作的必要条件,否则会与 LVS 抢占 VIP 的 ARP 响应。
Envoy 代理架构
Envoy 是 CNCF 毕业项目,用 C++ 编写的高性能七层代理,天然支持云原生服务网格架构。
xDS API 动态配置体系
Envoy 最大优势在于所有配置均可通过 xDS API 动态下发,无需重启进程:
| xDS API | 控制内容 | 典型场景 |
|---|---|---|
| LDS | Listener 配置 | 监听端口、过滤器链 |
| RDS | Route 配置 | 路由规则、权重分流 |
| CDS | Cluster 配置 | 上游集群、负载均衡策略 |
| EDS | Endpoint 配置 | 后端实例列表、健康状态 |
| SDS | Secret 配置 | TLS 证书、密钥动态下发 |
与传统代理需要 reload 不同,Envoy 的配置推送是增量的、最终一致的,控制面(如 Istio Pilot)可实现秒级配置生效。
Envoy 基础配置示例
# envoy.yaml 基础配置
static_resources:
listeners:
- name: listener_0
address:
socket_address:
address: 0.0.0.0
port_value: 8080
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: backend
domains: ["*"]
routes:
- match:
prefix: "/api/v1"
route:
cluster: api_service
timeout: 30s
http_filters:
- name: envoy.filters.http.router
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
clusters:
- name: api_service
type: EDS
lb_policy: ROUND_ROBIN
eds_cluster_config:
eds_config:
api_config_source:
api_type: GRPC
grpc_services:
- envoy_grpc:
cluster_name: xds_cluster
Envoy 作为 API 网关
Envoy 具备丰富的 L7 过滤器,可直接作为 API 网关承担路由、熔断、限流等核心职责。
路由与灰度发布
# 基于 Header 的灰度路由
route_config:
virtual_hosts:
- name: canary
domains: ["*"]
routes:
- match:
headers:
- name: x-canary
exact: "true"
route:
cluster: api_canary
- match:
prefix: "/"
route:
cluster: api_stable
熔断配置(Outlier Detection)
clusters:
- name: api_service
outlier_detection:
consecutive_5xx: 5 # 连续5个5xx触发熔断(与 consecutive_gateway_failure 互斥,二选一)
interval: 10s # 检测间隔
base_ejection_time: 30s # 最小驱逐时间
max_ejection_percent: 50 # 最大驱逐比例
全局限流(Global Rate Limiting)
# HTTP 过滤器中启用限流
http_filters:
- name: envoy.filters.http.ratelimit
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.ratelimit.v3.RateLimit
domain: production
failure_mode_deny: true
rate_limit_service:
grpc_service:
envoy_grpc:
cluster_name: rate_limit_cluster
transport_api_version: V3
生产建议:将 Envoy 的 xDS API 与 Istio 或自研控制面配合使用,可以实现流量管理的完全自动化。Envoy 的热重启能力和动态配置使其在服务网格场景中无可替代。
LVS vs HAProxy vs Nginx vs Envoy 选型
| 维度 | LVS | HAProxy | Nginx | Envoy |
|---|---|---|---|---|
| 工作层次 | L4 | L4/L7 | L7(Stream L4) | L4/L7 |
| 性能 | 极高(内核态) | 高 | 高 | 高(C++) |
| 动态配置 | 需配合 Keepalived | Runtime API | Reload / API | xDS(最优) |
| 健康检查 | Keepalived 实现 | 内置 | 被动检测 | 内置+主动 |
| 云原生集成 | 弱 | 一般 | Ingress Controller | 服务网格标配 |
| 学习成本 | 中 | 低 | 低 | 中高 |
| 适用规模 | 超大规模入口 | 中小规模 L7 | 通用 Web | 微服务架构 |
选型决策路径
场景一:超大规模四层入口 —— 选 LVS(DR 模式)。当并发连接数达到百万级、后端节点超过百台时,LVS 的内核态转发是唯一可靠选择。
场景二:中小规模 Web 服务 —— 选 Nginx 或 HAProxy。配置简单、社区成熟、运维成本低,适合大多数常规业务。
场景三:微服务架构 —— 选 Envoy。xDS 动态配置、服务网格集成、丰富的 L7 策略,是 Kubernetes 生态的事实标准。
场景四:L4 + L7 混合架构 —— LVS(L4 入口)+ Envoy(L7 代理)组合。兼顾内核态极致性能与七层灵活路由,适用于大规模微服务的生产环境。
避免误区:Nginx 虽然可以通过 Upstream 模块做四层负载均衡,但其内核态转发能力远不及 LVS。当四层流量成为瓶颈时,不要试图用 Nginx 替代 LVS。
Envoy 与 Nginx 七层代理对比
| 维度 | Envoy | Nginx |
|---|---|---|
| 配置方式 | 静态 YAML + xDS 动态 API | 静态配置 + reload |
| 热重启 | 支持(零停机) | reload(平滑替换 worker,已有连接不受影响,但配置不动态) |
| 服务网格 | Istio 标准数据面 | 需第三方适配 |
| L7 过滤器 | 丰富(限流/熔断/认证) | 基础(rewrite/proxy) |
| 可观测性 | 内置 Prometheus 指标 | 需第三方模块 |
| 学习曲线 | 中高 | 低 |
| 适用场景 | 微服务、服务网格 | 通用 Web、反向代理 |
LVS 三种模式配置命令对照
# NAT 模式(LVS 做网关)
ipvsadm -A -t 192.168.1.100:80 -s rr
ipvsadm -a -t 192.168.1.100:80 -r 10.0.0.1:80 -m
ipvsadm -a -t 192.168.1.100:80 -r 10.0.0.2:80 -m
# DR 模式(修改 MAC 地址)
ipvsadm -A -t 192.168.1.100:80 -s rr
ipvsadm -a -t 192.168.1.100:80 -r 10.0.0.1:80 -g # -g 表示 DR 模式
ipvsadm -a -t 192.168.1.100:80 -r 10.0.0.2:80 -g
# TUN 模式(IP 隧道封装)
ipvsadm -A -t 192.168.1.100:80 -s rr
ipvsadm -a -t 192.168.1.100:80 -r 10.0.0.1:80 -i # -i 表示 TUN 模式
ipvsadm -a -t 192.168.1.100:80 -r 10.0.0.2:80 -i
# 查看当前规则
ipvsadm -L -n --stats
Envoy 热重启机制
# Envoy 支持零停机热重启,配置变更无需中断连接
# 查看当前配置快照(config_dump 是只读 GET 端点;动态配置经 xDS 下发)
curl localhost:9901/config_dump
# 热重启流程:旧进程 → fork 新进程 → 新进程接管监听 socket → 旧进程处理完当前请求后退出
# 适用场景:路由规则变更、证书更新、限流参数调整
# 验证热重启是否成功
curl localhost:9901/server_info | jq '.state'
# 输出 "LIVE" 表示正常运行
LVS 与云负载均衡对比
| 维度 | LVS | AWS ALB/NLB | Azure Load Balancer |
|---|---|---|---|
| 部署位置 | 自建机房 | AWS 云内 | Azure 云内 |
| 性能 | 极高(内核态) | 高(托管) | 高(托管) |
| 运维成本 | 高(需自运维) | 低(全托管) | 低(全托管) |
| 弹性扩展 | 手动 | 自动 | 自动 |
| 混合云支持 | 原生支持 | 需 VPN 连接 | 需 VPN 连接 |
Keepalived 高可用检查清单
| 检查项 | 要求 | 验证方式 |
|---|---|---|
| VRRP 协议放行 | 防火墙放行 UDP 112 和组播 224.0.0.18 | tcpdump -i eth0 vrrp |
| virtual_router_id | 主备节点必须一致 | 检查 /etc/keepalived/keepalived.conf |
| priority 差值 | 建议 10-20(如 100 vs 90) | ip addr show 检查 VIP 绑定 |
| 健康检查间隔 | delay_loop 建议 3-5 秒 | 查看 /var/log/syslog 中 VRRP 日志 |
| 备节点优先级 | BACKUP 节点 priority 应低于 MASTER | ipvsadm -L -n 检查连接分发 |
| 脑裂防护 | 3 节点或使用仲裁设备 | 测试 MASTER 宕机后 VIP 切换 |
# 验证 VIP 漂移
# 在 MASTER 节点执行
ip addr show eth0 | grep 192.168.1.100
# 杀死 MASTER 的 keepalived 进程
killall keepalived
# 在 BACKUP 节点检查 VIP 是否接管
ip addr show eth0 | grep 192.168.1.100
故障排查案例:VIP 漂移后客户端无法访问
现象:Keepalived 执行了 VIP 漂移,BACKUP 节点接管 VIP 后,客户端请求超时。但 ipvsadm -L -n 显示连接已正常分发到后端。
排查:在后端 Real Server 上执行 tcpdump -i lo -n | grep VIP,发现收到的请求包目的 IP 是 VIP,但响应包源 IP 变成了 Real Server 的 RIP。客户端收到源 IP 不匹配的响应包后直接丢弃。
根因:新接管 VIP 的 BACKUP 节点的 Real Server 未更新 VIP 绑定——之前 MASTER 节点的 VIP 绑定在后端已生效,但 BACKUP 节点的 VIP MAC 地址变更后,ARP 表未刷新,导致后端仍向旧 MASTER 发送响应包。
修复:① 在 Real Server 的启动脚本中加入 ARP 通知:arping -U -c 3 -I eth0 $VIP,VIP 变更后主动广播新的 ARP 表项;② 确保 arp_ignore=1 和 arp_announce=2 已在所有 Real Server 上持久化。
# Real Server 启动脚本中添加 VIP 变更通知
#!/bin/bash
VIP="192.168.1.100"
INTERFACE="eth0"
# 绑定 VIP
ip addr add $VIP/32 dev lo
# 主动通知网关更新 ARP 表
arping -U -c 3 -I $INTERFACE $VIP &
# Keepalived 通知脚本(配合 notify_master 使用)
notify_master() {
arping -U -c 3 -I $INTERFACE $VIP
logger "VIP $VIP promoted on $(hostname)"
}
LVS 性能基准测试方法
# 使用 wrk 测试 LVS DR 模式下的吞吐量
# 测试脚本:100 并发连接,持续 60 秒
wrk -t4 -c100 -d60s http://192.168.1.100/index.html
# 使用 ipvsadm 监控实时连接分发
watch -n 1 'ipvsadm -L -n --stats | head -20'
# 使用 iperf3 测试 LVS 四层 TCP 吞吐
# 客户端
iperf3 -c 192.168.1.100 -P 4 -t 30
# 查看 LVS 连接表(调试连接超时问题)
cat /proc/net/ip_vs
常见错误
- VIP 无法漂移:检查防火墙是否放行 VRRP 协议(组播地址 224.0.0.18)、
virtual_router_id是否两端一致、auth_pass是否匹配。 - DR 模式下 Real Server 无法响应:确认
arp_ignore=1和arp_announce=2已生效,检查 VIP 是否正确绑定在 lo 接口并使用 /32 掩码。 - Envoy 配置不生效:确认 xDS 控制面地址可达、集群名称与配置中的
cluster_name一致;检查 Envoy 日志中是否有配置推送错误。 - Keepalived 健康检查频繁切换:后端 Real Server 健康检查路径返回非 200 状态码,或
connect_timeout设置过短导致误判;适当增加retry次数和delay_before_retry间隔。 - Nginx 替代 LVS 后性能骤降:四层高并发场景应使用 LVS(DR 模式),Nginx 工作在用户态,单核处理能力远低于 LVS 内核态转发。
最佳实践
- LVS 生产环境首选 DR 模式:性能最优、配置最成熟;仅在无法保证二层互通时才考虑 NAT 或 TUN。
- Keepalived 双节点部署:MASTER 和 BACKUP 节点分别部署在不同物理机或虚拟机上,避免单点故障;
priority差值建议设为 10-20。 - Envoy 配合控制面使用:通过 Istio 或自研控制面动态下发配置,避免手动维护静态配置文件;利用 xDS 的增量推送实现秒级生效。
- 统一监控与告警:将 LVS 的
ipvsadm -L -n --stats输出、Keepalived 状态日志、Envoy 的 Prometheus 指标统一接入监控平台,及时发现流量异常。 - 分层架构选型:大规模微服务推荐 LVS(L4 入口)+ Envoy(L7 代理)的组合,兼顾内核态性能与七层灵活路由。
练习题
- 在两台虚拟机上部署 LVS DR 模式 + Keepalived 高可用集群,配置 VIP 漂移并验证故障切换;使用
ipvsadm -L -n观察连接分发情况。 - 编写 Envoy 配置文件,实现基于请求路径的灰度路由(/api/v2 → canary 集群,其余 → stable 集群),并配合熔断策略检测后端健康状态。
- 对比 LVS NAT 模式与 DR 模式的吞吐量:在相同后端服务器配置下,分别搭建两种模式,使用
ab或wrk进行压力测试并记录性能差异。
学习检查点
学完本章后,请检验自己是否掌握以下内容:
| 检查项 | 自测问题 | 验证方法 |
|---|---|---|
| 概念理解 | 能用自己的话解释负载均衡的会话保持、灰度发布原理 | 尝试向他人讲解 |
| 命令操作 | 能不查文档完成 LVS/Keepalived 高可用集群配置 | 在终端实际执行 |
| 原理掌握 | 能说出七层负载均衡与四层负载均衡的区别和适用场景 | 画出流程图 |
| 故障排查 | 能独立排查负载均衡后端健康检查失败的问题 | 模拟故障并修复 |
| 最佳实践 | 能说明为什么需要配置负载均衡的优雅关闭和连接排水 | 对比不同方案 |
本章总结
负载均衡选型是分层问题:内核态的 LVS 承担百万级四层入口,Nginx/HAProxy 服务中小规模 Web,Envoy 凭借 xDS 动态配置成为微服务体系的事实标准。生产架构推荐 L4 + L7 组合——LVS 入口 + Envoy 代理,兼顾极致性能与灵活路由。无论哪一层,健康检查与统一监控都是高可用落地的前提。