云原生高阶第一次作业
LVS项目知识点总结
一、什么是集群
集群(Cluster) 是一组相互独立的计算机(节点)通过高速网络连接,协同工作并对外表现为一个单一的整体系统。计算机集群简称集群,是一种计算机系统。
集群的核心思想是:将多台普通服务器组合起来,提供超越单台服务器性能的计算能力、更高的可用性和更好的可扩展性。
直到Linux集群的出现,集群的概念才得以广为传播。
二、集群分类
集群系统主要分为以下三大类:
1. 负载均衡集群(Load Balancing Cluster)
目的:提供和节点个数成正比的负载能力,将大量并发请求分发到后端多台服务器上处理。
特点:通过一个或多个前端负载均衡器将工作负载分发到后端的一组服务器上,从而达到整个系统的高性能和高可用性。
适用场景:大访问量的Web服务、HTTP服务等。
代表技术:LVS(Linux Virtual Server)、Nginx、HAProxy。
2. 高可用集群(High Availability Cluster,HA集群)
目的:提供冗余的容错备份,确保服务不间断。
特点:通过主备切换、故障转移等机制避免单点故障。
适用场景:数据库服务、关键业务系统等需要7×24小时不间断运行的服务。
3. 高性能计算集群(High Performance Computing Cluster,HPC集群)
目的:将计算任务拆分成多个子任务并行处理,缩短整体计算时间。
特点:通过并行计算技术处理大规模计算问题。
适用场景:科学计算、大数据处理、气象预测等。
三者关系:这三者相辅相成。负载均衡集群往往也具有一定的高可用性特点;高可用集群既适用于静态数据服务也适用于动态数据服务。
三、LVS的作用
LVS(Linux Virtual Server,Linux虚拟服务器) 是由章文嵩博士于1998年创建的开源负载均衡软件项目。
核心作用
-
四层负载均衡:LVS工作在OSI模型的第四层(传输层),支持TCP/UDP协议的负载均衡。
-
高并发处理:LVS工作在内核空间中,具有极高的并发处理能力和极低的资源消耗。
-
高可用性:通过集群技术实现高可用、可伸缩的网络服务,如www服务、cache服务、DNS服务、FTP服务、mail服务等。
-
透明性:LVS架构对用户是透明的,用户只能看见一台作为负载均衡器的虚拟服务器(Virtual Server),而看不到提供服务的真实服务器群。
架构组成
LVS集群从逻辑上可分为三层:
| 层级 | 组件 | 作用 |
|---|---|---|
| 调度层 | Director Server(负载调度器) | 集群对外的前端机,负责将客户请求发送到后端服务器执行 |
| 服务器集群层 | Real Server(真实服务器) | 实际提供服务的服务器节点 |
| 共享存储层 | Shared Storage | 为RS提供共享数据存储 |
四、LVS的4种模式及原理
LVS共有四种工作模式:NAT模式、DR模式、TUN模式、FULLNAT模式。
模式一:NAT模式(Network Address Translation)
原理概述:
NAT模式通过修改数据包的目标IP地址和源IP地址来实现流量转发。
详细流程:
客户端 → Director(VIP)→ 修改目标IP为RS的RIP → RS处理 → 返回Director → 修改源IP为VIP → 客户端
-
客户端发送请求到VIP(虚拟IP),Director接收请求
-
Director根据调度算法选择一台Real Server
-
Director将请求报文的目标IP地址(VIP)改为选定RS的RIP地址
-
RS处理请求后,将响应返回给Director
-
Director将响应报文的源IP地址改为VIP,返回给客户端
架构特点:
-
RS应使用私有地址,各RS的网关必须指向DIP
-
请求和响应报文都必须经过Director
-
配置简单,是所有模式中最容易配置的
优缺点:
| 优点 | 缺点 |
|---|---|
| 配置简单 | 性能较低,Director可能成为瓶颈 |
| 支持端口映射 | 请求和响应都经过Director,带宽压力大 |
| RS可以使用任何OS | 不适合大流量场景 |
模式二:DR模式(Direct Routing,直接路由)
原理概述:
DR模式不修改IP报文,而是通过修改数据帧的目标MAC地址将请求转发给Real Server。
详细流程:
客户端 → Director(VIP)→ 修改目标MAC为RS的MAC → RS(配置VIP)→ 直接回复客户端
-
Client发送请求到LVS的VIP上,Director接收请求
-
Director根据调度算法选择一台Real Server
-
Director不修改目标IP地址和目标端口,也不封装IP报文
-
Director将请求报文的数据帧的目标MAC地址改为所选RS的MAC地址
-
修改后的数据帧在服务器组的局域网上发送
-
RS接收到包后,直接把结果返回给客户端,不经过Director
关键配置:
-
RS需要在环回接口(lo)上配置VIP,但不响应VIP的ARP请求(需做ARP抑制)
-
Director和RS必须在同一物理网络(同一VLAN)中
优缺点:
| 优点 | 缺点 |
|---|---|
| 性能最高,响应不经过Director | Director和RS必须在同一网段 |
| 适合大流量场景 | RS需要配置VIP和ARP抑制 |
| 没有IP隧道开销 | 不支持端口映射 |
模式三:TUN模式(IP Tunneling,IP隧道)
原理概述:
TUN模式通过IP隧道技术,将请求报文封装在另一个IP报文中发送给Real Server。
详细流程:
客户端 → Director(VIP)→ IP隧道封装 → RS(解封装,确认有VIP)→ 直接回复客户端
-
客户端将访问VIP的报文发送给LVS服务器
-
LVS服务器将请求报文重新封装(在原有IP包头外加上新的IP隧道包头),发送给后端真实服务器
-
后端真实服务器解封IP隧道,确认自身有VIP后进行请求处理
-
RS处理完成后,直接把响应包通过自己的外网地址发送给客户端,不经过Director
IP隧道技术:将一个完整的IP报文封装成另一个新IP报文的数据部分。
架构特点:
-
Director和RS可以不在同一网络中,只要两者能够通过IP Tunnel相连即可
-
RS需要有公网IP地址
-
减少了Director对公网IP地址的消耗
优缺点:
| 优点 | 缺点 |
|---|---|
| Director和RS可以跨网段 | 需要处理IP隧道封装和解封装的开销 |
| RS直接响应客户端 | 效率不如DR模式 |
| 适合地理分布的集群 | 配置较复杂 |
模式四:FULLNAT模式
原理概述:
FULLNAT模式是NAT模式的增强版,同时对源IP和目标IP进行转换。
与NAT模式的区别:
| 对比项 | NAT模式 | FULLNAT模式 |
|---|---|---|
| 转换内容 | 仅转换目标IP | 同时转换源IP和目标IP |
| RS看到的来源 | 客户端真实IP | Director的Local Address |
| 跨VLAN支持 | 不支持 | 支持 |
| 部署限制 | RS网关必须指向DIP | 无VLAN限制 |
核心作用:
FULLNAT主要解决了LVS和RS跨VLAN的问题,LVS和RS不再有VLAN的从属关系,可以做到多个LVS对应多个RS,从而解决水平扩容问题。
TOA(TCP Option Address)机制:
由于FULLNAT模式下RS看到的是Director的IP而非客户端真实IP,需要通过TOA模块在TCP option中插入客户端真实IP信息。
四种模式对比总结
| 特性 | NAT | DR | TUN | FULLNAT |
|---|---|---|---|---|
| 修改IP | 是 | 否 | 否(封装) | 是(源+目) |
| 修改MAC | 否 | 是 | 否 | 否 |
| 响应路径 | 经过Director | 直接返回 | 直接返回 | 经过Director |
| RS与Director网段 | 可不同 | 必须相同 | 可不同 | 可不同 |
| 性能 | 低 | 最高 | 中 | 中 |
| 端口映射 | 支持 | 不支持 | 不支持 | 支持 |
| 配置复杂度 | 简单 | 中等 | 复杂 | 中等 |
五、LVS的13种调度算法
LVS支持多种调度算法,管理员可以根据实际需求灵活选择。以下是LVS的13种调度算法:
静态调度算法(不关心后端服务器的实时负载)
1. 轮询调度(Round Robin,RR)
以轮询方式依次将请求调度到不同的服务器,即每次调度执行 i = (i + 1) mod n。优点是无状态、简洁。
2. 加权轮询调度(Weighted Round Robin,WRR)
根据真实服务器的不同处理能力来调度访问请求,处理能力强的服务器能处理更多的访问流量。
3. 目标地址散列调度(Destination Hashing,DH)
根据请求的目标IP地址进行散列计算,将请求分配给对应的服务器。
4. 源地址散列调度(Source Hashing,SH)
根据请求的源IP地址进行散列计算,将同一源IP的请求始终分配给同一台服务器。
动态调度算法(根据后端服务器的实时负载进行调整)
5. 最少连接调度(Least Connections,LC)
动态地将网络请求调度到当前已建立连接数最少的服务器上。IPVS表存储了所有活动的连接。
6. 加权最少连接调度(Weighted Least Connections,WLC)
最少连接调度的超集,各个服务器用相应的权值表示其处理性能。
计算公式:(active*256 + inactive)/ weight
7. 基于局部性的最少连接(Locality-Based Least Connections,LBLC)
针对目标IP地址的负载均衡,主要用于Cache集群。
8. 带复制的基于局部性的最少连接(Locality-Based Least Connections with Replication,LBLCR)
LBLC的改进版,维护一个目标IP到一组服务器的映射。
9. 最短期望延迟调度(Shortest Expected Delay,SED)
基于WLC算法,考虑了服务器的当前连接数和处理能力。
10. 最少队列调度(Never Queue,NQ)
SED的改进版,如果有空闲服务器则直接分配,无需等待。
11.故障转移调度 (FQ)
根据服务器权重值进行调度,权重最高的服务器优先接收所有请求,直到该服务器达到其配置的连接上限,再将新请求转移到下一个权重最高的服务器。适用于主备模式的故障转移场景。
12.溢出连接调度(OVF)
根据服务器的连接上限(ipvsadm -a 中 -u 参数设定的上限值)进行调度。优先选择 当前连接数未达到上限 且 连接数/上限值 最小的服务器。当所有服务器均达到上限时,选择连接数最少的服务器。
13.一致性哈希调度(MH)
对请求的目标IP地址进行哈希计算,将具有相同目标IP的请求始终分配给同一台服务器。与 DH(目标地址散列)类似,但 MH 在服务器增减时重新映射的开销更小(类似一致性哈希环),更适合缓存集群的伸缩场景。
算法选择建议
| 场景 | 推荐算法 |
|---|---|
| 服务器性能相同,无状态服务 | RR(轮询) |
| 服务器性能不同 | WRR(加权轮询) |
| 长连接服务(如数据库) | LC或WLC(最少连接) |
| 需要会话保持 | SH(源地址散列) |
| Cache集群 | LBLC或LBLCR |
六、LVS的多端口轮询问题解决方案
问题描述
当Real Server同时开放多个端口(如HTTP的80端口和HTTPS的443端口)时,LVS默认对每个端口独立进行轮询调度。
这会导致一个问题:同一个用户的HTTP请求(80端口)被分配到RS1,而该用户的HTTPS请求(443端口)可能被分配到RS2。对于需要同时使用HTTP和HTTPS的应用(如购物网站的登录和支付),这会造成会话错乱。
解决方案:防火墙标记(Firewall Mark)
核心思想:使用iptables在mangle表中给访问同一VIP的不同端口的数据包打上相同的防火墙标记,LVS根据这个标记统一调度。
实现步骤:
步骤1:在Director上打防火墙标记
# 将访问VIP 192.168.1.100的80端口和443端口的数据包都打上标记6666 iptables -t mangle -A PREROUTING -d 192.168.1.100 -p tcp --dport 80 -j MARK --set-mark 6666 iptables -t mangle -A PREROUTING -d 192.168.1.100 -p tcp --dport 443 -j MARK --set-mark 6666
步骤2:LVS使用防火墙标记创建虚拟服务
# 使用标记6666创建虚拟服务,而不是使用端口 ipvsadm -A -f 6666 -s rr
步骤3:添加Real Server
# 添加RS1(同时服务80和443) ipvsadm -a -f 6666 -r 192.168.1.10 -g # 添加RS2(同时服务80和443) ipvsadm -a -f 6666 -r 192.168.1.11 -g
原理说明:
防火墙标记将不同端口的请求"绑定"在一起,LVS将它们视为同一个服务的不同入口。当与持久连接(-p参数)结合使用时,可确保来自同一客户端的连接在持久时间内路由到同一台主机。
七、LVS的会话粘滞解决方案
问题描述
HTTP是一种无状态协议,每次请求完成后连接会自动断开。在LVS负载均衡集群中,如果同一个用户的多次请求被分配到不同的Real Server,而各RS之间没有共享Session,用户就会遇到"登录状态丢失"的问题。
解决方案
方案一:持久连接(Persistent Connection)
原理:LVS在Director的内存中维护一个连接模板表(connection template),记录客户端IP与RS的映射关系。
工作流程:
-
当新客户端(源IP)首次访问VIP时,LVS根据调度算法将其分配到一台RS
-
LVS创建一个连接模板,记录该映射关系,超时时间为-p参数指定的值
-
在超时时间内,来自同一源IP的所有请求都直接使用该模板,转发到同一台RS
配置命令:
# 创建持久虚拟服务,超时时间为900秒 ipvsadm -A -t 192.168.1.100:80 -s rr -p 900 # 或使用-E选项修改已有服务 ipvsadm -E -t 192.168.1.100:80 -s rr -p 900
特点:
-
无论使用何种调度算法,持久连接都能保证同一源IP的请求定向到同一RS
-
持久连接功能无关算法,在所有调度算法之上工作
-
超时时间应根据业务需求设置(如300秒、900秒等)
方案二:源地址散列调度(Source Hashing,SH)
原理:根据请求的源IP地址进行散列计算,将同一源IP的请求始终分配给同一台服务器。
配置命令:
ipvsadm -A -t 192.168.1.100:80 -s sh
特点:
-
算法层面保证同一源IP始终分配到同一RS
-
但如果该RS故障,需要重新分配
方案三:共享Session存储(外部方案)
原理:将Session存储在独立的外部存储中(如Redis、Memcached、数据库),所有RS共享访问。
特点:
-
不依赖LVS的调度策略
-
需要额外的存储组件
-
适合大规模分布式系统
方案对比
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 持久连接 | 配置简单,LVS原生支持 | 可能导致负载不均 | 大多数场景(推荐) |
| SH算法 | 算法层面保证 | 服务器变化时需重新映射 | 简单场景 |
| 共享Session | 灵活,支持故障转移 | 需要额外组件 | 大规模分布式系统 |
八、实操:LVS-DR模式环境搭建
实验环境规划
| 主机 | 角色 | IP地址 | 说明 |
|---|---|---|---|
| Director | 负载调度器 | 192.168.14.111(DIP) 192.168.14.200(VIP) | LVS调度器 |
| RS1 | 真实服务器1 | 192.168.14.10(RIP) lo:0=192.168.14.200(VIP) | 提供Web服务 |
| RS2 | 真实服务器2 | 192.168.14.11(RIP) lo:0=192.168.14.200(VIP) | 提供Web服务 |
| Client | 客户端 | 192.168.14.100 | 测试访问 |
ipvsadm常用参数:
| 参数 | 说明 |
|---|---|
-A | 添加虚拟服务 |
-a | 添加真实服务器 |
-t | TCP协议 |
-s | 指定调度算法 |
-r | 指定Real Server |
-g | DR模式(直接路由) |
-m | NAT模式 |
-i | TUN模式(隧道) |
-p | 持久连接超时时间 |
九、准备工作
一台director,nat和仅主机模式
Director eth0 (NAT)
nmcli con add type ethernet ifname eth0 con-name static-eth0 ipv4.addresses 172.25.254.11/24 ipv4.gateway 172.25.254.2 ipv4.method manual
nmcli con up static-eth0
Director eth1 (仅主机,无网关)
nmcli con add type ethernet ifname eth1 con-name static-eth1 ipv4.addresses 192.168.0.11/24 ipv4.method manual
nmcli con up static-eth1
一台RS1,一台RS2
nmcli con add type ethernet ifname eth0 con-name static-rs1 ipv4.addresses 192.168.0.10/24 ipv4.method manual
nmcli con up static-rs1
RS2同上(把10改成20)
一台client
Client
nmcli con add type ethernet ifname eth0 con-name static-client ipv4.addresses 192.168.0.100/24 ipv4.method manual
nmcli con up static-client
利用持久连接实现会话粘滞
[root@director ~]# dnf install -y ipvsadm
[root@director ~]# ip addr add 192.168.0.200/32 dev eth1 label eth1:0
[root@rs1 ~]# ip addr add 192.168.0.200/32 dev lo label lo:0
[root@rs1 ~]# sysctl -w net.ipv4.conf.lo.arp_ignore=1
net.ipv4.conf.lo.arp_ignore = 1
[root@rs1 ~]# sysctl -w net.ipv4.conf.lo.arp_announce=2
net.ipv4.conf.lo.arp_announce = 2
[root@rs1 ~]# sysctl -w net.ipv4.conf.all.arp_ignore=1
net.ipv4.conf.all.arp_ignore = 1
[root@rs1 ~]# sysctl -w net.ipv4.conf.all.arp_announce=2
net.ipv4.conf.all.arp_announce = 2
RS2上同理
[root@rs1 ~]# dnf install -y httpd
[root@rs1 ~]# echo "RS1 (192.168.0.10)" > /var/www/html/index.html
[root@rs1 ~]# systemctl start httpd
RS2同理
client
[root@client ~]# for i in {1..10}; do curl 192.168.0.200; done
RS2 (192.168.0.20)
RS2 (192.168.0.20)
RS2 (192.168.0.20)
RS2 (192.168.0.20)
RS2 (192.168.0.20)
RS2 (192.168.0.20)
RS2 (192.168.0.20)
RS2 (192.168.0.20)
RS2 (192.168.0.20)
RS2 (192.168.0.20)

DR模式
[root@director ~]# ipvsadm -C
[root@director ~]# ipvsadm -A -t 192.168.0.200:80 -s rr
[root@director ~]# ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.10 -g -w 1
[root@director ~]# ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.20 -g -w 1
[root@director ~]# 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

利用火墙标记解决轮询错误
[root@director ~]# ipvsadm -C
[root@director ~]# iptables -t mangle -F
[root@director ~]# iptables -t mangle -A PREROUTING -d 192.168.0.200 -p tcp --dport 80 -j MARK --set-mark 8888
[root@director ~]# iptables -t mangle -A PREROUTING -d 192.168.0.200 -p tcp --dport 443 -j MARK --set-mark 8888
[root@director ~]# ipvsadm -A -f 8888 -s rr -p 900
[root@director ~]# ipvsadm -a -f 8888 -r 192.168.0.10 -g -w 1
[root@director ~]# ipvsadm -a -f 8888 -r 192.168.0.20 -g -w 1

NAT模式实现方法
[root@bogon ~]# cat /bin/vmset.sh
#!/bin/bash
# ============================================================
# 通用网络配置脚本 - vmset.sh
# 用法:
# vmset.sh <网卡名> <IP地址> <主机名> [网关|noroute]
# 示例:
# vmset.sh eth1 192.168.0.100 myserver # 自动使用 192.168.0.1 为网关
# vmset.sh eth1 192.168.0.100 myserver noroute # 不设置网关(无默认路由)
# vmset.sh eth1 192.168.0.100 myserver 192.168.0.254 # 指定网关
# ============================================================
# ---------- 参数检查 ----------
if [ $# -lt 3 ]; then
echo "错误:参数不足。"
echo "用法: $0 <网卡名> <IP地址> <主机名> [网关|noroute]"
exit 1
fi
INTERFACE="$1"
IP_ADDR="$2"
HOSTNAME="$3"
GATEWAY="$4" # 可能是IP、noroute 或为空
# ---------- 检查网卡是否存在 ----------
if ! ip link show "$INTERFACE" > /dev/null 2>&1; then
echo "错误:网卡 $INTERFACE 不存在!"
exit 2
fi
# ---------- 检查 NetworkManager 是否运行 ----------
if ! systemctl is-active --quiet NetworkManager; then
echo "警告:NetworkManager 未运行,正在启动..."
systemctl start NetworkManager
sleep 2
fi
# ---------- 处理连接配置 ----------
CON_NAME="$INTERFACE" # 连接名与网卡名一致,便于管理
# 检查连接是否存在,不存在则创建
if ! nmcli connection show "$CON_NAME" &> /dev/null; then
echo "连接 '$CON_NAME' 不存在,正在创建..."
nmcli connection add type ethernet ifname "$INTERFACE" con-name "$CON_NAME" || {
echo "错误:创建连接失败!"
exit 3
}
fi
# ---------- 根据网关参数设置 IP 配置 ----------
if [ -z "$GATEWAY" ]; then
# 未指定网关 → 自动使用网段 .1 作为网关(如 192.168.0.1)
# 自动从IP地址提取网段前缀(/24 是常见掩码,可根据需要调整)
BASE_IP=$(echo "$IP_ADDR" | cut -d '.' -f1-3)
GW="${BASE_IP}.1"
echo "未指定网关,自动使用 $GW"
nmcli connection modify "$CON_NAME" ipv4.method manual ipv4.addresses "$IP_ADDR/24" ipv4.gateway "$GW"
elif [ "$GATEWAY" == "noroute" ]; then
# 明确指定 noroute → 不设网关,禁止默认路由
echo "检测到 noroute,将不设置网关并禁止默认路由"
nmcli connection modify "$CON_NAME" ipv4.method manual ipv4.addresses "$IP_ADDR/24" ipv4.gateway "" ipv4.never-default yes
else
# 第四个参数为 IP 地址 → 作为网关
echo "使用指定网关 $GATEWAY"
nmcli connection modify "$CON_NAME" ipv4.method manual ipv4.addresses "$IP_ADDR/24" ipv4.gateway "$GATEWAY"
fi
# ---------- 激活连接 ----------
echo "正在激活连接 $CON_NAME ..."
nmcli connection up "$CON_NAME" || {
echo "错误:激活连接失败!"
exit 4
}
# ---------- 设置主机名 ----------
echo "设置主机名为 $HOSTNAME ..."
hostnamectl set-hostname "$HOSTNAME"
# ---------- 显示最终配置 ----------
echo "========== 配置完成 =========="
echo "网卡 : $INTERFACE"
echo "IP : $IP_ADDR/24"
if [ "$GATEWAY" == "noroute" ]; then
echo "网关 : 无(已禁止默认路由)"
elif [ -n "$GATEWAY" ]; then
echo "网关 : $GATEWAY"
else
echo "网关 : $GW (自动)"
fi
echo "主机名: $HOSTNAME"
echo "=============================="
# 验证IP是否生效
echo "当前 IP 配置:"
ip -4 addr show "$INTERFACE" | grep inet
[root@bogon ~]#
实现sh命令的脚本如上
vsnode
[root@vsnode ~]# vmset.sh eth0 172.25.254.100 vsnode
[root@vsnode ~]# vmset.sh eth1 192.168.0.100 vsnode noroute
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
[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
RS2同上
验证
[root@vsnode ~]# curl 192.168.0.10
RS1 - 192.168.0.10
[root@vsnode ~]# curl 192.168.0.20
RS2 - 192.168.0.20

这时候发现有点不太对,怎么找不到自己呢,原来没装httpd

也是直接over了,完工

喜欢主播的可以关注一手,主播不定期更新
更多推荐

所有评论(0)