LVS的DR模式(Ubuntu24.04)

整体架构

DR 模式:LVS 只承担入站请求,通过改写数据帧的 MAC 地址把请求直接发给 RS,RS 处理完直接把响应返回客户端(不经过 LVS)。要求调度器与 RS 在同一个局域网内,性能是三种模式中最好的,生产环境首选。

                         ┌─────────────────────────────┐
                         │      路由器 router          │
                         │  ens37 外网 192.168.1.10    │
                         │  ens33 内网 192.168.2.10    │
                         └─────────────┬───────────────┘
                 上网(网关)             │
    ┌───────────────┬──────────────────┼───────────────────┐
    │               │                  │                   │
 ┌──┴───┐      ┌────┴───┐         ┌────┴────┐         ┌────┴────┐
 │Client│      │  LVS   │         │  RS1    │         │  RS2    │
 │.2.50 │      │ .2.200 │         │ .2.210  │         │ .2.220  │
 └──────┘      └───┬────┘         └─────────┘         └─────────┘
    │           VIP .2.100         lo:VIP 不响应ARP      lo:VIP 不响应ARP
    └───访问VIP──→ LVS改MAC转发 ──→ RS1/RS2 ──直接回包──→ Client

架构与 IP 规划

DR 模式特点:LVS 只负责调度入站请求(把数据帧的目的 MAC 改成选中的 RS 的 MAC),不修改数据报文;RS 直接给客户端回包(源地址=VIP)。要求 LVS 与 RS 必须在同一局域网,性能三种模式中最高。

环境规划表

机器

主机名

网卡

IP地址

网关

特殊配置

路由器

router

ens33(内网)

192.168.2.10

无(网关角色)

提供上网

ens37(外网)

192.168.1.10

192.168.1.2(VMware NAT网关)

接VMware NAT网络

LVS分发器

lvs

ens33

192.168.2.200

192.168.2.10

VIP 绑 ens33(对外可见)

RS1

rs1

ens33

192.168.2.210

192.168.2.10

lo 绑 VIP(不可见)+ ARP抑制

RS2

rs2

ens33

192.168.2.220

192.168.2.10

lo 绑 VIP(不可见)+ ARP抑制

Client

client

ens33

192.168.2.50

192.168.2.10

测试机

VIP

—

—

192.168.2.100:80

—

虚拟服务地址

数据流向:Client → VIP(192.168.2.100:80)→ LVS 改 MAC → RS1/RS2 → RS 直接回包(源地址=VIP,不经过 LVS)。

⭐ VMware NAT 网段地址规律(重要,防踩坑)

 某个 VMware NAT 网段(比如 192.168.1.0/24)
 ├── 192.168.1.1   = 宿主机(Windows)的虚拟网卡    ← 不能用作自己IP
 ├── 192.168.1.2   = VMware NAT 网关(负责上网)    ← 网关就是它,不能占用
 └── 192.168.1.128~254 = DHCP 分配池(虚拟机自动获取)
  • 每个 VMware NAT 网段,网关都是该网段的 .2(.1 是宿主机,.2 是 NAT 网关)

  • 自己机器的 IP 必须避开 .1 和 .2(否则抢地址/冲突,上不了网)

  • 你的网段是 192.168.1.0/24 → 网关 = 192.168.1.2,自己用 192.168.1.10

前期准备(所有机器)

 # 更新软件源
 sudo apt update && sudo apt upgrade -y
 ​
 # 关闭防火墙(Ubuntu默认用ufw)
 sudo ufw disable
 sudo systemctl stop ufw
 sudo systemctl disable ufw

注:Ubuntu 22.04+ 的 netplan 禁止使用 gateway4,必须用 routes 字段配网关。

路由器配置

作用:ens33 内网口 192.168.2.10 做内网网关,ens37 外网口接 VMware NAT 网络提供上网。

 # 编辑配置文件
 vim /etc/netplan/50-cloud-init.yaml
 ​
 # 替换一下内容
 network:
   ethernets:
     ens33:                      # 内网口(接实验网络)
       addresses:
         - 192.168.2.10/24
     ens37:                      # 外网口(接VMware NAT网络)
       addresses:
         - 192.168.1.10/24       # 静态:避开 .1(宿主机)和 .2(NAT网关)
       routes:
         - to: default
           via: 192.168.1.2      # 网关 = VMware NAT 网关(网段.2),不是 .1!
       nameservers:
         addresses:
           - 114.114.114.114
           - 8.8.8.8
   version: 2
 ​
 # 刷新配置文件
 sudo netplan apply
 ​
 # 开启转发 + NAT(让内网机器上网)
 echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
 sudo sysctl -p
 sudo iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o ens37 -j MASQUERADE
 ​
 # NAT规则持久化
 sudo apt install -y iptables-persistent
 sudo netfilter-persistent save
 ​
 # 验证路由器自己能否上网(注意:ping可能被禁,用curl判断)
 curl -s -o /dev/null -w "HTTP %{http_code}\n" --connect-timeout 5 https://www.baidu.com

⚠️ 测试外网别用 ping:这个 NAT 网络禁 ICMP(ping 不通),但 HTTP/HTTPS 正常。判断能不能上网请用 curl,不要用 ping。

LVS分发器配置(核心)

作用:192.168.2.200,绑定 VIP 192.168.2.100:80(对外可见),用 -g 直接路由转发。

网卡配置

 # 编辑配置文件
 vim /etc/netplan/50-cloud-init.yaml
 ​
 # 替换一下内容
 network:
   ethernets:
     ens33:
       addresses:
         - 192.168.2.200/24
       routes:
         - to: default
           via: 192.168.2.10      # 网关指向路由器
       nameservers:
         addresses:
           - 114.114.114.114
           - 8.8.8.8
   version: 2
 ​
 # 刷新配置文件
 sudo netplan apply
 ​
 # 安装ipvsadm + 开启IP转发
 sudo apt install ipvsadm -y
 echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
 sudo sysctl -p

加载内核模块(DR 不需要 ipip!)

 sudo modprobe ip_vs
 sudo modprobe ip_vs_rr
 ​
 echo "ip_vs"   | sudo tee -a /etc/modules
 echo "ip_vs_rr"| sudo tee -a /etc/modules

添加LVS调度规则(DR模式用 -g)

 sudo ipvsadm -C
 sudo ipvsadm -A -t 192.168.2.100:80 -s rr
 sudo ipvsadm -a -t 192.168.2.100:80 -r 192.168.2.210:80 -g
 sudo ipvsadm -a -t 192.168.2.100:80 -r 192.168.2.220:80 -g
 sudo ipvsadm -Ln

⚠️ 和 TUN 的区别:这里用 -g(直接路由),不是 -i(隧道)、不是 -m(NAT);不需要 MASQUERADE(回包直接走 RS→Client)。

绑定 VIP 到 LVS(★关键,漏了客户端找不到 VIP)

 # DR 模式:VIP 必须绑在实体网卡上(对外可见,要应答 ARP)
 sudo ip addr add 192.168.2.100/32 dev ens33
 ip addr show ens33 | grep inet    # 应看到 192.168.2.200/24 和 192.168.2.100/32

保存LVS规则 + 开机自启(systemd 方式)

 # ① 保存规则(必须加 -n!否则存成主机名,恢复时 VIP 变 127.0.1.1 → Connection refused)
 sudo ipvsadm-save -n > /etc/ipvsadm.rules
 ​
 # ② 创建开机自启服务(开机:绑 VIP + 恢复规则)
 sudo tee /etc/systemd/system/lvs-boot.service <<'EOF'
 [Unit]
 Description=LVS 开机配置(绑定VIP + 恢复规则)
 After=network.target
 ​
 [Service]
 Type=oneshot
 ExecStart=/bin/bash -c 'ip addr replace 192.168.2.100/32 dev ens33; ipvsadm-restore < /etc/ipvsadm.rules 2>/dev/null'
 RemainAfterExit=yes
 ​
 [Install]
 WantedBy=multi-user.target
 EOF
 ​
 # 更新、开机自启、启动
 sudo systemctl daemon-reload
 sudo systemctl enable lvs-boot.service
 sudo systemctl start lvs-boot.service
 ​
 # ③ 验证
 systemctl is-enabled lvs-boot.service    # 应输出 enabled

RS1/RS2 配置(★DR 最容易出错的部分)

作用:192.168.2.210(RS1)/192.168.2.220(RS2),lo 绑 VIP(Non-ARP,对外不可见),直接回包。

网卡配置(RS1示例,RS2改IP)

 # 编辑配置文件
 vim /etc/netplan/50-cloud-init.yaml
 ​
 # 替换一下内容
 network:
   ethernets:
     ens33:
       addresses:
         - 192.168.2.210/24      # RS2 改 192.168.2.220/24
       routes:
         - to: default
           via: 192.168.2.10
       nameservers:
         addresses:
           - 114.114.114.114
           - 8.8.8.8
   version: 2
 ​
 # 刷新配置文件
 sudo netplan apply

绑定 VIP 到 lo(Non-ARP,对外不可见)+ 开机自启

 # 等价于 CentOS 的 ifconfig lo:0 192.168.2.100 up
 sudo ip addr add 192.168.2.100/32 dev lo
 ip addr show lo | grep inet    # 确认出现 192.168.2.100/32
 ​
 # 开机自启(systemd 方式)
 sudo tee /etc/systemd/system/lvs-rs-boot.service <<'EOF'
 [Unit]
 Description=RS 开机配置(绑定VIP)
 After=network.target
 ​
 [Service]
 Type=oneshot
 ExecStart=/bin/bash -c 'ip addr replace 192.168.2.100/32 dev lo'
 RemainAfterExit=yes
 ​
 [Install]
 WantedBy=multi-user.target
 EOF
 ​
 # 更新、开机自启、启动
 sudo systemctl daemon-reload
 sudo systemctl enable lvs-rs-boot.service
 sudo systemctl start lvs-rs-boot.service

ARP 抑制 + rp_filter(★关键,防止VIP冲突)

 # RS 不响应 VIP 的 ARP(否则请求被 RS 截走,负载均衡失效)
 echo 1 | sudo tee /proc/sys/net/ipv4/conf/all/arp_ignore
 echo 2 | sudo tee /proc/sys/net/ipv4/conf/all/arp_announce
 ​
 # 关闭反向路径过滤(否则回包/收包可能被丢)
 echo 0 | sudo tee /proc/sys/net/ipv4/conf/all/rp_filter
 echo 0 | sudo tee /proc/sys/net/ipv4/conf/ens33/rp_filter
 echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
 ​
 # 持久化
 sudo tee /etc/sysctl.d/99-lvs-dr.conf <<'EOF'
 net.ipv4.ip_forward = 1
 net.ipv4.conf.all.arp_ignore = 1
 net.ipv4.conf.all.arp_announce = 2
 net.ipv4.conf.all.rp_filter = 0
 net.ipv4.conf.ens33.rp_filter = 0
 EOF
 ​
 # 立即加载并应用
 sudo sysctl -p /etc/sysctl.d/99-lvs-dr.conf

为什么必须 ARP 抑制(填坑):LVS 和两台 RS 都配了同一个 VIP。路由器/客户端问"谁是 192.168.2.100"时,必须只有 LVS 应答(VIP 对外可见),RS 不能应答,否则请求可能被 RS 截走,轮询失效。

  • arp_ignore=1:只响应"目的 IP 是接收网卡本地地址"的 ARP 请求 → RS 的 VIP 在 lo 上,ens33 收到对 VIP 的 ARP 不响应

  • arp_announce=2:发 ARP 时用最合适的实体网卡地址,不用 VIP 声明自己

安装Web服务

 sudo apt install nginx -y
 echo "rs1" | sudo tee /var/www/html/index.html    # RS2 写 rs2
 sudo systemctl start nginx
 sudo systemctl enable nginx

⚠️ nginx 必须监听在所有网卡(默认即可,不要只绑 127.0.0.1),因为请求发到 VIP(192.168.2.100)。

Client测试客户端配置

作用:192.168.2.50,访问 VIP 测试负载均衡。

 # 编辑配置文件
 vim /etc/netplan/50-cloud-init.yaml
 ​
 # 替换一下内容
 network:
   ethernets:
     ens33:
       addresses:
         - 192.168.2.50/24
       routes:
         - to: default
           via: 192.168.2.10
       nameservers:
         addresses:
           - 114.114.114.114
           - 8.8.8.8
   version: 2
 ​
 # 刷新配置文件
 sudo netplan apply
 ​
 # 安装 curl 工具
 sudo apt install curl -y

验证与测试

网络连通性测试

 # ① 连通性(同网段内ping可用)
 ping -c 2 192.168.2.100    # Client → VIP(应通;不通=查LVS有没有绑VIP)
 ping -c 2 192.168.2.200    # Client → LVS(应通)
 ping -c 2 192.168.2.10     # Client → 路由器内网口(应通)
 ​
 # ② 直接访问 RS(不走 LVS,验证 RS 本身)
 curl http://192.168.2.210  # 应显示 rs1
 curl http://192.168.2.220  # 应显示 rs2
 ​
 # ③ 通过 VIP 轮询测试(应 rs1/rs2 交替出现)
 for i in {1..10}; do curl -s http://192.168.2.100; echo; done
 ​
 # ④ 在 LVS 上看统计
 sudo ipvsadm -Ln --stats   # OutBytes=0 是正常的!响应不走 LVS
 sudo ipvsadm -Lnc

注:验证"能不能上网/下载"用 curl,不要用 ping(NAT 网络禁 ICMP)。

LVS统计监控

DR vs TUN vs NAT 模式对比

项目

NAT 模式(-m)

TUN 模式(-i)

DR 模式(-g)

网卡要求

LVS 必须双网卡

全部单网卡即可

全部单网卡即可

RS 特殊接口

无

tunl0

lo(等价lo:0)

RS 需 ARP 抑制

否

是

是

内核模块

ip_vs

ip_vs + ipip

只需 ip_vs

同局域网要求

可跨网段

可跨网段

必须同局域网

回包路径

必须经 LVS

RS 直接回客户端

RS 直接回客户端

LVS 瓶颈

有

无

无(生产首选)

MASQUERADE

必须配

不需要

不需要

LVS管理命令速查

操作

命令

查看规则

ipvsadm -Ln

查看统计

ipvsadm -Ln --stats

查看连接

ipvsadm -Lnc

清空规则

ipvsadm -C

添加虚拟服务

ipvsadm -A -t VIP:端口 -s 算法

添加真实服务器(DR)

ipvsadm -a -t VIP:端口 -r RIP:端口 -g

删除真实服务器

ipvsadm -d -t VIP:端口 -r RIP:端口

保存规则

ipvsadm-save -n > /etc/ipvsadm.rules

恢复规则

ipvsadm-restore < /etc/ipvsadm.rules

常见问题排查

问题

检查方法

解决方案

Client ping 不通 VIP(报 Destination Host Unreachable)

LVS 上 ip addr show ens33

LVS 没绑 VIP:ip addr add 192.168.2.100/32 dev ens33

访问 VIP 报 Connection refused

LVS 上 ipvsadm -Ln

ipvsadm 规则 VIP 错(存成主机名变 127.0.1.1):重建规则 + ipvsadm-save -n > /etc/ipvsadm.rules

一直访问同一台 RS

浏览器缓存

curl --no-cache 或用 for 循环

轮询时 RS 抢请求/乱

RS 上 cat /proc/sys/net/ipv4/conf/all/arp_ignore

ARP 抑制没配:置 1,announce 置 2

RS 收到请求不回包

RS 上 cat /proc/sys/net/ipv4/conf/all/rp_filter

rp_filter 没关:置 0

网站 502

systemctl status nginx

nginx 没起或没监听全部网卡

路由器/内网机器上不了网

curl https://www.baidu.com

ens37 静态IP避开.1/.2、网关填网段.2、路由器配 MASQUERADE

ping 不通外网

—

正常! 该 NAT 网络禁 ICMP,用 curl 判断

重启后全失效

systemctl is-enabled lvs-boot.service

持久化用 systemd 服务(LVS: lvs-boot.service,RS: lvs-rs-boot.service);ARP 写 sysctl.d;MASQUERADE 存 iptables-persistent

关键注意事项

  1. 所有机器单网卡即可(DR 不需要双网卡)

  2. LVS 的 VIP 必须绑实体网卡(ens33,对外可见),否则 Client 找不到 VIP

  3. RS 的 VIP 必须绑 lo(对外不可见),这是 DR 最容易漏的

  4. RS 必须做 ARP 抑制(arp_ignore=1 / arp_announce=2),否则 RS 抢 VIP,负载均衡失效

  5. RS 必须关闭 rp_filter,否则回包被丢

  6. 调度参数用 -g(直接路由),不是 -i(TUN)、不是 -m(NAT)

  7. 不需要 MASQUERADE(LVS 上),回包直接 RS→Client

  8. 不需要 ipip 模块(那是 TUN 用的),只需 ip_vs

  9. DR 要求 LVS 与 RS 必须在同一局域网

  10. 持久化:VIP+ipvsadm 用 systemd 服务(LVS: lvs-boot.service,RS: lvs-rs-boot.service);ARP/rp_filter 写 /etc/sysctl.d/99-lvs-dr.conf;路由器 MASQUERADE 存 iptables-persistent

  11. 所有实验机内网网关指向路由器 192.168.2.10

  12. 路由器外网口:接 VMware NAT,静态 IP 用 .2 以外(如 192.168.1.10),网关必须是网段的 .2(192.168.1.2)

  13. 判断外网连通性用 curl,不要用 ping(NAT 网络禁 ICMP)

  14. 路由器必须配 MASQUERADE(192.168.2.0/24 → ens37),否则内网机器出不去


配置完成后,通过 Client 访问 http://192.168.2.100,多次刷新应看到 rs1 和 rs2 交替出现,说明 LVS DR 集群部署成功!