一、什么是集群(Cluster)
集群是为了解决某个特定的问题,将多台计算机组合起来形成的单个系统
二、集群分类
(一)按功能用途划分
- 负载均衡集群 LB(Load Balance) 核心:分摊用户请求流量,LVS、Nginx、HAProxy 都属于此类。
- 高可用集群 HA(High Availability) 核心:故障自动转移,解决单点故障,代表:Keepalived、Heartbeat。
- 高性能集群 HPC(High Performance Computing) 核心:并行计算,用于大数据、科学运算,代表:MPI 分布式计算。
(二)按层级划分
- 四层负载均衡(传输层):LVS(IPVS 内核模块),基于 IP + 端口转发,性能极高
- 七层负载均衡(应用层):Nginx、Apache,基于 URL、Cookie、Host 转发,功能丰富
三、lvs的作用
1. 全称
Linux Virtual Server,Linux 虚拟服务器,由章文嵩博士开发,是 Linux 内核内置的四层负载均衡模块(ipvs)。
2. 核心作用
- 四层(TCP/UDP)流量调度,将客户端请求分发至后端多台真实服务器(RS);
- 实现后端服务水平扩容,支持成千上万并发连接;
- 配合 Keepalived 实现调度器本身高可用,消除调度器单点故障;
- 屏蔽后端服务器真实 IP,提升服务安全性。
3. LVS 架构三角色
- DS/Director Server(调度器):LVS 主机,配置 VIP 虚拟 IP,负责请求转发
- RS/Real Server(真实后端服务器):提供业务服务的 Web / 数据库节点
- VIP:虚拟 IP,用户直接访问的公网入口 IP
四、lvs的4种模式及原理
模式 1:VS-NAT 网络地址转换模式(最易部署)
1.nat模式数据逻辑

1.客户端发送访问请求,请求数据包中含有请求来源(cip),访问目标地址(VIP)访问目标端口 (9000port)
2.VS服务器接收到访问请求做DNAT把请求数据包中的目的地由VIP换成RS的RIP和相应端口 3.RS1相应请求,发送响应数据包,包中的相应保温为数据来源(RIP1)响应目标(CIP)相应端口 (9000port)
4.VS服务器接收到响应数据包,改变包中的数据来源(RIP1-->VIP),响应目标端口(9000-->80)
5.VS服务器把修改过报文的响应数据包回传给客户端 6.lvs的NAT模式接收和返回客户端数据包时都要经过lvs的调度机,所以lvs的调度机容易阻塞
2.nat模式数据传输过程

IPVS 内核模块工作在 PREROUTING 之后,iptables PREROUTING 规则会优先处理并篡改 / 丢弃待调度数据包,干扰 LVS 流量转发逻辑,因此部署 LVS 负载均衡时需要清空调度器上全部 iptables 防火墙规则,避免链路冲突。
3.nat模式实现

调度器中:
root@vsnode \~# vmset.sh eth0 172.25.254.100 vsnode
root@vsnode \~# vmset.sh eth1 192.168.0.100 vsnode noroute
#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 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
#测试
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
#更改权重
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
rs1中
#设定网络
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中
#设定网络
root@RS1 \~# vmset.sh eth0 192.168.0.20 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 RS2 - 192.168.0.20 > /var/www/html/index.html
模式 2:VS-DR 直接路由模式(生产最常用,性能最优)
**1.**DR模式数逻辑

在DR模式中,RS接收到访问请求后不需要回传给VS调度器,直接把回传数据发送给client,所以RS和vs 上都要有vip
2.DR模式数据传输过程

1.客户端发送数据帧给vs调度主机帧中内容为客户端IP+客户端的MAC+VIP+VIP的MAC
2.VS调度主机接收到数据帧后把帧中的VIP的MAC该为RS1的MAC,此时帧中的数据为客户端IP+客户端 的MAC+VIP+RS1的MAC
3.RS1得到2中的数据包做出响应回传数据包,数据包中的内容为VIP+RS1的MAC+客户端IP+客户端IP的 MAC
3.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 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
#数据转发策略
root@router \~# iptables -t nat -A POSTROUTING -o eth1 -j SNAT --to-source 192.168.0.100
root@vsnode \~# iptables -t nat -A POSTROUTING -o eth0 -j SNAT --to-source 172.25.254.100
调度器中:
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.0.50/24,192.168.0.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.0.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.0.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
192.168.0.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.0.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.0.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 172.25.254.99 client norouter
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/4)
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:e5:75:af brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname ens160
inet 172.25.254.99/24 brd 172.25.254.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fee5:75af/64 scope link tentative noprefixroute
valid_lft forever preferred_lft forever
client
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
连接已成功激活(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 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) 比特的数据。
64 比特,来自 192.168.0.200: icmp_seq=1 ttl=128 时间=1.08 毫秒
RS1:
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
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
ethernet
ipv4
address1=127.0.0.1/8
address2=192.168.0.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.0.200/32 scope global lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
#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:
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
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
ethernet
ipv4
address1=127.0.0.1/8
address2=192.168.0.200/32
method=manual
root@RS2 system-connections# nmcli connection reload
root@RS2 system-connections# nmcli connection up lo
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/6)
root@RS2 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.0.200/32 scope global lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
#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
模式 3:VS-TUN IP 隧道模式(跨公网跨地域调度)
1.DIP, VIP, RIP都应该是公网地址
2.RS的网关一般不能指向DIP
3.请求报文要经由Director,但响应不能经由Director
4.不支持端口映射
5.RS的OS须支持隧道功能
模式 4:VS-FULLNAT 全 NAT 模式(阿里开源扩展模式)
四种模式核心对比表
| 模式 | 报文修改位置 | 回程路径 | 是否支持端口映射 | 推荐场景 |
|---|---|---|---|---|
| NAT | 三层 IP + 端口 | 经 DS | 支持 | 测试环境、少量后端 |
| DR | 二层 MAC 地址 | 直回客户端 | 不支持 | 生产大规模集群 |
| TUN | IP 隧道封装 | 直回客户端 | 不支持 | 跨公网异地节点 |
| FullNAT | 双向 IP 转换 | 经 DS | 支持 | 特殊跨网段内网架构 |
五、lvs的13种算法
(一)静态调度算法(共 4 种)
- rr 轮询 Round Robin 请求依次逐个分给每台 RS,不考虑服务器性能、连接数;适合所有 RS 硬件完全一致场景。
- wrr 加权轮询 Weighted RR 给 RS 设置权重,权重越高分配请求越多;解决服务器性能差异问题,比如 8 核机器权重 3,4 核权重 1。
- sh 源地址哈希 Source Hash 对客户端源 IP 做哈希运算,同一 IP 永远调度到同一台 RS;原生实现会话黏滞。
- dh 目标地址哈希 Destination Hash 对访问目标 IP 哈希,同一目标地址固定分到一台 RS;多用于后端缓存服务器集群。
(二)动态调度算法(共 9 种,基于实时负载)
- lc 最少连接 Least Connections 优先分给当前活跃 TCP 连接数最少的 RS;长连接服务(数据库、SSH)适用。
- wlc 加权最少连接 Weighted LC(LVS 默认算法) LC 升级版,计算公式:
(活跃连接数×256+非活跃连接)/权重,数值越小越优先分配;兼顾负载与服务器性能,通用首选。 - sed 最短期望延迟 Shortest Expected Delay 简化版 WLC,只计算活跃连接:
(活跃连接数+1)×256/权重,忽略空闲连接,响应速度更快。 - nq 永不排队 Never Queue SED 优化版:如果存在活跃连接数为 0 的空闲 RS,直接分配,不执行公式计算,避免空闲节点闲置。
- lblc 基于本地的最少连接 缓存集群专用:同一客户端 IP 优先调度至上一次访问的 RS,仅当该节点负载过高时,切换为最少连接节点。
- lblcr 带复制的基于本地最少连接 LBLC 升级版,允许多台 RS 缓存同一份数据,提升缓存命中率。
六、lvs的多端口轮询问题解决方案
1. 问题描述
同一台后端 RS 需要对外提供多个端口服务(如 80 网页、443 HTTPS、3306 数据库),直接对 VIP 多端口轮询会出现:80 分到 RS1、443 分到 RS2,业务端口分散在不同节点。
使用防火墙标记 FWMARK(最优,统一调度池)
给多个端口打同一个防火墙标记,LVS 基于标记做统一调度,保证多端口请求落在同一 RS:
#1.添加轮询策略
root@vsnode boot# ipvsadm -A -t 192.168.0.200:80 -s rr
root@vsnode boot# ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.20 -g
root@vsnode boot# ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.10 -g
root@vsnode boot# ipvsadm -A -t 192.168.0.200:443 -s rr
root@vsnode boot# ipvsadm -a -t 192.168.0.200:443 -r 192.168.0.10:443 -g
root@vsnode boot# ipvsadm -a -t 192.168.0.200:443 -r 192.168.0.20:443 -g
root@vsnode boot# ipvsadm -Ln
2. iptables给VIP 80/443打标记10
root@vsnode boot# iptables -t mangle -A PREROUTING -d 192.168.0.200 -p tcp -m multiport --dports 80,443 -j MARK --set-mark 10
3. LVS基于标记10创建集群,只配置一次后端RS
root@vsnode boot#ipvsadm -A -f 10 -s wlc
root@vsnode boot#ipvsadm -a -f 10 -r 192.168.1.10 -g
root@vsnode boot#ipvsadm -a -f 10 -r 192.168.1.20 -g
七、lvs的会话粘滞解决方案
1. 问题本质
HTTP 会话、登录 Session、购物车数据存储在单台 RS 内存,LVS 轮询导致同一用户多次请求落到不同服务器,登录状态丢失。
1.设定ipvs调度策略
root@vsnode \~# ipvsadm -A -f 10 -s rr -p 1
通过
-p参数设置黏滞超时时间,同一客户端 IP 在超时时间内固定调度同一 RS,实操命令:
