什么是集群Cluster
集群就是把多台独立的物理服务器,通过网络组合在一起,对外表现为一个整体系统,统一对外提供服务。主要用来解决三大问题:分担访问压力、规避服务器单点故障、集中算力完成海量计算任务。
集群三大分类
1、LB 负载均衡集群
多台后端服务器共同承接用户请求,流量被拆分分发到各个节点,单台机器只承载部分访问量,以此分摊并发压力。
2、HA 高可用集群
核心目的:消除单点故障(SPOF)。
- MTBF:设备正常不间断运行的平均时长,数值越大稳定性越好
- MTTR:服务故障之后,修复恢复运行的平均耗时,耗时越短业务影响越小
- 可用性计算公式:可用性 = MTBF / (MTBF + MTTR),取值区间 0~1。业界常用 99%、99.9%、99.99%、99.999% 这类标准衡量服务可靠程度
- SLA 服务等级协议:服务商和使用者约定好的服务质量标准。在既定成本下约定服务可用指标,一旦达不到标准需要履行对应的赔付规则,运维的核心工作就是保障业务达标 SLA。 停机分为计划内维护停机、意外故障停机,运维重点管控突发的非计划停机事故。
3、HPC 高性能计算集群
整合多台服务器的运算能力,处理大规模、高难度的海量运算任务,多用于科研、气象模拟、军工测算等领域,属于国家关键算力资源。
LVS 作用
依托内核 ipvs 模块工作,调度服务器 VS 依据数据包目的 IP、通信协议、端口,搭配选定的调度算法,将用户请求转发分配给后端真实业务服务器 RS。
LVS 四种工作模式
1、NAT 模式
原理属于多目标地址 DNAT 转换,改写数据包目的 IP 与端口,将 VIP 替换为后端 RS 的内网 RIP 完成转发。
- RS 内网 IP 和调度器 IP 处于同一网段,后端服务器网关必须指向调度器内网地址
- 用户请求、客户端回包全部流经调度器,调度节点容易形成性能瓶颈
- 支持端口修改映射;调度主机必须是 Linux 系统,后端服务器系统无限制 工作流程:
- 客户端发起请求,报文携带本机 IP、访问 VIP、目标端口
- VS 做 DNAT 转换,把报文目的 VIP 修改为对应 RS 的 RIP
- RS 处理业务并返回数据,报文源地址为自身 RIP,目标为客户端 IP
- 响应数据经过 VS 时,将源地址由 RIP 改回 VIP
- 封装完成的数据包传回客户端 补充:ipvs 挂载在防火墙 PREROUTING 与 INPUT 链中间,自行编写 PREROUTING 防火墙规则会干扰 LVS 转发,部署时建议清空 iptables 规则。

2、DR 直接路由(官方默认,生产最常用)
仅修改数据二层 MAC 地址完成转发,数据包 IP 头部(源 IP、目的 IP、端口)全程不会改动。调度器修改数据帧的目标 MAC 为选定 RS 的网卡 MAC,RS 处理请求后,响应数据直接发送给客户端,无需经过调度器,所以 VS 与所有 RS 节点都需要绑定 VIP 地址。 工作流程:
- 客户端发出数据帧:IP 为客户端 IP 访问 VIP,二层 MAC 为本机 MAC、VS 网卡 MAC
- VS 只替换二层目标 MAC 为对应 RS 硬件 MAC,IP 数据保持原样转发
- RS 接收报文处理业务,以 VIP 作为源地址,直接路由返回数据给客户端

3、TUN 隧道模式(了解即可)
原始 IP 报文完整保留,在原有报文外层再新增一层 IP 头部封装传输。外层 IP 以调度器 IP 为源、RS 内网 IP 为目标;后端解析外层报文处理业务,回复报文直接经由 VIP 回传给客户端,支持跨网段、跨机房部署。 工作流程:
- 客户端发送原始请求报文:源 IP 客户端、目的 IP VIP
- VS 外层封装 IP 头(源 DIP、目的 RIP),封装报文转发至 RS
- RS 剥离外层头部处理请求,响应报文直接回送客户端

4、FULLNAT 模式(课外了解)
同时修改报文源 IP 和目的 IP:客户端 IP 改为调度器 IP,访问 VIP 替换为后端 RIP。
- VIP 一般为公网地址,调度器、后端内网 IP 可处于不同网段,RS 网关无需指向调度器
- RS 收到的请求源地址是调度器 IP,回复数据先发给 VS,再由 VS 转发给客户端
- 上下行流量都经过调度节点,原生自带端口映射能力

LVS 调度算法
按照是否采集后端服务器实时负载,划分静态、动态两类;动态算法会计算节点负载开销值,优先分配流量给开销更低的服务器。
静态算法(固定规则分发,不检测实时负载)
- RR 轮询:请求轮流分配给所有后端节点,服务器硬件配置不一致时不推荐使用
- WRR 加权轮询:根据服务器性能配置权重,硬件性能越强权重越高,分到的请求数量更多
- SH 源地址哈希:同一客户端 IP 的请求永久分配至首次匹配的服务器,实现会话保持效果
- DH 目标地址哈希:访问同一个目标地址的请求固定下发同一台 RS,多用于运营商缓存代理服务
动态算法(结合实时连接负载分配流量)
- LC 最少连接:负载开销 = 活跃连接数 ×256 + 空闲连接数
- WLC 加权最少连接(LVS 默认算法):开销 = (活跃连接数 ×256 + 空闲连接数) ÷ 服务器权重
- SED 最短期望延迟:高权重机器优先接收新建连接,权重差距大时高权重节点会承接大量初始请求
- NQ 永不排队:首轮请求均匀分配,后续流量依照 SED 规则调度
- LBLC 本地最少连接:动态化的目标哈希算法,适配正向代理业务
- LBLCR 带复制的 LBLC:优化原生 LBLC 负载不均衡问题,可将高负载节点流量分流至空闲服务器
内核 4.15 新增两种调度算法
- FO 加权故障溢出:常用于灰度发布。遍历后端节点列表,选择无过载标记、权重最高的服务器分发流量;标记过载的主机不再接入新连接。
- OVF 溢出连接调度:优先给高权重节点分配连接,当其活跃连接数量等于自身权重值后,自动切换下一台合格节点。 可用服务器条件:无过载标记、当前活跃连接数小于权重、权重不为 0。
lvs的多端口轮询问题解决方案
环境配置:

route路由
bash
[root@base ~]# vmset.sh eth1 192.168.0.100 route noroute
成功删除连接 "eth1" (45442c56-377e-4cf9-bfb0-a180b32d5db2)。
连接 "eth1" (4305eacb-402b-4eb6-ad0a-c3ca3096a31e) 已成功添加。
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/5)
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:d4:23:50 brd ff:ff:ff:ff:ff:ff
altname enp19s0
altname ens224
inet 192.168.0.100/24 brd 192.168.0.255 scope global noprefixroute eth1
valid_lft forever preferred_lft forever
inet6 fe80::472f:6377:9b91:fbd3/64 scope link tentative noprefixroute
valid_lft forever preferred_lft forever
route
[root@base ~]# vmset.sh eth0 172.25.254.100 route
连接 "eth0" (5b735a59-482c-4537-8960-adec233fc21f) 已成功添加。
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/7)
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:d4:23:46 brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname ens160
inet 172.25.254.100/24 brd 172.25.254.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::cf58:3175:4375:ff6b/64 scope link tentative noprefixroute
valid_lft forever preferred_lft forever
route
[root@router ~]# dnf install ipvsadm -y
[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
[root@router ~]# echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf
[root@router ~]# sysctl -p
net.ipv4.ip_forward = 1
Lobster AI
vsnode调度器
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]
address1=192.168.0.50
gateway=192.168.0.100
method=manual
[ipv6]
addr-gen-mode=default
method=auto
[proxy]
[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]
address1=127.0.0.1/8
address2=192.168.0.200/32
method=manual
[ipv6]
addr-gen-mode=default
method=auto
[proxy]
[root@RS1 system-connections]# nmcli connection reload
[root@base system-connections]# chmod 600 eth0.nmconnection
[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.200 0.0.0.0 UG 100 0 0 eth0
127.0.0.0 0.0.0.0 255.0.0.0 U 30 0 0 lo
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.100/32 scope global lo
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:e9:03:89 brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname ens160
inet 192.168.0.50/24 brd 192.168.0.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::5337:ae2c:d589:1a21/64 scope link noprefixroute
valid_lft forever preferred_lft forever
client客户端
bash
[root@client ~]# vmset.sh eth0 172.25.254.99 client norouter
[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@base ~]# vim /etc/NetworkManager/system-connections/eth0.nmconnection
[root@base ~]# nmcli connection reload
[root@base ~]# nmcli connection up eth0
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/6)
[root@base ~]# 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 102 0 0 eth0
172.25.254.0 0.0.0.0 255.255.255.0 U 102 0 0 eth0
rs1和rs2后端真实服务器
bash
# rs1和rs2配置相同
[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
[ipv6]
addr-gen-mode=default
method=auto
[proxy]
[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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:d3:c0:b0 brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname ens160
inet 192.168.0.10/24 brd 192.168.0.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::594c:53b2:c4d:da94/64 scope link noprefixroute
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
Lobster AI
rs1和rs2后端真实服务器
bash
# rs1和rs2配置相同
[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
[ipv6]
addr-gen-mode=default
method=auto
[proxy]
[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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:d3:c0:b0 brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname ens160
inet 192.168.0.10/24 brd 192.168.0.255 scope global noprefixroute eth0
valid_lft forever preferred_lft forever
inet6 fe80::594c:53b2:c4d:da94/64 scope link noprefixroute
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
测试

利用火墙标记解决轮询错误
bash
#在RS1和RS2中开启https
[root@RS1 ~]# dnf install httpd
[root@RS1 ~]# systemctl restart httpd
[root@RS2 ~]# dnf install httpd
[root@RS2 ~]# systemctl restart httpd
#在vsnode中添加https的轮询策略
[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.20 -g
[root@vsnode ~]# ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.10 -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
轮询错误展示

解决方案:使用火墙标记访问vip的80和443的所有数据包,设定标记为6666,然后对此标记进行负载
bash
[root@vsnode ~]# ipvsadm -C
[root@vsnode ~]# iptables -t mangle -A PREROUTING -d 192.168.0.200 -p tcp -m multiport --dports 80,443 -j MARK --set-mark 6666
[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

利用持久连接实现会话粘滞
bash
[root@vsnode ~]# ipvsadm -D -f 6666
[root@vsnode ~]# ipvsadm -A -f 6666 -s rr -p 1
[root@vsnode ~]# ipvsadm -a -f 6666 -r 192.168.0.10 -g
[root@vsnode ~]# ipvsadm -a -f 6666 -r 192.168.0.20 -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
FWM 6666 rr persistent 1
-> 192.168.0.10:0 Route 1 0 0
-> 192.168.0.20:0 Route 1 0 0
