集群到底是什么?
集群:把多台独立服务器(节点)组合在一起,对外看成一个整体,协同完成工作。单台服务器:单点,一旦宕机服务直接挂;性能上限固定。
集群:一堆机器组队。分担压力、互相备份,组成集群的每一台服务器,叫做节点(node)。
集群三大经典分类
负载均衡集群 LB(Load Balance)
目标:分摊流量,提升处理能力,解决并发压力。
请求统一发到调度器,分发到后端多台业务服务器。
典型组件:LVS、HAProxy、Nginx 负载均衡
场景:网站、API 服务、Ollama 多实例集群
例子:上万用户访问网站,一台扛不住,多台 web 服务器组成集群,流量分散。
高可用集群 HA(High Availability)
目标:防止单点故障,机器坏了业务不中断,实现故障自动转移。
核心:冗余、故障切换(failover)
典型组件:Keepalived、Pacemaker
场景:数据库主备、关键中间件
例子:主服务器宕机,备用服务器立刻接管虚拟 IP,用户无感知。
场景:网站流量突增,单台服务器扛不住压力,页面加载卡顿、接口超时,甚至直接宕机。
这时候,负载均衡就成了救命稻草,而LVS(Linux Virtual Server)作为Linux内核层的高性能负载均衡方案,更是大型系统架构中不可或缺的一环。
一、初识LVS:什么是Linux Virtual Server?
LVS全称Linux Virtual Server,即Linux虚拟服务器,是由章文嵩博士开发的一款开源负载均衡技术,目前已成为Linux内核的标准模块之一。它的核心作用很简单:将前端客户端的请求流量,智能分发到后端多台真实服务器(Real Server,简称RS)上,实现负载分担,从而提升服务的并发处理能力、可用性和稳定性。
这里要划重点:LVS工作在OSI七层模型的第四层(传输层),基于IP和端口进行流量转发,属于“四层负载均衡”,相比Nginx等七层负载均衡,它的优势在于性能极高——因为是内核层转发,几乎没有用户态到内核态的切换开销,能轻松承载百万级并发。
二、了解LVS核心术语
VS(Virtual Server):虚拟服务器,也就是LVS调度器,对外提供一个统一的访问入口(VIP),负责接收客户端请求并分发到后端RS。
RS(Real Server):真实服务器,真正提供业务服务的服务器(比如Web服务器、应用服务器),后端可以有多台,形成集群。
VIP(Virtual IP):虚拟IP,VS对外暴露的IP地址,是客户端唯一的访问地址,相当于集群的“门面”。
DIP(Director IP):调度器的内网IP,用于和后端RS通信,转发请求和接收响应(部分模式下)。
RIP(Real IP):真实服务器的IP地址,后端RS的内网IP,用于和VS通信。
CIP(Client IP):客户端的IP地址,发起请求的终端IP。
总结访问流程:客户端(CIP)访问VIP → VS(调度器,DIP)接收请求 → 调度器将请求分发到某台RS(RIP) → RS处理请求并响应 → 响应结果返回给客户端。
LVS四大工作模式:
LVS有四种核心工作模式,分别是NAT模式、DR模式、TUN模式和FULLNAT模式,其中NAT和DR是最常用的两种,TUN和FULLNAT仅作了解即可。
三、LVS四大工作模式:重点掌握这两种
LVS有四种核心工作模式,分别是NAT模式、DR模式、TUN模式和FULLNAT模式,其中NAT和DR是最常用的两种,TUN和FULLNAT仅作了解即可,我们重点拆解前两种。
3.1 NAT模式:简单易部署,适合小规模集群
NAT(Network Address Translation)模式,本质是“多目标IP的DNAT”,核心是通过修改请求报文的目标IP和端口,将请求转发到后端RS,所有请求和响应都需要经过VS调度器。
核心原理:
客户端发送请求,数据包中包含CIP(源IP)、VIP(目标IP)和目标端口(比如80)。
VS调度器接收请求,将数据包的目标IP(VIP)改为某台RS的RIP,目标端口改为RS的对应端口,然后转发给该RS。
RS处理请求后,发送响应数据包,源IP是RIP,目标IP是CIP。
VS调度器接收响应,将源IP(RIP)改为VIP,目标端口(如果有修改)改回客户端请求的端口,再将响应转发给客户端。
优缺点:
优点:部署简单,RS不需要配置VIP,支持端口映射,RS可以是任意操作系统(Windows、Linux都可以)。
缺点:所有请求和响应都经过VS,VS容易成为性能瓶颈,适合后端RS数量较少(建议不超过10台)的小规模集群。
注意:NAT模式下,RS的网关必须指向VS的DIP,否则响应报文无法返回给VS;同时要清空iptables防火墙策略,避免干扰LVS工作。
3.2 DR模式:性能最优,生产环境首选
DR(Direct Routing)模式,即直接路由模式,是LVS的默认模式,也是应用最广泛的模式。它的核心是不修改IP地址和端口,仅通过重新封装MAC地址,将请求转发到后端RS,响应报文由RS直接返回给客户端,不经过VS。
核心原理:
客户端发送请求,数据帧中包含CIP、客户端MAC、VIP、VIP的MAC。
VS调度器接收数据帧,将帧中的目标MAC(VIP的MAC)改为某台RS的MAC地址,源MAC改为VS的DIP对应接口的MAC,然后转发给该RS(IP和端口不变)。
RS接收数据帧,发现目标IP是VIP(RS上也配置了VIP),就处理请求,然后直接将响应报文发送给客户端(源IP是VIP,目标IP是CIP),不经过VS。
优缺点:
优点:性能极高,响应报文不经过VS,VS仅负责分发请求,不会成为瓶颈;支持大规模集群(后端RS可达到上百台)。
缺点:部署相对复杂,VS和RS必须在同一个物理网络(不能跨网段);RS和VS上都需要配置VIP,需要解决VIP地址冲突问题。
解决VIP冲突的方法(重点):
方法1:在前端网关做静态绑定,将VIP和VS的MAC地址绑定,确保请求都发送到VS。
方法2:在RS上使用arptables工具,禁止RS响应VIP的ARP请求。
方法3:修改RS的内核参数(arp_ignore和arp_announce),限制ARP响应和通告级别,避免RS对外暴露VIP。
3.3 TUN模式和FULLNAT模式(了解即可)
TUN模式:通过在原IP报文外封装一个新的IP首部(源IP是DIP,目标IP是RIP),实现远距离转发,适合VS和RS不在同一物理网络的场景,但RS必须支持隧道功能,且所有IP(DIP、VIP、RIP)都需是公网地址。
FULLNAT模式:同时修改请求报文的源IP(CIP→DIP)和目标IP(VIP→RIP),支持跨网段部署,但Linux内核默认不支持,需要手动打补丁,应用场景较少。
3.4LVS工作模式总结
四、LVS调度算法
LVS的调度算法决定了请求如何分配到后端RS,分为静态算法(不考虑RS负载)和动态算法(根据RS负载动态分配),我们重点掌握常用的几种。
4.1 静态调度算法
RR:将请求依次分发到后端RS,简单公平,但不考虑RS的性能差异,适合所有RS配置相同的场景。
WRR:根据RS的权重分配请求,权重越高的RS,被分配到请求的次数越多,适合RS配置不同的场景(比如高性能服务器权重高)。
SH:根据客户端的源IP(CIP)进行哈希计算,将同一个IP的请求始终分发到同一台RS,实现会话绑定(session sticky),适合需要保持会话的场景(比如用户登录后的数据交互)。
DH:Destination Hashing;目标地址哈希,第一次轮询调度至RS,后续将发往同一个目标地址的请 求始终转发至第一次挑中的RS,典型使用场景是正向代理缓存场景中的负载均衡,如:宽带运营商
4.2 动态调度算法
WLC(权重最少链接):LVS默认调度算法,根据RS的权重和当前连接数动态分配请求,权重越高、连接数越少的RS,被优先分配请求,适合大多数生产场景。默认调度方法Overhead=(activeconns x 256+inactiveconns)/weight
LC(最少链接发):不考虑权重,仅将请求分配给当前连接数最少的RS,适合RS配置相同的场景。 适用于长连接应用Overhead(负载值)=activeconns(活动链接数) x 256+inactiveconns(非活动链接数)
FO:4.15内核后新增,常用作灰度发布,优先调度权重最高且未过载的RS,若RS过载,则不再分配请求。在此FO算法中,遍历虚拟服务所关联的真实服务器链表,找到还未过载(未设置IP_VS_DEST_F OVERLOAD标志)的且权重最高的真实服务器,进行调度,当服务器承接大量链接,我们可以对此服务器进行过载标记(IP_VS_DEST_F OVERLOAD),那么vs调度器就不会把链接调度到有过载标记的主机中。
SED:Shortest Expection Delay,初始连接高权重优先Overhead=(activeconns+1+inactiveconns) x 256/weight,但是,当node1的权重为1,node2的权重为10,经过运算前几次的调度都会被node2承接
NQ:Never Queue,第一轮均匀分配,后续SED
LBLC:Locality-Based LC,动态的DH算法,使用场景:根据负载状态实现正向代理
LBLCR:LBLC with Replication,带复制功能的LBLC,解决LBLC负载不均衡问题,从负载重的复制到负载轻的RS
五、实战部署
5.1 实验环境准备(DR模式)
主机名 | IP地址 | VIP | 角色 | 网关 |
|---|---|---|---|---|
| router(路由) | NAT-eth0:172.25.254.100,仅主机-eth1:192.168.0.100 | 无 | 路由器 | 无 |
LVS(调度器) | VIP-192.168.0.200 DIP-192.168.0.50(仅主机模式) | 192.168.0.200(lo接口) | VS | 192.168.0.100(路由器IP) |
RS1(真实服务器) | RIP-192.168.0.10(仅主机模式) | 192.168.0.200(lo接口) | RS(Web服务器) | 192.168.0.100 |
RS2(真实服务器) | RIP-192.168.0.20(仅主机模式) | 192.168.0.200(lo接口) | RS(Web服务器) | 192.168.0.100 |
client(测试机) | CIP-172.25.254.10(NAT模式) | 无 | 测试客户端 | 172.25.254.100 |
5.2 部署步骤
第一步:配置所有主机的网络(确保互相ping通)
以lvs调度器为例,配置网卡和VIP(rs1、rs2配置类似)
# 配置eth0网卡(仅主机模式) vim /etc/NetworkManager/system-connections/eth0.nmconnection [connection] id=eth0 type=ethernet interface-name=eth0 [ipv4] method=manual address1=192.168.50.0/24,192.168.0.100 # 配置VIP(lo接口) vim /etc/NetworkManager/system-connections/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 # 重启网络连接 nmcli connection up lo nmcli connection up eth0第二步:在RS(rs1、rs2)上解决VIP冲突,修改内核参数
# 修改内核参数,限制ARP响应和通告 echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce # 安装Web服务(用于测试) yum install httpd -y # 分别在rs1、rs2上创建测试页面 # rs1: echo "RS1 - 192.168.0.10" > /var/www/html/index.html # rs2: echo "RS2 - 192.168.0.20" > /var/www/html/index.html # 启动httpd服务 systemctl start httpd systemctl enable httpd第三步:在VS(lvs)配置调度策略
# 安装ipvsadm工具(LVS的管理工具) yum install ipvsadm -y # 先清除现有LVS策略 ipvsadm -C # 添加集群服务(VIP:192.168.0.200,端口80,调度算法WRR) ipvsadm -A -t 192.168.0.200:80 -s wrr # 添加后端RS,指定DR模式(-g表示DR模式) ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.10:80 -g ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.20:80 -g # 查看LVS策略 ipvsadm -Ln # 保存策略(避免重启失效) ipvsadm -Sn > /etc/sysconfig/ipvsadm-config # 设置ipvsadm开机自启 systemctl enable --now ipvsadm.service第四步:测试LVS集群效果
# 循环访问VIP,查看响应结果 for N in {1..10};do curl 192.168.0.100;done测试结果
5.3 实战二:NAT模式部署
NAT模式部署无需配置VIP(仅VS需要VIP),无需解决VIP冲突,步骤更简洁,适合后端RS数量少的小规模场景,以下是完整部署流程,环境与DR模式复用,仅调整网络和调度配置
主机名 | IP地址(网卡模式) | VIP(仅VS配置) | 角色 | 网关(关键配置) |
lvs(调度器) | eth0:172.25.254.100(NAT模式,对外通信);eth1:192.168.0.100(仅主机模式,对内通信) | 172.25.254.100 | VS(双网卡,转发请求) | 无 |
rs1(真实服务器) | 192.168.0.10(仅主机模式) | 无 | RS(Web服务器) | IP:192.168.0.100 |
rs2(真实服务器) | 192.168.0.20(仅主机模式) | 无 | RS(Web服务器) | IP:192.168.0.100 |
client(测试机) | 172.25.254.10(NAT模式) | 无 | 测试客户端 | 172.25.254.100 |
NAT模式要求VS具备双网卡(外网网卡NAT模式,内网网卡仅主机模式),负责转发外网请求到内网RS;RS网关必须指向VS的内网IP,否则响应报文无法返回VS,这是NAT模式部署的核心要点。
5.3.2 部署步骤
第一步:配置VS(lvs)双网卡及内核转发
VS作为调度器,需配置双网卡(外网eth0、内网eth1),并开启内核IP转发功能,确保请求能正常转发。
# 1. 配置外网网卡eth0(NAT模式,对外暴露VIP) vim /etc/NetworkManager/system-connections/eth0.nmconnection [connection] id=eth0 type=ethernet interface-name=eth0 [ipv4] method=manual address1=172.25.254.100/24 # 此IP即为VIP,对外暴露 # 2. 配置内网网卡eth1(仅主机模式,与RS通信) vim /etc/NetworkManager/system-connections/eth1.nmconnection [connection] id=eth1 type=ethernet interface-name=eth1 [ipv4] method=manual address1=192.168.0.100/24 # 内网IP,与RS同一网段 # 3. 重启网络连接,使网卡配置生效 nmcli connection up eth0 nmcli connection up eth1 # 4. 开启内核路由转发功能 echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf sysctl -p # 5. 清空iptables防火墙策略 iptables -F iptables -t nat -F第二步:配置RS(rs1、rs2)网络及Web服务
RS无需配置VIP,仅需配置IP、指定网关(VS内网IP),并安装Web服务用于测试,两台RS配置步骤一致,仅IP不同。
# 1. 配置RS网卡(仅主机模式) vim /etc/NetworkManager/system-connections/eth0.nmconnection [connection] id=eth0 type=ethernet interface-name=eth0 [ipv4] method=manual address1=192.168.0.10/24,192.168.0.100 # IP+网关(网关必须是VS内网IP) # 2. 重启网络连接 nmcli connection up eth0 # 3. 安装Web服务 yum install httpd -y # rs1创建测试页面 echo "RS1 - 192.168.0.10" > /var/www/html/index.html # rs2创建测试页面 # echo "RS2 - 192.168.0.20" > /var/www/html/index.html # 4. 启动httpd服务并设置开机自启 systemctl start httpd systemctl enable httpd # 5. 测试RS能否ping通VS内网IP(192.168.0.10),确保通信正常 ping -c 3 192.168.0.10第三步:在VS(lvs)上配置LVS NAT模式调度策略
NAT模式调度策略与DR模式的核心区别的是:添加RS时指定-N参数(表示NAT模式),无需配置VIP到lo接口(VIP直接配置在eth0外网网卡)。
# 1. 安装ipvsadm工具 yum install ipvsadm -y # 2. 清除现有LVS策略 ipvsadm -C # 3. 添加集群服务 ipvsadm -A -t 172.25.254.100:80 -s rr # 4. 添加后端RS,指定NAT模式(-m表示NAT模式) ipvsadm -a -t 172.25.254.100:80 -r 192.168.0.10 -m ipvsadm -a -t 172.25.254.100:80 -r 192.168.0.20 -m # 5. 查看LVS策略,确认配置生效 ipvsadm -Ln # 正常输出应包含:TCP 172.25.254.100:80 rr,及两台RS的信息(Forward为Masq,即NAT模式) # 6. 保存策略,避免重启失效 ipvsadm-save > /etc/sysconfig/ipvsadm # 7. 设置ipvsadm开机自启,确保重启后策略生效 systemctl enable --now ipvsadm.service第四步:测试NAT模式LVS集群效果
在测试机client上执行循环访问命令
for N in {1..10};do curl 172.25.254.100;done结果
若测试失败,优先检查RS网关是否指向VS内网IP、VS内核转发是否开启、防火墙是否清空。
以下实验是在DR模式下进行的
5.4 利用火墙标记解决轮询错误
以http和https为例,当我们在RS中同时开放80和443端口,那么默认控制是分开轮询的,这样我们就出现了一个轮询错乱的问题,当我第一次访问80被轮询到RS1后下次访问443仍然可能会被轮询到RS1上,因此我们需要解决这个问题
1.在rs主机中同时开启http和https两种协议
dnf install mod_ssl -y systemctl restart httpd systemctl restart httpd2.在VS调度器中中添加https的轮询策略
ipvsadm -A -t 192.168.0.200:80 -s rr ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.20 -g ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.10 -g ipvsadm -a -t 192.168.0.200:443 -r 192.168.0.10:443 -g ipvsadm -a -t 192.168.0.200:443 -r 192.168.0.20:443 -g 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:4433.使用客户端轮询错误展示
curl 192.168.0.200;curl -k https://192.168.0.200 RS2 - 192.168.0.20 RS2 - 192.168.0.204.解决方案:使用火墙标记访问vip的80和443的所有数据包,设定标记为6666,然后对此标记进行负载(在vS调度器)
ptables -t mangle -A PREROUTING -d 192.168.0.200 -p tcp -m multiport --dports 80,443 -j MARK --set-mark 6666 ipvsadm -A -f 6666 -s rr ipvsadm -a -f 6666 -r 192.168.0.10 -g ipvsadm -a -f 6666 -r 192.168.0.20 -g#测试:在客户端
5.5.lvs持久链接
在我们客户上网过程中有很多情况下需要和服务器进行交互,客户需要提交响应信息给服务器,如果单纯的进行调度会导致客户填写的表单丢失,为了解决这个问题我们可以用sh算法,但是sh算法比较简单粗暴,可能会导致调度失衡
解决方案
在进行调度时,不管用什么算法,只要相同源过来的数据包我们就把他的访问记录在内存中,也就是把这个源的主机调度到了那个RS上
如果在短期(默认360S)内同源再来访问我仍然按照内存中记录的调度信息,把这个源的访问还调度到同一台RS上。
如果过了比较长的时间(默认最长时间360s)同源访问再次来访,那么就会被调度到其他的RS上
在VS调度器 ipvsadm -A -f 6666 -s rr -p 1 ipvsadm -Ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn FWM 6666 rr persistent 1 -> 192.168.0.10:0 Route 1 0 0 -> 192.168.0.20:0 使用客户端 curl 192.168.0.200 RS1 - 192.168.0.10 curl 192.168.0.200 RS1 - 192.168.0.10 在VS调度器 watch -n 1 ipvsadm -Lnc IPVS connection entries pro expire state source virtual destination TCP 01:56 FIN_WAIT 172.25.254.99:42420 192.168.0.200:80 192.168.0.20:80 IP 00:57 ASSURED 172.25.254.99:0 0.0.26.10:0 192.168.0.20:0 TCP 01:54 FIN_WAIT 172.25.254.99:46216 192.168.0.200:80 192.168.0.20:80 TCP 01:55 FIN_WAIT 172.25.254.99:46222 192.168.0.200:80 192.168.0.20:80