LVS 全称 Linux Virtual Server ,是 Linux 内核层实现的高性能、高可用的负载均衡集群技术 ,由章文嵩博士开发,目前是 Linux 内核的标准模块之一。它的核心作用是将前端的请求流量分发到后端多台真实服务器(Real Server)上,从而提升服务的并发处理能力和可用性。
一.实验环境
| 主机名 | 角色 |
|---|---|
| vsnode | 调度器(VS) |
| RS1 | 真实服务器(RS) |
| RS2 | 真实服务器(RS) |
| server | 测试机 |
二、集群 vs 分布式
- 集群(Cluster) :多台服务器运行相同服务 ,通过负载均衡提升并发能力或高可用性。
- 常见类型:
- LB(负载均衡):分摊请求压力;
- HA(高可用):避免单点故障,保障服务持续在线。
- 常见类型:
- 分布式(Distributed) :将一个业务拆分成多个子服务,部署在不同服务器上,各司其职,协同完成整体功能。
✅ 集群 = 同事干一样的活,人多力量大;
✅ 分布式 = 不同岗位协作,拼成完整业务。
三、LVS(Linux Virtual Server)原理
-
作用:四层(传输层)负载均衡器,内核级实现,高性能、高可用。
-
角色 :
- VS(Virtual Server):调度器,接收客户端请求并转发;
- RS(Real Server):真实服务器,处理实际业务。
-
关键 IP :
- VIP:对外虚拟 IP(客户端访问地址);
- DIP:调度器内网 IP;
- RIP:真实服务器 IP;
- CIP:客户端 IP。
-
主流工作模式 :
表格
模式 特点 适用场景 NAT 修改目标 IP,请求/响应都经 VS;支持端口映射 小规模集群,RS 可为任意系统 DR(默认) 改 MAC 地址转发,响应直接回客户端;不支持端口映射 高性能、同局域网环境 TUN IP 隧道封装,跨网络;RS 需支持隧道 跨机房/远距离部署
✅ LVS 核心思想:让多台后端服务器看起来像一台高性能服务器。
四.lvs部署命令介绍
4.1.lvs软件相关信息
-
程序包:ipvsadm
-
Unit File: ipvsadm.service
-
主程序:/usr/sbin/ipvsadm
-
规则保存工具:/usr/sbin/ipvsadm-save
-
规则重载工具:/usr/sbin/ipvsadm-restore
-
配置文件:/etc/sysconfig/ipvsadm-config
-
ipvs调度规则文件:/etc/sysconfig/ipvsadm
4.2.ipvsadm命令
核心功能:
-
集群服务管理:增、删、改
-
集群服务的RS管理:增、删、改
-
查看
4.2.1 lvs集群中的增删改
1.管理集群服务中的增删改
bash
ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]]
-A #添加
-E #修改
-t #tcp服务
-u #udp服务
-s #指定调度算法,默认为WLC
-p #设置持久连接超时,持久连接可以理解为在同一个时间段同一个来源的请求调度到同一Realserver
-f #firewall mask 火墙标记,是一个数字
bash
#增加
[root@DR-server ~]# ipvsadm -A -t 192.168.170.100:80 -s rr
[root@DR-server ~]# ipvsadm -A -f 66 -p 3000
#修改
[root@DR-server ~]# ipvsadm -E -t 192.168.170.100:80 -s wrr -p 3000
#删除
[root@DR-server ~]# ipvsadm -D -t 192.168.170.100:80
[root@DR-server ~]# ipvsadm -D -f 66
2.管理集群中RealServer的增删改
bash
ipvsadm -a|e -t|u|f service-address -r realserver-address [-g|i|m] [-w weight]
-a #添加realserver
-e #更改realserver
-t #tcp协议
-u #udp协议
-f #火墙 标签
-r #realserver地址
-g #直连路由模式
-i #ipip隧道模式
-m #nat模式
-w #设定权重
-Z #清空计数器
-C #清空lvs策略
-L #查看lvs策略
-n #不做解析
--rate :输出速率信息
bash
#添加
[root@DR-server ~]# ipvsadm -a -t 192.168.170.100:80 -r 192.168.131.30 -m
[root@DR-server ~]# ipvsadm -a -t 192.168.170.100:80 -r 192.168.131.40 -m -w 2
#更改
[root@DR-server ~]# ipvsadm -e -t 192.168.170.100:80 -r 192.168.131.30 -m -w 1
[root@DR-server ~]# ipvsadm -e -t 192.168.170.100:80 -r 192.168.131.30 -i -w 1
#删除
[root@DR-server ~]# ipvsadm -d -t 192.168.170.100:80 -r 192.168.131.30
五.LVS实战案例
5.1部署NAT模式集群案例
1.Director 服务器采用双网卡,一个是桥接网卡连接外网,一个是仅主机网卡与后端Web服务器相连,调度器vscode添加一个网络适配器作为网关

2.Web服务器采用仅主机网卡与director相连
3.Web服务器网关指向192.168.131.100
4.后端web服务器不需要连接外网
5.1.1.实验环境
| 主机名 | ip | vip | 角色 |
|---|---|---|---|
| vsnode | 192.168.131.100 | 192.168.170.100 | 调度器(VS) |
| RS1 | 192.168.131.10,GW 192.168.131.100 | null | 真实服务器(RS) |
| RS2 | 192.168.131.20,GW 192.168.131.100 | null | 真实服务器(RS) |
5.1.2.配置命令
1.分别给VS,RS1和RS2设定网络,vscode(192.168.170.100/192.168.131.100),RS1(192.168.131.10),RS2(192.168.131.20),同时给RS1和RS2设置网关并查看
bash
[root@RS1+RS2 ~]# nmcli connection modify eth0 ipv4.gateway 192.168.131.100
[root@RS1+RS2 ~]# nmcli connection reload
[root@RS1+RS2 ~]# nmcli connection up eth0
[root@RS1+RS2 ~]# route -n
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 192.168.131.100 0.0.0.0 UG 100 0 0 eth0
192.168.131.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
2.设定访问业务真实数据
bash
[root@RS1+RS2 ~]# dnf install httpd -y
[root@RS1+RS2 ~]# systemctl enable --now httpd
[root@RS1+RS2 ~]# echo RS1 - 192.168.131.10 > /var/www/html/index.html
3.开启内核路由功能
bash
[root@vsnode ~]# echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf
[root@vsnode ~]# sysctl -p
net.ipv4.ip_forward = 1
4.编写策略
bash
[root@vsnode ~]# dnf install ipvsadm.x86_64 -y
[root@vsnode ~]# ipvsadm -C
[root@vsnode ~]# ipvsadm -A -t 192.168.170.100:80 -s wrr
[root@vsnode ~]# ipvsadm -a -t 192.168.170.100:80 -r 192.168.131.10:80 -m -w 1
[root@vsnode ~]# ipvsadm -a -t 192.168.170.100:80 -r 192.168.131.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 192.168.170.100:80 wrr
-> 192.168.131.10:80 Masq 1 0 0
-> 192.168.131.20:80 Masq 1 0 0
测试:

5.更改权重
bash
[root@vsnode ~]# ipvsadm -e -t 192.168.170.100:80 -r 192.168.131.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 192.168.170.100:80 wrr
-> 192.168.131.10:80 Masq 2 0 0
-> 192.168.131.20:80 Masq 1 0 0
测试:

8.规则持久化,实验过程可以用过打开另外一个shell的并执行监控命令的方式进行观察
(1)利用自定义文件进行持久化
bash
[root@vsnode ~]# ipvsadm-save -n
-A -t 192.168.170.100:80 -s wrr
-a -t 192.168.170.100:80 -r 192.168.131.10:80 -m -w 2
-a -t 192.168.170.100:80 -r 192.168.131.20:80 -m -w 1
[root@vsnode ~]# ipvsadm-save -n > /mnt/ipvs.rule
[root@vsnode ~]# ipvsadm -C
[root@vsnode ~]# ipvsadm-restore < /mnt/ipvs.rule
(2)利用守护进程进行规则持久化
bash
[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.
5.2部署DR模式集群案例
5.2.1.实验环境
| 主机名 | ip | vip | 角色 |
|---|---|---|---|
| client | 192.168.170.99 vmware NAT | null | 测试主机 |
| router | NAT-eth0:192.168.170.100,仅主机-eth1:192.168.131.10 | null | 路由器 |
| vscode | 192.168.131.50,GW 192.168.131.100 仅主机 | lo:192.168.131.200 | 调度器 |
| RS1 | 192.168.131.10,GW 192.168.131.100 仅主机 | lo:192.168.131.200 | web服务器1 |
| RS2 | 192.168.131.20, GW 192.168.131.100 仅主机 | lo:192.168.131.200 | web服务器2 |
5.2.2解决vip响应问题
DR模型中各主机上均需要配置VIP,解决地址冲突的方式有三种:
(1)在前端网关做静态绑定
(2)在各RS使用arptables
(3)在各RS修改内核参数,来限制arp响应和通告的级别
5.2.3.配置详情
配置要点
1.Director服务器采用双IP桥接网络,一个是VPP,一个DIP
2.Web服务器采用和DIP相同的网段和Director连接
3.每个Web服务器配置VIP
4.每个web服务器可以出外网
配置内容如下:
1.在路由器中
(1)将原本调度器改为路由器router,并关闭ipvsadm命令
bash
[root@vsnode ~]# hostnamectl hostname router
[root@router ~]# systemctl disable --now ipvsadm.service
Removed "/etc/systemd/system/multi-user.target.wants/ipvsadm.service".
[root@router ~]# ipvsadm -C
(2)设定内核路由功能
bash
[root@router ~]# echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf
[root@router ~]# sysctl -p
net.ipv4.ip_forward = 1
(3)数据转发策略
bash
[root@router ~]# iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 192.168.131.100
[root@vsnode ~]# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 192.168.170.100
2.vsnode 调度器
(1)网络配置
bash
[root@vsnode ~]# vmset.sh eth0 192.168.0.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.131.50/24,192.168.131.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.131.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)
(2)配置策略
bash
[root@vscode ~]# ipvsadm -A -t 192.168.131.100:80 -s wrr
[root@vscode ~]# ipvsadm -a -t 192.168.131.100:80 -r 192.168.131.101:80 -g
[root@vscode ~]# ipvsadm -a -t 192.168.131.100:80 -r 192.168.131.102:80 -g
[root@vscode ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.131.100:80 wrr
-> 192.168.131.101:80 Route 1 0 0
-> 192.168.131.102:80 Route 1 0 0
[root@vscode ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.131.100:80 wrr
-> 192.168.131.101:80 Route 1 0 0
-> 192.168.131.102:80 Route 1 0 0
3.客户端
测试是否能ping通调度器
bash
[root@client ~]# ping 192.168.131.200
PING 192.168.131.200 (192.168.131.200) 56(84) 比特的数据。
64 比特,来自 192.168.131.200: icmp_seq=1 ttl=128 时间=0.953 毫秒
64 比特,来自 192.168.131.200: icmp_seq=2 ttl=128 时间=1.82 毫秒
^C
--- 192.168.131.200 ping 统计 ---
已发送 2 个包, 已接收 2 个包, 0% packet loss, time 1009ms
rtt min/avg/max/mdev = 0.953/1.384/1.815/0.431 ms
4.RS1和RS2
(1)在lo上设定vip并激活
bash
[root@RS1 ~]# cd /etc/NetworkManager/system-connections/
[root@RS1 system-connections]# cp -p eth0.nmconnection lo.nmconnection
[root@RS1 system-connections]# vim lo.nmconnection
[connection]
id=lo
type=loopback
interface-name=lo
[ipv4]
address1=127.0.0.1/8
address2=192.168.131.200/32
method=manual
[root@RS1 system-connections]# nmcli connection reload
[root@RS1 system-connections]# nmcli connection up lo
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/6)
[root@RS1 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.131.200/32 scope global lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
(2)arp禁止响应
bash
[root@RS1 system-connections]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@RS1 system-connections]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@RS1 system-connections]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
[root@RS1 system-connections]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
测试:

5.3.防火墙标签解决轮询错误
5.3.1.轮询规则中可能会遇到的错误
以http和https为例,当我们在RS中同时开放80和443端口,那么默认控制是分开轮询的,这样我们就出现了一个轮询错乱的问题
问题背景 :
当 LVS 同时为 HTTP(80)和 HTTPS(443)提供服务时,若分别配置两个虚拟服务(如 VIP:80 和 VIP:443),LVS 会独立调度 这两个端口。这可能导致同一客户端访问 80 端口被分配到 RS1,而访问 443 时又被分配到 RS2,破坏会话一致性(例如登录状态丢失)。
问题呈现
bash
在RS1和RS2中安装mod_ssl并重启apache
]# yum install mod_ssl -y
]# systemctl restart httpd
在vsode中设置调度,因为我们要调度80和443两个端口所以我们需要设定两组策略
]# ipvsadm -C
[root@vscode ~]# ipvsadm -A -t 192.168.131.200:80 -s rr
[root@vscode ~]# ipvsadm -A -t 192.168.131.200:443 -s rr
[root@vscode ~]# ipvsadm -a -t 192.168.131.200:80 -r 192.168.131.10:80 -g
[root@vscode ~]# ipvsadm -a -t 192.168.131.200:80 -r 192.168.131.20:80 -g
[root@vscode ~]# ipvsadm -a -t 192.168.131.200:443 -r 192.168.131.10:80 -g
[root@vscode ~]# ipvsadm -a -t 192.168.131.200:443 -r 192.168.131.20:80 -g
[root@vscode ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 192.168.131.200:80 rr
-> 192.168.131.10:80 Route 1 0 0
-> 192.168.131.20:80 Route 1 0 0
TCP 192.168.131.200:443 rr
-> 192.168.131.10:443 Route 1 0 0
-> 192.168.131.20:443 Route 1 0 0
测试问题
[root@client ~]# curl http://192.168.131.200;curl -k https://192.168.131.200
RS1 server - 192.168.131.10
RS1 server - 192.168.131.10
当访问vip时两次调度都到了10
解决方案:使用防火墙标记(FireWall Mark, FWM)
-
在 Director(调度器) 上通过
iptables的mangle表,对目标为 VIP 且目的端口为 80/443 的报文打上相同标记 (如--set-mark 6666)。 -
然后在 LVS 中基于该标记(-f 6666)定义一个统一的虚拟服务,使多个端口共享同一调度策略和后端 RS 列表。
-
结果:来自同一客户端的 80 和 443 请求始终被调度到同一台 RS ,保证业务连续性。
bash在vs调度器中设定端口标签,人为80和443是一个整体 [root@vscode ~]# iptables -t mangle -A PREROUTING -d 192.168.131.200 -p tcp -m multiport --dports 80,443 -j MARK --set-mark 6666 设定调度规则 [root@vscode ~]# ipvsadm -A -f 6666 -s rr [root@vscode ~]# ipvsadm -a -f 6666 -r 192.168.131.10 -g [root@vscode ~]# ipvsadm -a -f 6666 -r 192.168.131.20 -g
测试结果:

5.4 LVS 持久连接(Persistence)
目的 :确保同一客户端在一段时间内始终访问同一台 RS,适用于需要保持会话状态的场景(如表单提交、购物车)。
原理 :
LVS 在内核中维护一个持久连接模板表 ,记录源 IP 到 RS 的映射关系。只要在超时时间内(默认 360 秒)再次访问,就复用之前的调度结果,无视调度算法。
配置方式 :
在创建或修改虚拟服务时添加 -p [timeout] (注意:持久连接优先级高于调度算法(如 RR、WLC),但长时间不用会失效。):
bash
ipvsadm -AlE -tlulf service-address [-s scheduler] [-p [timeout]]默认360秒
在lvs调度器中设定
[root@lvs ~]# ipvsadm -E -f 6666 -s rr -p [3000] # 持久连接 3000 秒
[root@lvs ~]# ipvsadm -LnC