一、lvs(Linux virtual server)运行原理
1.1lvs简介
LVS:Linux Virtual Server
,负载调度器,内核集成,章文嵩,阿里的四层
SLB(Server LoadBalance)
是基
于
LVS+keepalived
实现
LVS
官网
:
http://www.linuxvirtualserver.org/
LVS
相关术语
VS: Virtual Server
,负责调度
RS:RealServer
,负责真正提供服务
1.2lvs集群的类型
lvs-nat
:
修改请求报文的目标
IP,
多目标
IP
的
DNAT
lvs-dr
:
操纵封装新的
MAC
地址
lvs-tun:
在原请求IP
报文之外新加一个
IP
首部
lvs-fullnat:修改请求报文的源和目标
IP
1.2.1nat模式
Ivs-nat:
·本质是多目标
IP
的
DNAT
,通过将请求报文中的目标地址和目标端口修改为某挑出的
RS
的
RIP
和
PORT
实现转发
·RIP
和
DIP
应在同一个
IP
网络,且应使用私网地址
;RS
的网关要指向
DIP
·请求报文和响应报文都必须经由
Director
转发,
Director
易于成为系统瓶颈
·支持端口映射,可修改请求报文的目标
PORT
·VS
必须是
Linux
系统,
RS
可以是任意
OS
系统
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的调度机容易阻塞
客户请求到达vip后进入PREROUTING,在没有ipvs的时候因该进入本机INPUT,当IPVS存在后访问请求在通过PREROUTING后被ipvs结果并作nat转发
pvs
的作用点是在
PREROUTING
和
INPUT
链之间,所以如果在
prerouting
中设定规则会干扰
ipvs
的工作。所以在做lvs
时要把
iptables
的火墙策略全清理掉。
1.2.2DR模式
DR
:
Direct Routing
,直接路由,
LVS
默认模式
,
应用最广泛
,
通过为请求报文重新封装一个
MAC
首部进行 转发,源MAC
是
DIP
所在的接口的
MAC
,目标
MAC
是某挑选出的
RS
的
RIP
所在接口的
MAC
地址;源 IP/PORT,以及目标
IP/PORT
均保持不变。
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
1.2.3DR模式的特点
1.Director
和各
RS
都配置有
VIP
2.
确保前端路由器将目标
IP
为
VIP
的请求报文发往
Director
3.
在前端网关做静态绑定
VIP
和
Director
的
MAC
地址
二、lvs的调度算法
2.1lvs调度算法类型
ipvs scheduler
:根据其调度时是否考虑各
RS
当前的负载状态被分为两种:静态方法和动态方法
·静态方法:仅根据算法本身进行调度,不考虑
RS
的负载情况
·动态方法:主要根据每
RS
当前的负载状态及调度算法进行调度
Overhead=value
较小的
RS
将被调度
2.1.1lvs静态调度算法
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
,典型使用场景是正向代理缓存场景中的负载均衡,如:宽带运营商
2.1.2lvs动态调度算法
主要根据
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
三、环境配置(DR模式)
五台rhel9的克隆机
3.1
【lvs】两个网卡(NAT和仅主机模式)
vmset.sh eth0 172.25.254.100 lvs.lee.org
vmset.sh eth1 192.168.0.10 lvs.lee.org
lvs中要去打开内核路由功能,实现网络互联
vim /etc/sysysctl.conf中添加net.ipv4.ip_forward=1
确认打开
【webserver1】仅主机模式
vmset.sh eth0 192.168.0.10 webserver1.lee.org
下载并启动httpd
在/etc/NetworkManager/system-connections/eth0.nmconnection 中查看是否一致并查看网关
【webserver2】仅主机模式
vmset.sh eth0 192.168.0.20 webserver2.lee.org
下载并启动httpd
在/etc/NetworkManager/system-connections/eth0.nmconnection 中查看是否一致并查看网关
测试:
3.2
【client】配置
vmset.sh eth0 172.25.254.200 client.lee.org
【route】配置 双网卡(仅主机和NAT)
vmset.sh eth0 172.25.255.100
vmset.sh eth1 192.168.0.100
【webserver1】
【webserver2】
【lvs】
删除ip
启动eth1
查看网关
测试:
四、防火墙标签解决轮询错误
4.1防火墙标记解决轮询调度问题
[root@lvs ~]# ipvsadm -A -f 6666 -s rr
[root@lvs ~]# ipvsadm -a -f 6666 -r 192.168.0.101 -g
[root@lvs ~]# ipvsadm -a -f 6666 -r 192.168.0.102 -g
测试:
[root@client ~]# curl http://192.168.0.200;curl -k https://192.168.0.200
web1 - 192.168.0.10
web1 - 192.168.0.10
4.2lvs持久链接
在我们客户上网过程中有很多情况下需要和服务器进行交互,客户需要提交响应信息给服务器,如果单 纯的进行调度会导致客户填写的表单丢失,为了解决这个问题我们可以用sh
算法,但是
sh
算法比较简单 粗暴,可能会导致调度失衡
解决方法
[root@LVS ~]# iptables -t mangle -A PREROUTING -d 192.168.0.200 -p tcp -m multiport --dports 80,443 -j MARK --set-mark 66
[root@client ~]# curl 192.168.0.200;curl -k https://192.168.0.200
web2 - 192.168.0.20
web1 - 192.168.0.10
[root@client ~]# curl -k https://192.168.0.200
web2 - 192.168.0.20
[root@client ~]# curl -k https://192.168.0.200
web1 - 192.168.0.10
[root@client ~]# curl -k https://192.168.0.200
web2 - 192.168.0.20
[root@client ~]# curl -k https://192.168.0.200
web1 - 192.168.0.10