
如何在一台 VS(虚拟服务/负载均衡)主机上用 IPVS 的 NAT(Masquerade)方式做 172.25.254.100:80 的负载均衡,并将流量转发到两台后端 RS(真实服务器,192.168.0.10/192.168.0.20)上。包含网络配置、服务部署、IPVS 配置、持久化和常见问题排查。
目录
-
准备与假设
-
拓扑说明
-
在 VS 主机上(vsnode)配置
-
在后端服务器 RS1/RS2 上配置
-
测试验证
-
NAT 模式实现(ipvsadm)
-
权重与调度策略说明
-
规则持久化
-
常见问题与排查命令
-
命令速查表
准备与假设
-
主机:
-
vsnode(负载均衡器,外网/管理网接口 eth0:172.25.254.100,内网接口 eth1:192.168.0.100)

- RS1(后端,eth0:192.168.0.10)

- RS2(后端,eth0:192.168.0.20)

-
操作系统:CentOS/RHEL 类型(使用 nmcli、dnf、systemctl)
-
已安装 ipvsadm(IP Virtual Server 工具)
-
有 root 权限
-
HTTP 服务用于测试(httpd 或其它)
拓扑说明
-
客户端访问 VS 的 VIP:172.25.254.100:80
-
VS 将请求通过 NAT(Masquerade)转发到后端 RS(192.168.0.10:80、192.168.0.20:80)
-
后端回复包通过 VS 做地址转换返回客户端(MASQ),后端默认网关指向 VS 的内网地址 192.168.0.100

在 VS 主机中(示例:vsnode)
设置接口(示例命令,假设存在 vmset.sh 脚本):
```bash
root@vsnode \~# vmset.sh eth0 172.25.254.100 vsnode
root@vsnode \~# vmset.sh eth1 192.168.0.100 vsnode noroute
```
开启内核转发:
```bash
root@vsnode \~# echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf

root@vsnode \~# sysctl -p
应看到:
net.ipv4.ip_forward = 1

```
确保 ip_vs 模块加载:
root@vsnode \~# modprobe ip_vs
root@vsnode \~# modprobe ip_vs_wrr
root@vsnode \~# modprobe ip_vs_sh
root@vsnode \~# modprobe iptable_nat
root@vsnode \~# modprobe nf_conntrack
安装 ipvsadm(若未安装):
root@vsnode \~# dnf install -y ipvsadm
在后端 RS1(192.168.0.10)上
设置网络(示例):
root@RS1 \~# vmset.sh eth0 192.168.0.10 RS1 noroute
root@RS1 \~# nmcli connection modify eth0 ipv4.gateway 192.168.0.100
root@RS1 \~# nmcli connection reload
root@RS1 \~# nmcli connection up eth0
```
查看路由(示例):
root@RS1 \~# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.0.100 0.0.0.0 UG 100 0 0 eth0
192.168.0.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
```
安装并启动 httpd,写入测试页面:
root@RS1 \~# dnf install -y httpd
root@RS1 \~# systemctl enable --now httpd
root@RS1 \~# echo "RS1 - 192.168.0.10" > /var/www/html/index.html
```
开放防火墙 HTTP(如果使用 firewalld):
root@RS1 \~# firewall-cmd --permanent --add-service=http
root@RS1 \~# firewall-cmd --reload
若启用 SELinux,需要允许 httpd 做网络连接:
root@RS1 \~# setsebool -P httpd_can_network_connect 1
```
在后端 RS2(192.168.0.20)上
(注意:原文 RS2 部分引用了 RS1,已修正为 RS2)
设置网络:
root@RS2 \~# vmset.sh eth0 192.168.0.20 RS2 noroute
root@RS2 \~# nmcli connection modify eth0 ipv4.gateway 192.168.0.100
root@RS2 \~# nmcli connection reload
root@RS2 \~# nmcli connection up eth0
```
查看路由(示例):
root@RS2 \~# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.0.100 0.0.0.0 UG 100 0 0 eth0
192.168.0.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
```
安装并启动 httpd,写入测试页面:
root@RS2 \~# dnf install -y httpd
root@RS2 \~# systemctl enable --now httpd
root@RS2 \~# echo "RS2 - 192.168.0.20" > /var/www/html/index.html
```
开放防火墙并设置 SELinux 同 RS1(如需)。
在 VS 主机中测试后端连通性(在配置 RS 后)
直接访问后端 IP(从 vsnode):
root@vsnode \~# curl 192.168.0.10
输出应为:
RS1 - 192.168.0.10
root@vsnode \~# curl 192.168.0.20
输出应为:
RS2 - 192.168.0.20

如果 curl 无响应,排查防火墙、httpd 状态或路由设置。
NAT 模式实现(在 vsnode 上用 ipvsadm)
- 清除旧策略并添加 VIP 服务:
root@vsnode \~# ipvsadm -C
root@vsnode \~# ipvsadm -A -t 172.25.254.100:80 -s wrr
```
说明:
-
`-A`:添加一个虚拟服务(address:port)
-
`-t`:TCP (对于 HTTP)
-
`-s wrr`:使用加权轮询(Weighted Round Robin)
- 添加后端真实服务器(使用 Masquerade,即 NAT 模式):
root@vsnode \~# ipvsadm -a -t 172.25.254.100:80 -r 192.168.0.10:80 -m -w 1
root@vsnode \~# ipvsadm -a -t 172.25.254.100:80 -r 192.168.0.20:80 -m -w 1
```
说明:
-
`-a`:为已存在的虚拟服务添加真实服务器
-
`-r`:真实服务器地址
-
`-m`:Masq(NAT)转发方式(后端看到源地址为 VS)
-
`-w`:权重
- 查看配置:
root@vsnode \~# ipvsadm -Ln
会列出 VIP 与后端信息
```
- 测试 VIP:
root@vsnode \~# for i in {1..10}; do curl -s 172.25.254.100; echo; done
你应看到 RS1 与 RS2 的响应轮流出现,或按照权重分配
更改权重(示例)
将 RS1 权重改为 2:
```bash
root@vsnode \~# ipvsadm -e -t 172.25.254.100:80 -r 192.168.0.10:80 -m -w 2
root@vsnode \~# ipvsadm -Ln
```
效果:在 wrr 策略下,RS1 将被选中频率更高(约 double)。
调度算法简介
常用调度:
-
rr:Round Robin
-
wrr:Weighted Round Robin(按权重)
-
wlc:Weighted Least Connection
-
lc:Least Connection
选择依据后端能力与连接特性。
规则持久化
方法一:使用自定义文件(任意位置)
root@vsnode \~# ipvsadm-save -n > /mnt/ipvs.rule
清空并还原举例
root@vsnode \~# ipvsadm -C
root@vsnode \~# ipvsadm-restore < /mnt/ipvs.rule
```
方法二:使用系统配置并启用服务(推荐)
root@vsnode \~# ipvsadm-save -n > /etc/sysconfig/ipvsadm
root@vsnode \~# ipvsadm -C
root@vsnode \~# systemctl enable --now ipvsadm.service
创建并启动后,系统启动时会自动恢复 ipvs 规则
```
建议在系统网络启动之后再 restore(例如在 network-online.target 后启动)。
监控(实时查看)
在另一个 shell 中持续查看:
root@vsnode \~# watch -n 1 ipvsadm -Ln
抓包查看流量是否经过 VS:
root@vsnode \~# tcpdump -n -i eth1 host 192.168.0.10 or host 192.168.0.20 and port 80
```
常见问题与排查
-
无法访问 VIP:
-
确认 iptables/nftables 是否阻断(查看 nat 表)
-
确认 ip_vs 模块已加载(lsmod | grep ip_vs)
-
确认 sysctl net.ipv4.ip_forward=1 已生效
-
确认 ipvsadm 规则存在(ipvsadm -Ln)
-
后端响应但返回给客户端异常:
-
确认后端默认网关指向 VS(否则回复可能直接走别的网关)
-
如果使用 DR(Direct Routing)而不是 MASQ,还需在后端处理 VIP 回环(不需要在本场景)
-
防火墙/SELinux:
-
后端需要允许 80 端口(firewalld 或 iptables)
-
SELinux:httpd_can_network_connect
-
模块或依赖缺失:
-
modprobe ip_vs_*、iptable_nat、nf_conntrack
-
ipvsadm 规则未持久化:
-
检查 /etc/sysconfig/ipvsadm 或 systemd 服务状态
排查命令汇总:
查看 ipvs 规则
ipvsadm -Ln
查看内核模块
lsmod | egrep "ip_vs|iptable_nat|nf_conntrack"
查看 nat 表(iptables)
iptables -t nat -L -n -v
查看路由
ip route show
route -n
查看防火墙规则(firewalld)
firewall-cmd --list-all
检查服务端口监听
ss -tulnp | grep :80
抓包(在 vsnode)
tcpdump -n -i eth1 port 80
```
命令速查表(常用)
-
添加 VIP: ipvsadm -A -t VIP:PORT -s wrr
-
添加 RS: ipvsadm -a -t VIP:PORT -r RS_IP:PORT -m -w N
-
删除 VIP: ipvsadm -D -t VIP:PORT
-
删除 RS: ipvsadm -d -t VIP:PORT -r RS_IP:PORT
-
列表: ipvsadm -Ln
-
保存规则: ipvsadm-save -n > /path/file
-
还原规则: ipvsadm-restore < /path/file
结束语
- 本文档已将示例命令按主机角色分离并补充了防火墙、SELinux、模块与排查建议。按顺序执行网络配置 → 后端部署 → VS 上 IPVS 配置 → 测试验证 → 持久化 保存规则。若有特殊网络环境(VLAN、多个网段、云平台安全组),请相应调整防火墙与路由配置。