LVS(Linux Virtual Server)是一个工作在Linux内核态的四层负载均衡解决方案,具有高性能、高稳定性和高可用性的特点。它由章文嵩博士于1998年发起,现已成为Linux内核的标准组件,广泛应用于电商大促、游戏服务器集群等需要处理百万级并发连接的场景
LVS的三种工作模式
LVS的核心是通过不同技术将客户端请求分发至后端服务器,主要有以下三种工作模式:
-
NAT模式(网络地址转换)
原理 :调度器(Director)作为整个集群的网关,接收客户端请求后,修改目标IP地址为选定的真实服务器(RealServer),后者处理完请求后将响应数据发回给调度器,由调度器修改源IP后再返回给客户端。特点:请求和响应报文都必须经过调度器,因此调度器容易成为性能瓶颈,适用于节点数较少(10-20台)的小型集群。其优点在于配置简单,且后端服务器可以运行任意操作系统,支持端口映射。
-
DR模式(直接路由)
原理 :调度器和后端服务器共享同一个虚拟IP(VIP),且必须在同一物理网络。调度器收到请求后,不修改IP报文,只将数据帧的目标MAC地址改写为选定服务器的MAC地址并广播。后端服务器直接处理请求,并将响应通过其网卡直接返回给客户端 ,不再经过调度器。特点:这是性能最好的模式,消除了调度器的转发开销,理论吞吐量极高,非常适合大规模高并发场景。但它要求调度器和后端服务器在同一个二层网络,且不支持端口映射。后端服务器需要进行额外的ARP抑制配置,以避免IP冲突。
-
TUN模式(IP隧道)
原理:调度器收到请求后,通过IP隧道技术(如IPIP封装)将原始数据包封装在一个新的IP包中,发送给处于不同网络的后端服务器。服务器解封装后处理请求,并将响应直接返回给客户端。
-
特点 :最大的优势是支持**跨地域(跨子网)**部署集群,突破了DR模式的物理网络限制。但配置相对复杂,要求后端服务器支持IP隧道协议。由于存在封装和解封装的开销,性能略低于DR模式。
lvs集群体系结构

实验
nat模式
RS1
[root@RS1 ~]# vmset.sh eth0 192.168.153.10 RS1 noroute
[root@RS1 ~]# nmcli connection modify eth0 ipv4.gateway 192.168.153.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.153.100 0.0.0.0 UG 100 0 0 eth0
192.168.153.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
[root@RS1 ~]# dnf install httpd -y
[root@RS1 ~]# systemctl enable --now httpd
[root@RS1 ~]# echo RS1 - 192.168.153.10 > /var/www/html/index.html
RS2同RS1一样
在vs主机中测试环境
[root@vsnode ~]# curl 192.168.153.10 RS1 - 192.168.153.10 [root@vsnode ~]# curl 192.168.153.20 RS2 - 192.168.153.20
NAT模式实现方法
1.vs
#1,开启内核路由功能
[root@vsnode ~]# echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf
[root@vsnode ~]# sysctl -p
net.ipv4.ip_forward = 1
#2.编写策略
[root@vsnode ~]# ipvsadm -C
[root@vsnode ~]# ipvsadm -A -t 192.168.40.100:80 -s wrr
[root@vsnode ~]# ipvsadm -a -t 192.168.40.100:80 -r 192.168.153.10:80 -m -w 1
[root@vsnode ~]# ipvsadm -a -t 192.168.40.100:80 -r 192.168.153.20:80 -m -w 1
[root@vsnode ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.25.254.100:80 wrr
-> 192.168.153.10:80 Masq 1 0 0
-> 192.168.153.20:80 Masq 1 0 0
#测试
[root@vsnode ~]# for i in {1..10};do curl 192.168.40.100;done
RS2 - 192.168.153.20
RS1 - 192.168.153.10
RS2 - 192.168.153.20
RS1 - 192.168.153.10
RS2 - 192.168.153.20
RS1 - 192.168.153.10
RS2 - 192.168.153.20
RS1 - 192.168.153.10
RS2 - 192.168.153.20
RS1 - 192.168.153.10
#更改权重 [root@vsnode ~]# ipvsadm -e -t 192.168.40:80 -r 192.168.153.10:80 -m -w 2 [root@vsnode ~]# ipvsadm -Ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.25.254.100:80 wrr -> 192.168.153.10:80 Masq 2 0 5 -> 192.168.153.20:80 Masq 1 0 5 #测试 [root@vsnode ~]# for i in {1..10};do curl 192.168.40.100;done RS2 - 192.168.153.20 RS1 - 192.168.153.10 RS1 - 192.168.153.10 RS2 - 192.168.153.20 RS1 - 192.168.153.10 RS1 - 192.168.153.10 RS2 - 192.168.153.20 RS1 - 192.168.153.10 RS1 - 192.168.153.10 RS2 - 192.168.153.20


规则持久化
实验过程可以用过打开另外一个shell的并执行监控命令的方式进行观察
[root@vsnode ~]# watch -n 1 ipvsadm -Ln #利用自定义文件进行持久化 [root@vsnode ~]# ipvsadm-save -n -A -t 192.168.40:80 -s wrr -a -t 192.168.40:80 -r 192.168.153.10:80 -m -w 2 -a -t 192.168.40:80 -r 192.168.153.20:80 -m -w 1 [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 Created symlink /etc/systemd/system/multi-user.target.wants/ipvsadm.service → /usr/lib/systemd/system/ipvsadm.service.

DR模式实验过程
环境设定方式
#在路由器中
[root@router ~]# systemctl disable --now ipvsadm.service
Removed "/etc/systemd/system/multi-user.target.wants/ipvsadm.service".
[root@router ~]# ipvsadm -C
#在路由器中
[root@router ~]# vmset.sh eth0 192.168.40.100 vsnode
[root@router ~]# vmset.sh eth1 192.168.153.100 vsnode noroute、
#设定内核路由功能
[root@router ~]# echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf
[root@router ~]# sysctl -p
net.ipv4.ip_forward = 1
#数据转发策略
[root@router ~]# iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 192.168.153.100
[root@vsnode ~]# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 192.168.40.100
#vsnode 调度器0
[root@vsnode ~]# vmset.sh eth0 192.168.153.50 vsnode norouter
[root@vsnode ~]# vim /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0
[ipv4]
method=manual
address1==192.168.153.50/24,192.168.153.100
[root@vsnode ~]# cd /etc/NetworkManager/system-connections/
[root@vsnode system-connections]# cp -p eth0.nmconnection lo.nmconnection
[root@vsnode system-connections]# vim lo.nmconnection
[connection]
id=lo
type=loopback
interface-name=lo
[ipv4]
method=manual
address1==127.0.0.1/8
address2=192.168.153.200/32
[root@RS1 system-connections]# nmcli connection reload
[root@RS1 system-connections]# nmcli connection up eth0
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/7)
[root@RS1 system-connections]# nmcli connection up lo
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/8)
#检测
root@vsnode system-connections]# 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.153.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
192.168.153.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
[root@vsnode system-connections]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet 192.168.153.200/32 brd 192.168.0.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:41:e5:8b brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname ens160
inet 192.168.153.50/24 brd 192.168.0.255 scope global secondary noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::e40:8975:6b9:fea8/64 scope link noprefixroute
valid_lft forever preferred_lft forever
#客户端
[root@client ~]# vmset.sh eth0 192.168.40.99 client norouter
[root@client ~]# nmcli connection reload
[root@client ~]# nmcli connection up eth0
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/5)
[root@client ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.40.100 0.0.0.0 UG 100 0 0 eth0
192.168.40.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
#检测
[root@client ~]# ping 192.168.153.200
PING 192.168.153.200 (192.168.153.200) 56(84) 比特的数据。
64 比特,来自 192.168.153.200: icmp_seq=1 ttl=128 时间=1.08 毫秒
#RS1 [root@RS1 ~]# vmset.sh eth0 192.168.153.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 #在lo上设定vip [root@RS1 ~]# cd /etc/NetworkManager/system-connections/ [root@RS1 system-connections]# cp -p eth0.nmconnection lo.nmconnection [root@RS1 system-connections]# nmcli connection reload [root@RS1 system-connections]# nmcli connection up lo 连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/6) #arp禁止响应 [root@rs1 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore [root@rs1 ~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore [root@rs1 ~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce [root@rs1 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce


为什么必须禁止ARP响应?
在DR模式下,调度器(Director)和后端服务器(RealServer)都配置了相同的虚拟IP(VIP)。但只有调度器需要作为网关响应来自外部的ARP请求,后端服务器则必须保持"沉默"。
-
正常路径 :客户端或路由器广播"谁是VIP?"的ARP请求。只有调度器应该应答,将自己的MAC地址告诉请求方,这样流量才会流经调度器进行分发。
-
异常路径 :如果后端服务器应答了这个ARP请求,网络中的交换机可能会学到错误的MAC地址表。部分流量会被直接转发给后端服务器,导致这些请求绕过了调度器。由于后端服务器不具备调度器的分发逻辑,这些请求会因无法找到目标而失败。
根本原因:TCP/IP协议栈默认会响应任何发往本机IP地址(包括VIP)的ARP请求。
