LVS 项目知识点总结

系统性能扩展与集群简介

1. 系统性能扩展方式

常见的系统性能扩展方式有两种:

Scale Up(向上扩展):通过增强单台服务器的硬件配置(CPU、内存、硬盘)来提升性能,成本较高且有上限。

Scale Out(向外扩展):通过增加服务器数量形成集群,共同完成任务,处理能力可以线性增长,但需要解决负载均衡和任务调度问题。

2. 什么是集群(Cluster)

集群(Cluster)是为了解决某个特定问题,将多台计算机组合起来,对外表现为一个单一系统。集群根据用途通常分为三类:

负载均衡集群(LB, Load Balancing):由多台服务器组成,每台服务器只承担一部分访问请求,通过前端调度器分发流量,实现系统处理能力的高可扩展性。

高可用集群(HA, High Availability):通过冗余节点消除单点故障(SPOF),当主节点出现故障时,备用节点自动接管服务。衡量高可用性的关键指标包括 MTBF(平均无故障时间)、MTTR(平均恢复时间)和可用率 A = MTBF/(MTBF+MTTR),通常以"99.9%、99.99%"等形式体现 SLA(服务等级协议)。

高性能计算集群(HPC, High Performance Computing):将多台计算机的计算能力联合起来,解决复杂的科学计算问题,属于国家级战略资源,不在本次课程范围内。

3. 集群与分布式的区别

集群:同一套业务系统部署在多台服务器上,每台服务器的功能和代码完全相同,数据和业务逻辑没有差异。集群通过提高单位时间内处理的任务数量来提升效率。

分布式:一个业务系统被拆分成多个子业务,或本身就是不同的业务,部署到多台服务器上。每台服务器实现的功能不同,代码和数据也有差异,所有节点组合在一起才能完成完整业务。分布式通过缩短单个任务的执行时间来提升效率。

二、LVS 的作用与基本概念

LVS(Linux Virtual Server)是一个开源的负载均衡调度器,由章文嵩博士开发,已集成到 Linux 内核中。阿里的四层 SLB(Server Load Balance)便是基于 LVS + Keepalived 实现。LVS 工作在网络四层,不关心具体应用层数据,只根据 IP、端口和协议分发请求,具有极高的性能和稳定性。

1. LVS 核心术语

VS(Virtual Server):虚拟服务器,即调度器(Director),负责接收客户端请求并进行分发。

RS(Real Server):真实业务服务器,真正处理客户端请求并返回数据。

CIP(Client IP):客户端主机的 IP 地址。

VIP(Virtual IP):调度器对外暴露的 IP 地址,供客户端访问。

DIP(Director IP):调度器对内与 RS 通信使用的 IP 地址。

RIP(Real IP):真实服务器的 IP 地址。

基本访问流程:CIP ↔ VIP == DIP ↔ RIP。

2. LVS 工作原理

LVS 根据请求报文的目标 IP、目标协议及端口,按照选定的调度算法,将请求转发到某台 RS。整个转发过程对客户端是透明的。

LVS 安装部署与 ipvsadm 命令详解

1. LVS 的安装

bash 复制代码
[root@lvs-server ~]# dnf install ipvsadm.x86_64 -y

2. 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

3. ipvsadm 核心功能

ipvsadm 命令主要提供以下核心功能:集群服务管理:增、删、改集群服务的 RS 管理:增、删、改,查看规则在操作过程中,可以通过另一个 shell 开启实时监控:

bash 复制代码
[root@lvs-server ~]# watch -n 1 ipvsadm -Ln
管理集群服务(增删改)
bash 复制代码
# 设定服务器 VIP、端口及调度算法
[root@lvs-server ~]# ipvsadm -A -t 172.25.254.100:80 -s rr
指定使用防火墙标记来进行轮询,-p 指定持久连接超时时间(秒)
[root@lvs-server ~]# ipvsadm -A -f 66 -p 3000
更改调度算法
[root@lvs-server ~]# ipvsadm -E -t 172.25.254.100:80 -s wrr
删除集群服务
[root@lvs-server ~]# ipvsadm -D -f 66
管理集群中的 RealServer(增删改)
bash 复制代码
# 增加 RS(-m 表示 NAT 模式,-g 表示 DR 模式,-i 表示 TUN 模式)
[root@lvs-server ~]# ipvsadm -a -t 172.25.254.100:80 -r 192.168.0.10 -m
[root@lvs-server ~]# ipvsadm -a -t 172.25.254.100:80 -r 192.168.0.20 -m
修改 RS 权重和工作模式
[root@lvs-server ~]# ipvsadm -e -t 172.25.254.100:80 -r 192.168.0.10 -w 2 -m
[root@lvs-server ~]# ipvsadm -e -t 172.25.254.100:80 -r 192.168.0.20 -w 5 -i
删除单个 RS
[root@lvs-server ~]# ipvsadm -d -t 172.25.254.100:80 -r 192.168.0.20
清空所有规则
[root@lvs-server ~]# ipvsadm -C

4. LVS 策略保存

方法一:利用自定义文件保存策略
bash 复制代码
# 添加规则
[root@lvs-server ~]# ipvsadm -A -t 172.25.254.100:80 -s rr
[root@lvs-server ~]# ipvsadm -a -t 172.25.254.100:80 -r 192.168.0.10 -m
[root@lvs-server ~]# ipvsadm -a -t 172.25.254.100:80 -r 192.168.0.20 -m
查看并保存规则
[root@lvs-server ~]# ipvsadm-save
-A -t lvs-server:http -s rr
-a -t lvs-server:http -r 192.168.0.10:http -m -w 1
-a -t lvs-server:http -r 192.168.0.20:http -m -w 1
导出到自定义文件
[root@lvs-server ~]# ipvsadm-save > /mnt/haha
清空规则验证
[root@lvs-server ~]# ipvsadm -C
[root@lvs-server ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
-> RemoteAddress:Port           Forward Weight ActiveConn InActConn
从文件恢复规则
[root@lvs-server ~]# ipvsadm-restore < /mnt/haha
[root@lvs-server ~]# 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.0.100:80 rr
-> 192.168.0.10:80              Masq    1      0          0
-> 192.168.0.20:80              Masq    1      0          0
方法二:ipvs 策略开机生效
bash 复制代码
# 保存规则到系统配置文件
[root@lvs-server ~]# ipvsadm-save > /etc/sysconfig/ipvsadm
启用 ipvsadm 服务
[root@lvs-server ~]# systemctl enable --now ipvsadm.service
重启后仍然生效
reboot
[root@lvs-server ~]# 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.0.100:80 rr
-> 192.168.0.10:80              Masq    1      0          0
-> 192.168.0.20:80              Masq    1      0          0

三、LVS 的四种工作模式及原理

1. NAT 模式

本质是多目标 IP 的 DNAT(目标地址转换)。调度器将请求报文中的目标 IP 和目标端口修改为挑选出的 RS 的 RIP 和对应端口,再将报文发送给 RS。响应报文同样必须经过调度器,由调度器把源地址从 RIP 改回 VIP 后返回客户端。

特点与限制:

RIP 和 DIP 通常位于同一 IP 网络,且应使用私网地址。

RS 的网关必须指向 DIP。

所有请求和响应都经过调度器,调度器容易成为性能瓶颈。

支持端口映射,可修改请求报文的目标端口。

VS 必须是 Linux 系统,RS 可以是任意操作系统。

实验步骤

**实验环境:**VS 主机 eth0=172.25.254.100(VIP),eth1=192.168.0.100(DIP);RS1=192.168.0.10;RS2=192.168.0.20;服务端口为 80。

环境设定

VS 主机网络配置:

bash 复制代码
[root@vsnode ~]# vmset.sh eth0 172.25.254.100 vsnode
[root@vsnode ~]# vmset.sh eth1 192.168.0.100 vsnode noroute

RS1 网络配置与业务部署:

bash 复制代码
# 设定网络
[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
设定访问业务真实数据
[root@RS1 ~]# dnf install httpd -y
[root@RS1 ~]# systemctl enable --now httpd
[root@RS1 ~]# echo RS1 - 192.168.0.10 > /var/www/html/index.html

RS2 网络配置与业务部署:

bash 复制代码
# 设定网络
[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
设定访问业务真实数据
[root@RS2 ~]# dnf install httpd -y
[root@RS2 ~]# systemctl enable --now httpd
[root@RS2 ~]# echo RS2 - 192.168.0.20 > /var/www/html/index.html

在 VS 主机中测试环境连通性:

bash 复制代码
[root@vsnode ~]# curl 192.168.0.10
RS1 - 192.168.0.10
[root@vsnode ~]# curl 192.168.0.20
RS2 - 192.168.0.20
实现 NAT 模式负载均衡

1. 开启内核路由功能:

bash 复制代码
[root@vsnode ~]# echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf
[root@vsnode ~]# sysctl -p
net.ipv4.ip_forward = 1

2. 编写 ipvsadm 策略:

bash 复制代码
[root@vsnode ~]# ipvsadm -C
[root@vsnode ~]# ipvsadm -A -t 172.25.254.100:80 -s wrr
[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
[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.0.10:80              Masq    1      0          0
  -> 192.168.0.20:80              Masq    1      0          0

3. 测试负载均衡效果:

bash 复制代码
[root@vsnode ~]# for i in {1..10};do curl 172.25.254.100;done
RS2 - 192.168.0.20
RS1 - 192.168.0.10
RS2 - 192.168.0.20
RS1 - 192.168.0.10
RS2 - 192.168.0.20
RS1 - 192.168.0.10
RS2 - 192.168.0.20
RS1 - 192.168.0.10
RS2 - 192.168.0.20
RS1 - 192.168.0.10

4. 更改权重并验证:

bash 复制代码
[root@vsnode ~]# ipvsadm -e -t 172.25.254.100:80 -r 192.168.0.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.0.10:80              Masq    2      0          5
  -> 192.168.0.20:80              Masq    1      0          5
[root@vsnode ~]# for i in {1..10};do curl 172.25.254.100;done
RS2 - 192.168.0.20
RS1 - 192.168.0.10
RS1 - 192.168.0.10
RS2 - 192.168.0.20
RS1 - 192.168.0.10
RS1 - 192.168.0.10
RS2 - 192.168.0.20
RS1 - 192.168.0.10
RS1 - 192.168.0.10
RS2 - 192.168.0.20
规则持久化

实验过程中可以通过打开另外一个 shell 并执行监控命令的方式进行观察:

bash 复制代码
[root@vsnode ~]# watch -n 1 ipvsadm -Ln

方法一:利用自定义文件进行持久化

bash 复制代码
[root@vsnode ~]# ipvsadm-save -n
-A -t 172.25.254.100:80 -s wrr
-a -t 172.25.254.100:80 -r 192.168.0.10:80 -m -w 2
-a -t 172.25.254.100:80 -r 192.168.0.20:80 -m -w 1
[root@vsnode ~]# ipvsadm-save -n > /mnt/ipvs.rule
[root@vsnode ~]# ipvsadm -C
[root@vsnode ~]# ipvsadm-restore < /mnt/ipvs.rule

方法二:利用守护进程进行规则持久化

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.

2. DR 模式

DR(Direct Routing)是 LVS 默认模式,也是应用最广泛的模式。它通过重新封装请求报文的 MAC 首部,将源 MAC 改为 DIP 所在接口的 MAC,目标 MAC 改为选定 RS 的 MAC。请求报文中的 IP/PORT 保持不变,因此 RS 可以直接将响应报文返回给客户端,无需经过调度器。

特点与限制:

调度器和所有 RS 都必须在同一个物理网络(二层网络)中。

调度器和每个 RS 都需要配置 VIP,并且 RS 必须抑制对 VIP 的 ARP 响应。

请求报文由调度器转发,响应报文由 RS 直接返回客户端,极大降低调度器压力。

不支持端口映射。

RS 可使用大多数操作系统。

实验步骤

**实验环境:**路由器 eth0=172.25.254.100,eth1=192.168.0.100;调度器(vsnode)eth0=192.168.0.50/24;VIP=192.168.0.200(绑定在各 RS 的 lo 接口和调度器的 lo 接口上);RS1=192.168.0.10;RS2=192.168.0.20;客户端 eth0=172.25.254.99/24;服务端口为 80。

路由器设定

在路由器上关闭 ipvsadm 服务并清空规则,配置双网卡并开启内核路由转发和数据转发策略:

bash 复制代码
# 关闭 ipvsadm 服务(路由器不承担调度角色)
[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 172.25.254.100 vsnode
[root@router ~]# vmset.sh eth1 192.168.0.100 vsnode noroute
开启内核路由功能
[root@router ~]# echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf
[root@router ~]# sysctl -p
net.ipv4.ip_forward = 1
数据转发策略(双向 SNAT)
[root@router ~]# iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 192.168.0.100
[root@router ~]# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 172.25.254.100
调度器(vsnode)设定

配置调度器 eth0 的 IP 和网关,并在 lo 接口上绑定 VIP:

bash 复制代码
# 配置 eth0
[root@vsnode ~]# vmset.sh eth0 192.168.0.50 vsnode noroute
[root@vsnode ~]# nmcli connection modify eth0 ipv4.gateway 192.168.0.100
[root@vsnode ~]# nmcli connection reload
[root@vsnode ~]# nmcli connection up eth0
或者直接编辑 eth0 连接配置文件
[root@vsnode ~]# vim /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0
[ipv4]
method=manual
address1=192.168.0.50/24,192.168.0.100
[root@vsnode ~]# nmcli connection reload
[root@vsnode ~]# nmcli connection up eth0
在 lo 接口上绑定 VIP(192.168.0.200/32)
[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.0.200/32
[root@vsnode system-connections]# nmcli connection reload
[root@vsnode system-connections]# nmcli connection up lo
验证路由和 IP
[root@vsnode ~]# 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
[root@vsnode ~]# ip a
1: lo:  mtu 65536 ...
inet 127.0.0.1/8 scope host lo
inet 192.168.0.200/32 scope global lo
2: eth0:  mtu 1500 ...
inet 192.168.0.50/24 ...
RS1 设定

配置 RS1 的网络,在 lo 接口上绑定 VIP 并抑制 ARP 响应:

bash 复制代码
# 配置 eth0
[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
在 lo 接口上绑定 VIP(192.168.0.200/32)
[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]
method=manual
address1=127.0.0.1/8
address2=192.168.0.200/32
[root@RS1 system-connections]# nmcli connection reload
[root@RS1 system-connections]# nmcli connection up lo
[root@RS1 ~]# ip a
1: lo:  mtu 65536 ...
inet 127.0.0.1/8 scope host lo
inet 192.168.0.200/32 scope global lo
抑制对 VIP 的 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
RS2 设定

RS2 配置与 RS1 类似,仅 IP 不同:

bash 复制代码
# 配置 eth0
[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
在 lo 接口上绑定 VIP(192.168.0.200/32)
[root@RS2 ~]# cd /etc/NetworkManager/system-connections/
[root@RS2 system-connections]# cp -p eth0.nmconnection lo.nmconnection
[root@RS2 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.0.200/32
[root@RS2 system-connections]# nmcli connection reload
[root@RS2 system-connections]# nmcli connection up lo
[root@RS2 ~]# ip a
1: lo:  mtu 65536 ...
inet 127.0.0.1/8 scope host lo
inet 192.168.0.200/32 scope global lo
抑制对 VIP 的 ARP 响应
[root@RS2 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
[root@RS2 ~]# echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
[root@RS2 ~]# echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
[root@RS2 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
客户端设定

配置客户端网络,网关指向路由器的 eth0:

bash 复制代码
# 配置 eth0
[root@client ~]# vmset.sh eth0 172.25.254.99 client noroute
[root@client ~]# nmcli connection reload
[root@client ~]# nmcli connection up eth0
[root@client ~]# ip a
2: eth0:  mtu 1500 ...
inet 172.25.254.99/24 ...
设置网关和 DNS
[root@client ~]# vim /etc/NetworkManager/system-connections/eth0.nmconnection
[connection]
id=eth0
type=ethernet
interface-name=eth0
[ipv4]
method=manual
address1=172.25.254.99/24,172.25.254.100
dns=8.8.8.8;
[root@client ~]# nmcli connection reload
[root@client ~]# nmcli connection up eth0
[root@client ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         172.25.254.100  0.0.0.0         UG    100    0        0 eth0
172.25.254.0    0.0.0.0         255.255.255.0   U     100    0        0 eth0
测试连通性
[root@client ~]# ping 192.168.0.200
PING 192.168.0.200 (192.168.0.200) 56(84) bytes of data.
64 bytes from 192.168.0.200: icmp_seq=1 ttl=128 time=1.08 ms
配置 DR 模式负载均衡规则

在调度器(vsnode)上使用 ipvsadm 配置 DR 模式的负载均衡规则(-g 表示 DR 模式):

bash 复制代码
# 清空已有规则并添加 DR 模式虚拟服务
[root@vsnode ~]# ipvsadm -C
[root@vsnode ~]# ipvsadm -A -t 192.168.0.200:80 -s wrr
[root@vsnode ~]# ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.10:80 -g -w 1
[root@vsnode ~]# ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.20:80 -g -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.0.200:80 wrr
-> 192.168.0.10:80              Route   1      0          0
-> 192.168.0.20:80              Route   1      0          0
测试验证

在客户端上多次访问 VIP,验证负载均衡效果:

bash 复制代码
[root@client ~]# for i in {1..10}; do curl 192.168.0.200; done
RS2 - 192.168.0.20
RS1 - 192.168.0.10
RS2 - 192.168.0.20
RS1 - 192.168.0.10
RS2 - 192.168.0.20
RS1 - 192.168.0.10
RS2 - 192.168.0.20
RS1 - 192.168.0.10
RS2 - 192.168.0.20
RS1 - 192.168.0.10

在调度器上查看连接统计,确认请求已按 DR 模式正确分发:

bash 复制代码
[root@vsnode ~]# ipvsadm -Ln --stats
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port               Conns   InPkts  OutPkts  InBytes OutBytes
  -> RemoteAddress:Port
TCP  192.168.0.200:80                    10       60        0     3480        0
  -> 192.168.0.10:80                     5       30        0     1740        0
  -> 192.168.0.20:80                     5       30        0     1740        0

注意:在 DR 模式下,调度器只转发入站请求,响应由 RS 直接返回客户端,因此 OutPkts 和 OutBytes 始终为 0。这也是 DR 模式高性能的关键原因之一。

3. TUN 模式(隧道模式)

调度器不修改请求报文的原始 IP 首部(CIP→VIP),而是在原始报文外层再封装一个 IP 头部(DIP→RIP),通过 IP 隧道将报文发往选定的 RS。RS 收到后去掉外层 IP 头,直接响应客户端。

特点与限制:

DIP、VIP、RIP 都应为公网地址,适合跨地域、跨机房部署。

RS 的网关一般不能指向 DIP。

请求报文经过调度器,但响应直接从 RS 返回客户端。

不支持端口映射。

RS 操作系统必须支持 IP 隧道功能。

4. FullNAT 模式

同时修改请求报文的源 IP(CIP→DIP)和目标 IP(VIP→RIP),实现完整的地址转换。响应报文同样需经过调度器,由调度器将源 IP 改回 VIP 后返回客户端。

特点与限制:

VIP 为公网地址,RIP 和 DIP 为私网地址,且通常不在同一 IP 网络。

RS 收到的请求源 IP 是 DIP,因此只需响应到 DIP,再由调度器转发给客户端。

请求和响应都经过调度器。

支持端口映射。

默认 Linux 内核不支持该模式,需要额外补丁。

四种模式核心差异对比
对比维度 NAT DR TUN FullNAT
原理 DNAT 目标地址转换 MAC 地址重写 IP 隧道封装 完整源/目标地址转换
网络要求 RIP/DIP 同网段,私网地址,RS 网关指向 DIP 同一二层网络,RS 需配置 VIP 并抑制 ARP 需公网 IP,RS 支持 IP 隧道 VIP 公网,RIP/DIP 私网,不需同网段
性能瓶颈 请求和响应均经过调度器,瓶颈明显 调度器仅转发请求,性能高 请求经调度器,响应直返,性能高 请求和响应均经过调度器,瓶颈明显
端口映射 支持 不支持 不支持 支持
适用场景 小型内网服务,需要端口映射 高性能大规模 Web 服务,同机房 跨地域、跨机房部署 需要透明代理和源 IP 转换的场景

四、LVS 的调度算法

LVS 调度算法分为静态调度算法和动态调度算法两大类,同时还包含新内核引入的特殊算法。下面一一介绍。

1. 静态调度算法

RR(Round Robin)轮询:依次将请求分发给所有 RS,不论 RS 的实际负载和性能差异,简单但不精准。

WRR(Weighted Round Robin)加权轮询:在轮询的基础上为 RS 赋予不同权重,性能高的 RS 获得更多请求。

SH(Source Hashing)源地址哈希:对客户端 IP 进行哈希运算,保证同一客户端的所有请求始终发往同一台 RS,用于实现会话保持(Session Sticky)。

DH(Destination Hashing)目标地址哈希:对请求的目标 IP 做哈希,将发往同一目标地址的请求始终转发到固定的 RS,常用于正向代理缓存场景(如宽带运营商)。

2. 动态调度算法

动态算法会根据各 RS 当前的负载状态(连接数)和权重进行调度,负载值 Overhead 越小的 RS 越优先被选中。

LC(Least Connections)最少连接:选择活动连接数最少的 RS,适用于长连接场景。Overhead = activeconns * 256 + inactiveconns。

WLC(Weighted Least Connections)加权最少连接:默认调度算法,在最少连接的基础上引入权重,Overhead = (activeconns * 256 + inactiveconns) / weight。

SED(Shortest Expected Delay)最短预期延迟:优先选择权重高、当前连接少的 RS,公式:(activeconns+1) * 256 / weight,初期高权重 RS 可能集中接收到大量连接。

NQ(Never Queue):第一轮平均分配,之后采用 SED 算法,避免加权模型下初期所有连接都涌向高权重 RS。

LBLC(Locality-Based Least Connection)基于局部性的最少连接:动态版 DH 算法,根据缓存负载状态将请求调度到与目标 IP "最接近"的 RS,用于正向代理缓存。

LBLCR(LBLC with Replication)带复制的 LBLC:在 LBLC 基础上增加负载均衡机制,可将负载较重的缓存 RS 上的部分内容复制到负载较轻的 RS 上,避免局部过载。

3. 新内核新增算法(4.15+)

FO(Weighted Failover)权重故障切换:常用于灰度发布,优先选择未标记为过载(OVERLOAD)且权重最高的 RS 进行调度。若该 RS 连接数过高,管理员可手动标记过载,让其暂时退出调度。

OVF(Overflow-Connection)溢出连接:基于 RS 的权重和当前活动连接数调度,只有当 RS 的活动连接数小于其权重值时才会被选中,依次使用下一个满足条件的 RS。

五、LVS 多端口轮询问题与防火墙标记解决方案

1. 问题描述

当一台 RS 同时提供多个服务端口(如 80 端口 HTTP 和 443 端口 HTTPS)时,如果分别为每个端口配置独立的 LVS 规则,不同端口的请求将被独立轮询。这会导致来自同一用户的 HTTP 和 HTTPS 请求分别落在不同的 RS 上,造成会话状态错乱。

2. 防火墙标签(FWM)解决方案

通过 Netfilter 的 mangle 表为来自 VIP 的特定协议、特定端口的报文打上相同的防火墙标记(MARK),然后将该标记绑定为一个 LVS 虚拟服务。这样,80 和 443 端口的流量被当作同一服务统一调度,保证了同一客户端的 HTTP 和 HTTPS 请求被发往同一 RS。

bash 复制代码
# 在 Director 上打标记,将 80 和 443 端口流量标记为 6666
iptables -t mangle -A PREROUTING -d 192.168.0.100 -p tcp -m multiport --dports 80,443 -j MARK --set-mark 6666
基于防火墙标记创建 LVS 服务
ipvsadm -A -f 6666 -s rr
ipvsadm -a -f 6666 -r 192.168.0.101 -g
ipvsadm -a -f 6666 -r 192.168.0.102 -g
实验步骤

实验环境沿用 DR 模式实验环境:VIP=192.168.0.200,DIP/Router eth0=172.25.254.100,eth1=192.168.0.100,调度器 vsnode eth0=192.168.0.50/24,RS1=192.168.0.10,RS2=192.168.0.20。

1. 在 RS 上同时开启 HTTP 和 HTTPS 服务

在 RS1 和 RS2 上安装 mod_ssl 并重启 httpd:

bash 复制代码
# 在 RS1 和 RS2 中执行
[root@RS1 ~]# dnf install mod_ssl -y
[root@RS2 ~]# dnf install mod_ssl -y
[root@RS1 ~]# systemctl restart httpd
[root@RS2 ~]# systemctl restart httpd
2. 在调度器上添加 HTTP 和 HTTPS 的轮询规则

在 vsnode 上分别为 80 和 443 端口创建独立的 LVS 服务:

bash 复制代码
[root@vsnode ~]# ipvsadm -A -t 192.168.0.200:80 -s rr
[root@vsnode ~]# ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.10:80 -g
[root@vsnode ~]# ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.20:80 -g
[root@vsnode ~]# ipvsadm -A -t 192.168.0.200:443 -s rr
[root@vsnode ~]# ipvsadm -a -t 192.168.0.200:443 -r 192.168.0.10:443 -g
[root@vsnode ~]# ipvsadm -a -t 192.168.0.200:443 -r 192.168.0.20:443 -g
[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.0.200:80 rr
  -> 192.168.0.10:80              Route   1      0          0
  -> 192.168.0.20:80              Route   1      0          0
TCP  192.168.0.200:443 rr
  -> 192.168.0.10:443             Route   1      0          0
  -> 192.168.0.20:443             Route   1      0          0
3. 轮询错误展示

在客户端分别请求 HTTP 和 HTTPS,观察独立轮询导致的重复问题:

bash 复制代码
[root@client ~]# curl 192.168.0.200; curl -k https://192.168.0.200
RS2 - 192.168.0.20
RS2 - 192.168.0.20
# HTTP 和 HTTPS 是独立的 service,轮询可能出现相同的 RS
4. 使用防火墙标记解决轮询错误

在调度器上使用 iptables 对发往 VIP:80 和 VIP:443 的 TCP 报文打上相同的防火墙标记 6666,然后基于标记创建统一的 LVS 服务:

bash 复制代码
# 打标记
[root@vsnode ~]# iptables -t mangle -A PREROUTING -d 192.168.0.200 -p tcp -m multiport --dports 80,443 -j MARK --set-mark 6666
基于防火墙标记创建 LVS 服务
[root@vsnode ~]# ipvsadm -A -f 6666 -s rr
[root@vsnode ~]# ipvsadm -a -f 6666 -r 192.168.0.10 -g
[root@vsnode ~]# ipvsadm -a -f 6666 -r 192.168.0.20 -g
5. 验证修复效果

在客户端再次测试,确认 HTTP 和 HTTPS 请求被调度到不同的 RS:

bash 复制代码
[root@client ~]# curl 192.168.0.200; curl -k https://192.168.0.200
RS2 - 192.168.0.20
RS1 - 192.168.0.10

六、LVS 会话粘滞(持久连接)解决方案

1. 问题背景

对于需要会话保持的应用(如用户登录、购物车),如果调度器仅按连接数或轮询分发请求,可能导致同一用户的连续请求到达不同的 RS,造成会话数据丢失。

2. 解决方案对比

SH 源地址哈希算法:将同一客户端 IP 所有请求固定调度到同一 RS,实现简单,但可能造成负载不均衡(同一源 IP 的流量过大时单台 RS 压力集中)。

持久连接(Persistent Connection):由 LVS 在内存中记录最近一段时间内每个源 IP 与对应 RS 的调度关系。在超时时间内,来自同一源 IP 的所有请求都会被转发到同一 RS,达到"粘滞"效果;超过超时时间后,该源 IP 可以被重新调度到其他 RS。此方法可与任意外部调度算法叠加使用,默认超时时间为 360 秒。

七、总结

LVS 是构建高可用、可扩展负载均衡集群的核心技术,掌握其四种工作模式的适用场景和十三种调度算法的选择策略,能够帮助我们在实际项目中灵活应对各种流量分发需求。结合防火墙标记可以解决多端口轮询错乱,利用持久连接或 SH 算法则可保证会话粘滞。理解这些知识点是深入企业级负载均衡架构的基础。

相关推荐
Y_cheng_20 小时前
LVS知识梳理
运维·服务器·lvs
高卧怡怡1 天前
LVS认识及基础详解
lvs
椿.湫1 天前
lvs技术
服务器·网络·lvs
懒神降世1 天前
LVS负载均衡集群项目总结(二)
运维·负载均衡·lvs
高磊20052 天前
LVS(Linux virual server)
linux·服务器·lvs
梦Arrebol2 天前
lvs项目知识点总结
lvs
养海绵宝宝的小蜗2 天前
LVS(Linux Virtual Server)项目知识点总结
linux·运维·lvs
池以遇2 天前
云原生——LVS
运维·云原生·lvs
ljj2535575051__2 天前
LVS(Linux virual server)
服务器·网络·lvs