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 必须在同一局域网,性能三种模式中最高。
环境规划表
数据流向: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 # 应输出 enabledRS1/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.serviceARP 抑制 + 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 模式对比
LVS管理命令速查
常见问题排查
关键注意事项
所有机器单网卡即可(DR 不需要双网卡)
LVS 的 VIP 必须绑实体网卡(ens33,对外可见),否则 Client 找不到 VIP
RS 的 VIP 必须绑 lo(对外不可见),这是 DR 最容易漏的
RS 必须做 ARP 抑制(arp_ignore=1 / arp_announce=2),否则 RS 抢 VIP,负载均衡失效
RS 必须关闭 rp_filter,否则回包被丢
调度参数用
-g(直接路由),不是-i(TUN)、不是-m(NAT)不需要 MASQUERADE(LVS 上),回包直接 RS→Client
不需要 ipip 模块(那是 TUN 用的),只需 ip_vs
DR 要求 LVS 与 RS 必须在同一局域网
持久化: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所有实验机内网网关指向路由器 192.168.2.10
路由器外网口:接 VMware NAT,静态 IP 用
.2以外(如 192.168.1.10),网关必须是网段的.2(192.168.1.2)判断外网连通性用
curl,不要用 ping(NAT 网络禁 ICMP)路由器必须配 MASQUERADE(
192.168.2.0/24 → ens37),否则内网机器出不去
配置完成后,通过 Client 访问 http://192.168.2.100,多次刷新应看到 rs1 和 rs2 交替出现,说明 LVS DR 集群部署成功!
LVS的DR模式
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
评论交流
欢迎留下你的想法