LVS调度算法与具体实现(保姆级)

一、集群与分布式

   首先让我们来了解集群和分布式的概念:

集群:同一个业务系统,部署在多台服务器上,集群中,每一台服务器的访问内容没有差别,数据和代码都是一样的,有助于实现负载均衡。

分布式:一个业务被拆分成多个子业务,或者本身就是不同的业务,部署在多台服务器上。分布式中,每一台服务器实现的功能都是有差别的,数据和代码都是不一样的,分布式每台服务器加起来才是完整的业务。

对于大型网站,访问用户很多,实现一个集群,在前面部署一个负载均衡服务器,后面几台服务器完成同一个业务,如果有用户进行相应业务访问时,负载均衡服务器根据后端哪台服务器的负载情况,决定由哪一台去完成相应,如果那台服务器垮了,其他服务器还可以顶上来。分布式的每一个节点都完成不同的业务,如果一个节点垮了,那这个业务可能失败。

二、LVS(Linux Virtual Server)运行原理

LVS相关术语:

VS:virtual server,负责调度

RS:real server,真实提供服务的服务器

CIP:client ip,客户端的ip

VIP:virtual server外网的ip

DIP:director ip vs内网的ip

RIP:real server‘s ip

LVS集群类型:

lvs-nat:修改请求报文的目标ip,多目标ip的DNAT

lvs-dr:操纵封装新的mac地址

lvs-turn:在原请求ip报文之外新增一个ip首部

lvs-fullnat:修改请求报文的源和目标ip

nat模式的数据逻辑:

dr模式的数据逻辑:

三、LVS调度算法

1.lvs调度算法类型

ipvs scheduler:根据其调度时是否考虑RS当前的负载状态分为两种:静态方法和动态方法。

静态方法:仅根据算法本身调度,不考虑RS的负载情况

动态方法:主要根据RS当前负载状态和调度算法进行调度,Overhead=value较小的RS将优先调度

2.LVS静态调度算法

1、RR:roundrobin 轮询 RS分别被调度,当RS配置有差别时不推荐

2、WRR:Weighted RR,加权轮询根据RS的配置进行加权调度,性能差的RS被调度的次数少 3、SH:Source Hashing,实现session sticky,源IP地址hash;将来自于同一个IP地址的请求始终发往 第一次挑中的RS,从而实现会话绑定

4、DH:Destination Hashing;目标地址哈希,第一次轮询调度至RS,后续将发往同一个目标地址的请 求始终转发至第一次挑中的RS,典型使用场景是正向代理缓存场景中的负载均衡,如:宽带运营商

3.lvs动态调度算法

主要根据RS当前的负载状态及调度算法进行调度Overhead=value较小的RS会被调度

1、LC:least connections(最少链接发) 适用于长连接应用Overhead(负载值)=activeconns(活动链接数) x 256+inactiveconns(非活 动链接数)

2、WLC:Weighted LC(权重最少链接) 默认调度方法Overhead=(activeconns x 256+inactiveconns)/weight

3、SED:Shortest Expection Delay, 初始连接高权重优先Overhead=(activeconns+1+inactiveconns) x 256/weight 但是,当node1的权重为1,node2的权重为10,经过运算前几次的调度都会被node2承接

4、NQ:Never Queue,第一轮均匀分配,后续SED

5、LBLC:Locality-Based LC,动态的DH算法,使用场景:根据负载状态实现正向代理 6、LBLCR:LBLC with Replication,带复制功能的LBLC,解决LBLC负载不均衡问题,从负载重的复制 到负载轻的RS

四.LVS部署命令

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

2.NAT模式集群实验

  • 实验准备:
  • LVS:双网卡主机,开启内核路由功能,外网ip为172.25.254.100/24,内网ip为192.168.0.100/24
  • RS1:单网卡主机,只有一个ip,192.168.0.10/24
  • RS2:单网卡主机,只有一个ip,192.268.0.20/24

开启内核路由功能:

vim /etc/sysctl.conf
net.ipv4.ip forward=1
sysctl - a
net.ipv4.ip forward = 1

最后在curl上检测:

3.DR模式集群实验

  • 实验准备:
  • Client:nat模式,CIP为172.25.254.200,网关为172.25.254.100
  • Router:nat模式,VIP为172.25.254.100,仅主机模式,DIP为192.168.0.100,开启内核路由功能
  • LVS:仅主机模式,DIP为192.168.0.50,VIP为192.168.0.200,在回环上配置,网关为192.168.0.100
  • RS1:仅主机模式,RIP为192.168.0.10,VIP为192.168.0.200,在回环上配置
  • RS2:仅主机模式, RIP为192.168.0.20,VIP为192.168.0.200,在回环上配置

示意图如下:

准备一台母机,在/usr/bin/编写一个vmset.sh用于配置ip,vmset.sh脚本内容如下:

#!/bin/bash
rm -fr /etc/NetworkManager/system-connections/$1.nmconnection
cat > /etc/NetworkManager/system-connections/$1.nmconnection <<EOF
[connection]
id=$1
type=ethernet
interface-name=$1

[ipv4]
address1=$2/24,172.25.254.2
method=manual
dns=114.114.114.114;
EOF

chmod 600 /etc/NetworkManager/system-connections/$1.nmconnection
nmcli connection reload
nmcli connection up $1

hostnamectl hostname $3

cat > /etc/hosts <<EOF
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
$2	$3
EOF

写完之后不要忘记了给脚本一个可执行权限:

chmod +x /usr/bin/vmset.sh

之后清除历史命令保存并退出,维持母机一个纯净的实验环境

然后使用链接克隆克隆出五台主机,在client上使用脚本具体传参如下:

[root@client ~]# vmset.sh eth0 172.25.254.200 client.karl.org
连接已成功激活(D-Bus 活动路径:/org/freedesktop/NetworkManager/ActiveConnection/3)

 其中vmset.sh 中 $1是网卡名称,即ifname(填写你自己真实看到的网卡名称,$2(ip地址),$3(主机名)

如果你也想改成和我一样的网卡名称,可以用以下命令更新内核中的ifnames参数:

grubby --update-kernel ALL --args net.ifnames=0

写完之后别忘记了重启,最好在母机上就做好:

reboot

 以router路由器为例,添加第二块网络模式为仅主机模式的网卡:

打开wmware->右键router选择设置->添加->网络适配器->仅主机模式->确定(一定要点!!)

关于网段的规划也需要注意:

编辑->虚拟网络编辑器->VMnet1 仅主机>子网地址192.168.0.0->确定(一定要点!!)

                                    ->VMnet8 nat模式>子网地址172.25.254.0->确定(一定要点!!)

大功告成之后,根据我们规划好的ip从client到rs进行配置

这里在lvs,和两台real server上配置VIP的目的是:

  • 在Linux Virtual Server (LVS) 的 Direct Routing (DR) 模式中,配置虚拟IP地址(VIP)对于实现负载均衡和高可用性至关重要。在 DR 模式下,LVS 的主要组件包括 Director(调度器)和 Real Servers(真实服务器)。下面详细解释为什么需要在 LVS、RS1 和 RS2 上配置 VIP:
  • 1. **创建统一的入口点**:
  •    VIP 提供了一个统一的入口点,客户端只看到这个 VIP 地址,而不知道后端的真实服务器。这使得 LVS 能够透明地分发客户端请求到多个真实服务器,从而提高性能和可靠性。
  • 2. **负载均衡**:
  •    当客户端向 VIP 发起连接请求时,LVS 的调度器会根据预设的算法(如轮询、最少连接等)选择一个真实服务器并将请求转发过去。通过这种方式,负载可以在多个服务器之间均衡分配。
  • 3. **故障转移和高可用性**:
  •    在 DR 模式中,LVS 和所有 RS 都需要配置相同的 VIP。当某一台 RS 出现故障时,LVS 会检测到并停止向这台服务器发送请求,而不会影响到其他 RS 的正常服务。同时,如果 LVS 自身出现故障,通过心跳机制,VIP 可以被转移到另一个 LVS 实例上,保证服务的连续性。
  • 4. **隐藏真实服务器**:
  •    客户端只知道 VIP,而不直接与 RS 通信,这增加了系统的安全性,因为 RS 的实际 IP 地址对外界是隐藏的。
  • 5. **简化客户端配置**:
  •    对于客户端而言,只需要知道 VIP,不需要关心后端服务器的变动。这使得在扩展或缩减后端服务器数量时,客户端无需重新配置。
  • 6. **直接路由**:
  •    在 DR 模式中,数据包从 LVS 到 RS 的转发是通过 MAC 地址改写实现的,而不是通过 IP 重写。这意味着数据包在整个过程中保持原始 IP,提高了网络效率和性能。
  • 总之,配置 VIP 在 LVS 和 RS 上是 DR 模式下实现高效、可靠和安全的负载均衡的关键。通过 VIP,LVS 能够智能地管理后端服务器集群,同时对外提供一致的服务质量。

需要注意的是,在lvs,rs1,rs2上配置的VIP推荐用临时命令配置,且子网掩码为32

ip a a 192.168.0.200/32 dev lo

之后再在rs1,rs2上关闭VIP对外响应,也是临时的,重启失效

echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore 
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce 
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce 
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore

在路由器上开启主机内核通信功能

[root@router ~]# sysctl -a | grep ip_forward
net.ipv4.ip_forward = 0
net.ipv4.ip_forward_update_priority = 1
net.ipv4.ip_forward_use_pmtu = 0

使用vim命令,把net.ipv4.ip_forward = 1复制到/etc/sysctl.conf的最后一行:

vim /etc/sysctl.conf

改完之后刷新:

[root@router ~]# sysctl -p
net.ipv4.ip_forward = 1

可以看到此时内核路由通信功能已经开启

此时我们就可以在lvs上配置我们的ipvsadm策略了

下载ipvsadm,下载完不要启动,要不然更改的策略不会生效

dnf install ipvsadm -y

在我们两台rs上安装http服务并写入一些东西到默认发布目录,在真实的生产环境中,两台rs集群应当提供给客户的内容是一致的,在实验环境中为了效果明显,我们可以不同

dnf install httpd -y
[root@rs1 ~]# echo web1 - 192.168.0.10 > /var/www/html/index.html
[root@rs1 ~]# systemctl enable --now httpd
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service → /usr/lib/systemd/system/httpd.service.

输入好之后启动httpd服务,rs2上也是如此 

现在我们可以回到lvs负载调度器上配置我们的ipvsadm策略了

ipvsadm -A -t 192.168.0.200:80 -s wrr
ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.10:80 -g -w 1
ipvsadm -a -t 192.168.0.200:80 -r 192.168.0.20:80 -g -w 2

配置好之后查看下我们的策略:

[root@lvs ~]# 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   2      0          0 

最后在客户端上测试一下,模拟客户访问服务器的请求,由于wrr算法调度,会根据服务器的权重给定访问次数,可以看到效果如下:

[root@client ~]# for i in {1..10}
> do
> curl 192.168.0.200
> done
web1 - 192.168.0.10
web2 - 192.168.0.20
web2 - 192.168.0.20
web1 - 192.168.0.10
web2 - 192.168.0.20
web2 - 192.168.0.20
web1 - 192.168.0.10
web2 - 192.168.0.20
web2 - 192.168.0.20
web1 - 192.168.0.10

4.防火墙标签解决轮询错误

以http和https为例,当我们在RS中同时开放80和443端口,那么默认控制是分开轮询的,这样我们就出 现了一个轮询错乱的问题,当我第一次访问80被轮询到RS1后下次访问443仍然可能会被轮询到RS1上

在rs1和rs2上安装mod_ssl让apache支持https

yum install mod_ssl -y
systemctl restart httpd

在lvs中设置调度,因为我们要调度80和443两个端口所以我们需要设定两组策略

 ipvsadm -C
 ipvsadm -A -t 192.168.0.100:80 -s rr
 ipvsadm -A -t 192.168.0.100:443 -s rr
 ipvsadm -a -t 192.168.0.100:80 -r 192.168.0.101:80 -g
 ipvsadm -a -t 192.168.0.100:80 -r 192.168.0.102:80 -g
 ipvsadm -a -t 192.168.0.100:443 -r 192.168.0.102:80 -g
 ipvsadm -a -t 192.168.0.100:443 -r 192.168.0.101:80 -g

此时我们查看一下调度情况

[root@lvs ~]# 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.101:80             Route   1     0         0
 -> 192.168.0.102:80             Route   1     0         0
TCP 192.168.0.100:443 rr
 -> 192.168.0.101:443           Route   1     0         0
 -> 192.168.0.102:443           Route   1     0         0

测试一下:

[root@node10 ~]# curl http://192.168.0.100;curl -k https://192.168.0.100
RS1 server - 192.168.0.101 
RS1 server - 192.168.0.101

此时我们访问VIP后两次调度都到了RS1上,增大了RS1的负载,我们需要使用防火墙标签解决这个问题

清空一下之前的调度:

ipvsadm -C

在vs调度器中设定端口标签,把80和443视作一个整体

 iptables -t mangle -A PREROUTING -d 192.168.0.100 -p tcp -m multiport --dports 80,443 -j MARK --set-mark 66

设定调度规则

 ipvsadm -A -f 66 -s rr 
 ipvsadm -a -f 66 -r 192.168.0.10 -g 
 ipvsadm -a -f 66 -r 192.168.0.20 -g

我们现在来测试一下,看看会不会发生轮询错乱的问题:

[root@node10 ~]# curl -k https://192.168.0.100
RS2 server - 192.168.0.102
[root@node10 ~]# curl -k https://192.168.0.100;curl 192.168.0.100
RS1 server - 192.168.0.10
RS2 server - 192.168.0.20

5.lvs持久链接

在进行调度时,不管用什么算法,只要相同源过来的数据包我们就把他的访问记录在内存中,也就是把 这个源的主机调度到了那个RS上 如果在短期(默认360S)内同源再来访问我仍然按照内存中记录的调度信息,把这个源的访问还调度到 同一台RS上。 如果过了比较长的时间(默认最长时间360s)同源访问再次来访,那么就会被调度到其他的RS上

在lvs调度器中设定

 ipvsadm -E -f 66 -s rr -p [3000] 
 ipvsadm -LnC

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值