18 KiB
LVS
一:LVS 简介
1. 简介
LVS(Linux Virtual Server)即Linux虚拟服务器,是由章文嵩博士主导的开源负载均衡项目,目前LVS已经被集成到Linux内核模块中。LVS基于内核网络层工作,有着超强的并发处理能力,单台LVS可以承受上万的并发连接。LVS是基于4层的负载均衡软件,因此LVS在所有负载均衡软件中性能最强,稳定性最高,消耗CPU和内存少。LVS是工作在4层,所以它可以对应用层的所有协议作负载均衡,包括http、DNS、ftp等。
2. LVS 分层及组成
LVS 负载均衡分为3层:
- 第一层(Load Balancer),它负责负载均衡,有一台或多台调度器,是整个集群的总代理。它有两个网卡,一个网卡面向访问网站的客户端,一个网卡面向集群内部。负责将客户的请求发送到服务器上执行。
- 第二层(Server Array),这一层是真正执行客户请求的服务器,可以当做WEB服务器。
- 第三层(Shared Storage),它为服务器池提供一个共享的存储区,这样很容易使得服务器池拥有相同的内容,提供相同的服务。
3. 工作原理
- 用户请求的数据包到达负载均衡器的内核空间,首先经过的是内核的PREROUTING链
- 因为请求的数据包的目的地址一定是本机,然后将数据包送到INPUT链
- ipvs就工作在INPUT链上,ipvs利用ipvsadm定义的规则工作,ipvs对数据包进行检查,如果目的地址和端口不在规则里边,则将数据包送往用户空间
- 如果目的地址和端口在规则里边,则将数据包的目的地址和端口修改为后端真实服务器,然后将修改后的数据包送往POSTROUTING链
- 最后经过POSTROUTING链将数据包转发给后端服务器。
二:集群 Cluster
1. 概念
集群是为了解决某个特定问题将多台计算机组合起来形成的单个系统。
2. 常见类型
- LB:LoadBalancing(负载均衡)由多个主机组成,每个主机只承担一部分访问
- HA:High Availiablity(高可用)
- MTBF:Mean Time Between Failure 平均无故障时间,正常时间
- MTTR:Mean Time To Restoration( repair)平均恢复前时间,故障时间 A=MTBF/(MTBF+MTTR)
- SLA:Service level agreement(服务等级协议)
- SLA是在一定开销下为保障服务的性能和可用性,服 务提供商与用户间定义的一种双方认可的协定。
- HPC:High-performance computing(高性能计算)
3. LVS 集群类型
- **lvs-nat:**修改请求报文的目标
IP
,多目标的DNAT
- **lvs-dr:**操纵新封装的
MAC
地址 - **lvs-tun:**再远请求
IP
报文之外新加一个IP
首部 - **lvs-fullnat:**修改请求报文的源和目标
IP
三:分布式
1. 概念
分布式是将一个业务被拆成多个子业务或将本身就是不同的业务部署在多台服务器上。在分布式中,每一台服务器实现的功能是有差别的,数据和代码也是不一样的,分布式每台服务器功能加起来,才是完整的业务。
2. 集群和分布式的区别
集群是将同一个业务部署在多台服务器上,每一台服务器实现的功能没有差别,数据和代码都是一样的;分布式中每一台服务器实现的功能是有差别的,数据和代码也是不一样的,分布式每台服务器功能加起来,才是完整的业务。
分布式是以缩短单个任务的执行时间来提升效率的,而集群则是通过提高单位时间内执行的任务数来提升效率。
四:LVS 运行原理
1. nat 模式
概念
本质是多目标IP
的DNAT
,通过将请求报文中的目标地址和目标端口修改为某挑出的RS
的RIP
和PORT
实现转发。
RIP
和DIP
应在同一个IP
网络,且应使用私网地址;RS
的网关要指向DIP
。
请求报文和响应报文都必须经由Director转发,Director易于成为系统瓶颈
支持端口映射,可修改请求报文的目标`PORT`。
VS
必须是Linux
系统,RS
可以是任意OS
系统。
数据逻辑
- 客户端发送访问请求,请求数据包中含有请求来源(cip),访问目标地址(VIP)访问目标端口 (9000port)
- VS服务器接收到访问请求做DNAT把请求数据包中的目的地由VIP换成RS的RIP和相应端口
- RS1相应请求,发送响应数据包,包中的相应保温为数据来源(RIP1)响应目标(CIP)相应端口 (9000port)
- VS服务器接收到响应数据包,改变包中的数据来源(RIP1-->VIP),响应目标端口(9000-->80)
- VS服务器把修改过报文的响应数据包回传给客户端
- lvs的NAT模式接收和返回客户端数据包时都要经过lvs的调度机,所以lvs的调度机容易阻塞
2. DR 模式
概念
DR:Direct Routing,直接路由,LVS
默认模式,应用最广泛,通过为请求报文重新封装一个MAC首部进行 转发,源MAC
是DIP
所在的接口的MAC
,目标MAC
是某挑选出的RS
的RIP
所在接口的MAC
地址;源IP/PORT
,以及目标IP/PORT
均保持不变。
DR模式数据传输过程
- 客户端发送数据帧给
vs
调度主机帧中内容为客户端IP
+客户端的MAC
+VIP
+VIP
的MAC
VS
调度主机接收到数据帧后把帧中的VIP
的MAC
该为RS1
的MAC
,此时帧中的数据为客户端IP
+客户端 的MAC
+VIP
+RS1
的MAC
- RS1得到2中的数据包做出响应回传数据包,数据包中的内容为
VIP
+RS1
的MAC
+客户端IP
+客户端IP
的MAC
DR模式的特点
Director
和各RS
都配置有VIP
- 确保前端路由器将目标
IP
为VIP
的请求报文发往Director
- 在前端网关做静态绑定
VIP
和Director
的MAC
地址 RS
的RIP
可以使用私网地址,也可以是公网地址;RIP
与DIP
在同一IP
网络;RIP
的网关不能指向DIP
,以确保响应报文不会经由Director
RS
和Director
要在同一个物理网络- 请求报文要经由
Director
,但响应报文不经由Director
,而由RS
直接发往Client
- 不支持端口映射(端口不能修败)
RS
可使用大多数OS
系统
3. TUN 模式
概念
转发方式:不修改请求报文的IP首部(源IP为CIP,目标IP为VIP),而在原IP报文之外再封装一个IP首部 (源IP是DIP,目标IP是RIP),将报文发往挑选出的目标RS;RS直接响应给客户端(源IP是VIP,目标IP是CIP)。
TUN 模式传输数据过程
- 客户端发送请求数据包,包内有源IP+vip+dport
- 到达vs调度器后对客户端发送过来的数据包重新封装添加IP报文头,新添加的IP报文头中包含TUNSRCIP(DIP)+TUNDESTIP(RSIP1)并发送到RS1
- RS收到VS调度器发送过来的数据包做出响应,生成的响应报文中包含SRCIP(VIP)+DSTIP(CIP)+port,响应数据包通过网络直接回传给client
TUN 模式特点
- DIP, VIP, RIP都应该是公网地址
- RS的网关一般不能指向DIP
- 请求报文要经由Director,但响应不能经由Director
- 不支持端口映射
- RS的OS须支持隧道功能
4. LVS 类型总结
NAT模式 | TUN模式 | DR模式 | |
---|---|---|---|
RS操作系统 | 不限 | 支持隧道 | 禁用arp |
调度器和服务器网络 | 可跨网络 | 可跨网络 | 不可跨网络 |
调度服务器数量 | 少 | 多 | 多 |
RS服务器网关 | 指向调度器DIP | 指向路由 | 指向路由 |
- **lvs-nat与lvs-fullnat:**请求和响应报文都经由
Director
- lvs-nat:
RIP
的网关要指向DIP
- lvs-fullnat:
RIP
和DIP
未必在同一IP
网络,但要能通信 - **lvs-dr与lvs-tun:**请求报文要经由
Director
,但响应报文由RS
直接发往Client
- **lvs-dr:**通过封装新的
MAC
首部实现,通过MAC
网络转发 - **lvs-tun:**通过在原
IP
报文外封装新IP
头实现转发,支持远距离通信
五:LVS 调度算法
1. 调度算法类型
**ipvs scheduler:**根据其调度时是否考虑各RS
当前的负载状态被分为两种:静态方法和动态方法。
- 静态方法:仅根据算法本身进行调度,不考虑
RS
的负载情况 - 动态方法:主要根据每
RS
当前的负载状态及调度算法进行调度Overhead=value
较小的RS
将被调度
2. 静态调度算法
- RR:roundrobin 轮询 RS分别被调度,当RS配置有差别时不推荐
- WRR:Weighted RR,加权轮询根据RS的配置进行加权调度,性能差的RS被调度的次数少
- SH:Source Hashing,实现session sticky,源IP地址hash;将来自于同一个IP地址的请求始终发往 第一次挑中的RS,从而实现会话绑定
- DH:Destination Hashing;目标地址哈希,第一次轮询调度至RS,后续将发往同一个目标地址的请 求始终转发至第一次挑中的RS,典型使用场景是正向代理缓存场景中的负载均衡,如:宽带运营商
3. 动态调度算法
主要根据RS当前的负载状态及调度算法进行调度Overhead=value较小的RS会被调度。
- LC:least connections(最少链接发)适用于长连接应用Overhead(负载值)=activeconns(活动链接数) x 256+inactiveconns(非活 动链接数)
- WLC:Weighted LC(权重最少链接) 默认调度方法Overhead=(activeconns x256+inactiveconns)/weight
- 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
4. 新增调度算法
- FO(Weighted Fai Over)调度算法:常用作灰度发布。在FO算法中,遍历虚拟服务所关联的真实服务器链表,找到还未过载的且权重最高的真实服务器,进行调度当服务器承接大量链接,我们可以对此服务器进行过载标记,那么vs调度器就不会把链接调度到有过载标记的主机中。
- OVF(Overflow-connection)调度算法:基于真实服务器的活动连接数量和权重值实现。将新连接调度到权重值最高的真实服务器,直到其活动 连接数量超过权重值,之后调度到下一个权重值最高的真实服务器,在此OVF算法中,遍历虚拟服务相关 联的真实服务器链表,找到权重值最高的可用真实服务器。一个可用的真实服务器需要同时满足以下条件:
- 未过载(未设置IP_VS_DEST_F OVERLOAD标志)
- 真实服务器当前的活动连接数量小于其权重值
- 其权重值不为零
六: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. ipvsadm 命令
语法格式:
ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]]
参数:
-A # 添加
-E # 修改
-t # tcp服务
-u # udp服务
-s # 指定调度算法,默认为WLC
-p # 设置持久连接超时,持久连接可以理解为在同一个时间段同一个来源的请求调度到同一Realserver
-f # firewall mask 火墙标记,是一个数字
ipvsadm -a|e -t|u|f service-address -r realserver-address [-g|i|m] [-w weight]
参数:
-a # 添加realserver
-e # 更改realserver
-t # tcp协议
-u # udp协议
-f # 火墙标签
-r # realserver地址
-g # 直连路由模式
-i # ipip隧道模式
-m # nat模式
-w # 设定权重
-Z # 清空计数器
-C # 清空lvs策略
-L # 查看lvs策略
-n # 不做解析
--rate :输出速率信息
七:实战
1. nat 模式
实验环境:
主机名 | ip | vip | 角色 |
---|---|---|---|
director server | nat:192.168.159.131 | 仅主机:192.168.137.131 | 调度器 |
real-server1 | nat:192.168.159.132 | null | 真实服务器 |
real-server2 | nat:192.168.159.133 | null | 真实服务器 |
client | 仅主机:192.168.137.2 | null | 测试机 |
Director Server
启动IP转发
[root@director ~]# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
[root@director ~]# sysctl -p
配置VIP
[root@director ~]# nmcli connection modify 有线连接\ 1 ipv4.method manual ipv4.addresses 192.168.137.131/24 ipv4.gateway 192.168.137.1 ipv4.dns 192.168.137.1 autoconnect yes
[root@director ~]# nmcli con up 有线连接\ 1
配置ip
[root@director ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
BOOTPROTO="static"
ONBOOT="yes"
IPADDR=192.168.159.131
GATEWAY=192.168.159.2
NETMASK=255.255.255.0
DNS1=192.168.159.2
[root@director ~]# systemctl restart network
配置LVS规则
# 安装ipvsadm
[root@director ~]# yum install ipvsadm -y
# 创建虚拟服务
[root@director ~]# ipvsadm -A -t 192.168.137.131:80 -s rr
# 添加Real Server节点(-m表示NAT模式)
[root@director ~]# ipvsadm -a -t 192.168.137.131:80 -r 192.168.159.132:80 -m
[root@director ~]# ipvsadm -a -t 192.168.137.131:80 -r 192.168.159.133:80 -m
# 保存规则
[root@director ~]# ipvsadm-save > /etc/sysconfig/ipvsadm
[root@director ~]# systemctl restart ipvsadm
Real Server 配置
配置IP
[root@real-server1/2 ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
BOOTPROTO="static"
ONBOOT="yes"
IPADDR=192.168.159.132/133
GATEWAY=192.168.159.131 // ds 的DIP
NETMASK=255.255.255.0
DNS1=192.168.159.2
配置web服务
[root@real-server1/2 ~]# yum -y install httpd
[root@real-server1/2 ~]# systemctl start httpd
[root@real-server1/2 ~]# systemctl enable httpd
[root@real-server1/2 ~]# echo "Real Server1" > /var/www/html/index.html
[root@real-server2 ~]# echo "Real Server2" > /var/www/html/index.html
[root@real-server1/2 ~]# systemctl restart httpd
Client 配置
配置IP
[root@client ~]# nmcli connection modify ens33 ipv4.method manual ipv4.addresses 192.168.137.132/24 ipv4.gateway 192.168.137.1 ipv4.dns 192.168.137.1 autoconnect yes
[root@client ~]# nmcli con up ens33
测试
[root@client ~]# for i in {1..10}; do
> curl http://192.168.137.131:80
> done
real-server1
real-server2
real-server1
real-server2
real-server1
real-server2
real-server1
real-server2
real-server1
real-server2
2. dr 模式
实验环境
主机名 | ip | vip | 角色 |
---|---|---|---|
director server | nat:192.168.159.10 | 仅主机:192.168.137.100 | 调度器 |
real-server1 | nat:192.168.159.21 | lo:0:192.168.137.100 | 真实服务器 |
real-server2 | nat:192.168.159.22 | lo:0:192.168.137.100 | 真实服务器 |
client | nat:192.168.159.30 | null | 测试机 |
Director Server
配置IP
[root@director ~]# vim /etc/sysconfig/network-scripts/ifcfg-ens33
BOOTPROTO="static"
ONBOOT="yes"
IPADDR=192.168.159.131
GATEWAY=192.168.159.2
NETMASK=255.255.255.0
DNS1=192.168.159.2
[root@director ~]# systemctl restart network
配置VIP
[root@director ~]# nmcli connection modify 有线连接\ 1 ipv4.method manual ipv4.addresses 192.168.159.100/24 ipv4.gateway 192.168.159.2 ipv4.dns 192.168.159.2 autoconnect yes
[root@director ~]# nmcli con up 有线连接\ 1
配置LVS规则
# 安装ipvsadm
[root@director ~]# yum install ipvsadm -y
# 创建虚拟服务
[root@director ~]# ipvsadm -A -t 192.168.159.100:80 -s rr
# 添加Real Server节点(-g表示dr模式)
[root@director ~]# ipvsadm -a -t 192.168.159.100:80 -r 192.168.159.21:80 -g
[root@director ~]# ipvsadm -a -t 192.168.159.100:80 -r 192.168.159.22:80 -g
# 保存规则
[root@director ~]# ipvsadm-save > /etc/sysconfig/ipvsadm
[root@director ~]# systemctl restart ipvsadm
# 查看
[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.159.100:80 rr
-> 192.168.159.21:80 Route 1 0 0
-> 192.168.159.22:80 Route 1 0 0
Real Server 配置
配置VIP在lo接口
[root@real-server1/2 ~]# echo 'DEVICE=lo:0 IPADDR=192.168.159.100 NETMASK=255.255.255.255 ONBOOT=yes' > /etc/sysconfig/network-scripts/ifcfg-lo:0
[root@real-server1/2 ~]# ifup lo:0
编辑/etc/sysctl.conf
[root@real-server1/2 ~]# vim /etc/sysctl.conf
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
[root@real-server1/2 ~]# sysctl -p
配置web服务
[root@real-server1/2 ~]# yum -y install httpd
[root@real-server1/2 ~]# systemctl start httpd
[root@real-server1/2 ~]# systemctl enable httpd
[root@real-server1/2 ~]# echo "Real Server1" > /var/www/html/index.html
[root@real-server2 ~]# echo "Real Server2" > /var/www/html/index.html
[root@real-server1/2 ~]# systemctl restart httpd
Client 配置
[root@client ~]# for i in {1..10}; do
> curl http://192.168.159.100
> done
Real Server1
Real Server2
Real Server1
Real Server2
Real Server1
Real Server2
Real Server1
Real Server2
Real Server1
Real Server2