lvs负载均衡
一.介绍
集群:若干服务器在同一时刻干同一件事情
负载均衡集群
lvs
haproxy
nginx
F5(硬件设备)
高可用集群(关键性的业务)
keepalived
高性能集群(一般不用)
开发算法
天气预报
随着规模不断地扩大
公司会选择横向扩展
在集群中加服务器
个人会选择纵向扩展
换配置,或换电脑
二.LVS简介
LVS是Linux Virtual Server的简称,也就是Linux虚拟服务器,是一个由章文嵩博士发起的自由软件项目,官方站点是:http://www.linuxvirtualserver.org。现在LVS已经是Linux标准内核的一部分,在Linux2.4内核以前,使用LVS时必须重新编译内核以支持LVS功能模块,但是从Linux2.4内核心之后,已经完全内置了LVS的各个功能模块,无需给内核打任何补丁,可以直接使用LVS提供的各种功能。
使用LVS技术要达到的目标是:通过LVS提供的负载均衡技术和Linux操作系统实现一个高性能,高可用的服务器群集,它具有良好的可靠性、可扩展性和可操作性。从而以低廉的成本实现最优的服务性能。
三.LVS体系架构
使用LVS架设的服务器集群系统有三个部分组成:最前端的负载均衡层(Loader Balancer),中间的服务器群组层,用Server Array表示,最底层的数据共享存储层,用Shared Storage表示。在用户看来所有的应用都是透明的,用户只是在使用一个虚拟服务器提供的高性能服务。
四.四层负载和七层负载
1.四层负载(lvs只支持四层)
所谓四层负载均衡,也就是主要通过报文中的目标地址和端口,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。
以常见的TCP为例,负载均衡设备在接收到第一个来自客户端的SYN 请求时,即通过上述方式选择一个最佳的服务器,并对报文中目标IP地址进行修改(改为后端服务器IP),直接转发给该服务器。TCP的连接建立,即三次握手是客户端和服务器直接建立的,负载均衡设备只是起到一个类似路由器的转发动作。在某些部署情况下,为保证服务器回包可以正确返回给负载均衡设备,在转发报文的同时可能还会对报文原来的源地址进行修改。
2.七层负载
所谓七层负载均衡,也称为“内容交换”,也就是主要通过报文中的真正有意义的应用层内容,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。
以常见的TCP为例,负载均衡设备如果要根据真正的应用层内容再选择服务器,只能先代理最终的服务器和客户端建立连接(三次握手)后,才可能接受到客户端发送的真正应用层内容的报文,然后再根据该报文中的特定字段,再加上负载均衡设备设置的服务器选择方式,决定最终选择的内部服务器。负载均衡设备在这种情况下,更类似于一个代理服务器。负载均衡和前端的客户端以及后端的服务器会分别建立TCP连接。所以从这个技术原理上来看,七层负载均衡明显的对负载均衡设备的要求更高,处理七层的能力也必然会低于四层模式的部署方式。
五.iptables五链
1.iptables五链分别是PREROUTING、INPUT、FORWARD、OUTPUT、POSTROUTING
数据包的处理方式不同,流经的链也不同:
netfilter(网络过滤):
数据流入时要经过的链:PREROUTING(数据进到主机之前) -->INRUT(数据进到主机之后)
数据流出时要经过的链:OUTPUT(数据出去主机网卡所在)-->POSTROUTING(数据已经出去)
数据转发时要经过的链:PREROUTING(数据出去主机之前) -->FORWARD(中转)-->POSTROUTING(数据出去主机之后)
2.各功能的分别实现位置:
filter:INPUT,FORWARD,OUTPUT
nat:PREROUTING(DNAT),OUTPUT,POSTROUTING(SNAT)
mangle:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING
raw:PREROUTING,OUTPUT
六.lvs负载均衡软件
lvs:
安装ipvsadm/ipvs命令
ipvsadm:用户空间的命令行工具,用于管理集群服务
ipvs:工作于内核中netfilter INPUT钩子上
支持TCP,UDP,AH,EST,AH_EST,SCTP等诸多协议
grep -i -A 2 ‘ipvs’ /boot/config-3.10.0-862.el7.x86_64 查看系统对ipvs的支持情况,包括算法
[root@yeqixian ~]# grep -i -A 2 'ipvs' /boot/config-3.10.0-862.el7.x86_64
CONFIG_NETFILTER_XT_MATCH_IPVS=m
CONFIG_NETFILTER_XT_MATCH_LENGTH=m
CONFIG_NETFILTER_XT_MATCH_LIMIT=m
--
# IPVS transport protocol load balancing support
#
CONFIG_IP_VS_PROTO_TCP=y
--
# IPVS scheduler
#
CONFIG_IP_VS_RR=m
--
# IPVS SH scheduler
#
CONFIG_IP_VS_SH_TAB_BITS=8
--
# IPVS application helper
#
CONFIG_IP_VS_FTP=m
lvs arch:
调度器:director,dispatcher,balancer
RS:Real Server
Client IP:CIP
Director Virutal IP:VIP(外部的网卡)
Director IP:DIP(内部的网卡)
Real Server IP:RIP(和DIP在同一网段)
七.lvs的四种模型
NAT(地址转换)
DR(网关)
TUN(隧道模式)
FULLNAT(全NAT模式)
lvs-nat:masquerade
1.lvs-nat本质上就是多目标的DNAT(iptables)
lvs-nat模式通过修改请求报文的目标IP地址(同时可能会修改目标端口)至挑选出来的某RS的RIP地址实现转发
lvs-nat的特点:
RS和DIP应该使用私网地址,且RS的网关要指向DIP
请求和响应报文都要经由director转发,所以配置时需要将director的转发功能开启,极高负载的场景中,director可能会成为系统性能瓶颈
支持端口映射
RS可以使用任意OS
RS的RIP和Director的DIP必须在同一IP网络
2.lvs-dr(direct routing):lvs的默认模式,gateway
lvs-dr模式通过修改请求报文的目标MAC地址进行转发
Director:调度器要配置VIP,DIP
RSs:所有的Real Server都要配置RIP,VIP
lvs-dr的特点:
保证前端路由器将目标IP为VIP的请求报文发送给director,解决方案有以下三种:
1.静态绑定
2.arptables
3.修改RS主机内核的2个参数:
1.arp_announce:是否接收并记录别人的通告以及是否通告自己的mac地址给别人。arp_announce有三个可选值,0,1,2,其意义如下:
0(default,默认值为0):通告自己所拥有的所有地址(不能用)
1:尽量不通告与自己不在同一个网段的地址,比如不通告2.0网段的地址给1.0网段,不通告3.0网段的地址给1.0网段等,但是是尽量不通告,有可能还是会通告的(没有保障)
尽量避免不在该网络接口子网段的本地地址做出arp回应.
当发起ARP请求的源IP地址是被设置应该经由路由达到此网络接口的时候很有用.
此时会检查来访IP是否为所有接口上的子网段内ip之一.如果该来访IP不属于各个网络接口上的子网段内,那么将采用级别2的方式来进行处理.
2:总是不通告与自己不在同一个网段的地址,比如不通告2.0网段的地址给1.0网段,不通告3.0网段的地址给1.0网段等,绝对不会通告(应用)
对查询目标使用最适当的本地地址.在此模式下将忽略这个IP数据包的源地址并尝试选择与能与该地址通信的本地地址.
首要是选择所有的网络接口的子网中外出访问子网中包含该目标IP地址的本地地址.
如果没有合适的地址被发现,将选择当前的发送网络接口或其他的有可能接受到该ARP回应的网络接口来进行发送.
2.arp_ignore:是否响应arp请求
arp_ignore有9个可选值,0,1,2,3,4,5,6,7,8,其意义如下:
0(default,默认值为0):回应任何网络接口上对任何本地IP地址的arp查询请求
1:请求报文从哪个接口进入的且请求的目标地址就是此接口配置的地址才予以响应,否则不响应(应用)
只回答目标IP地址是来访网络接口本地地址的ARP查询请求
2:只回答目标IP地址是来访网络接口本地地址的ARP查询请求,且来访IP必须在该网络接口的子网段内
3:不回应该网络接口的arp请求,而只对设置的唯一和连接地址做出回应
4-7:保留未使用
8:不回应所有(本地地址)的arp查询
RS的RIP可以使用私有地址,也可以使用公网地址,但是不去用公网地址
RS跟Director必须在同一物理网络中,中间不能有路由器相隔
请求报文经由Director调度,但响应报文一定不能经由Director
不支持端口映射
RS可以是大多数OS
RS的网关不能指向DIP
lvs-dr配置:
lvs-dr配置:director只需要一块网卡,vip配置在lo接口中即可,此处假设dip与rip在同一网段
配置director的ip地址信息(dip,vip)
配置dip(编辑物理网卡配置文件/etc/sysconfig/network-scripts/ifcfg-eth0)
配置vip:
ip addr add 192.168.116.250/32 dev lo(如需永久,需写入配置文件)
配置RS的ip地址信息:
配置rip(编辑物理网卡配置文件/etc/sysconfig/network-scripts/ifcfg-eth0)
修改网卡内核参数:编辑/etc/sysctl.conf文件,添加如下内容:(如需永久,需写入配置文件)
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
配置vip:
ip addr add 192.168.116.250/32 dev lo
注意:此处必须先修改网卡内核参数然后再配置vip,因为如果先配vip,vip配好后就会立马通告给别人,而修改内核参数就是为了不通告
配置路由信息:在director和所有RS上进行如下配置:(如需永久,需写入配置文件//etc/sysconfig/network-scripts/route-lo (配置vip时选的网卡前面把ifcfg改为route))
route add -host vip dev interface:0
在director上添加并保存规则:
ipvsadm -A -t vip:port -s wrr
ipvsadm -a -t vip:port -r rip:port -g
ipvsadm -S > /etc/sysconfig/ipvsadm
DR配置:
[root@DR ~]# yum provides */bin/ipvsadm
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
No matches found
[root@DR ~]# yum provides *bin/ipvsadm
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
yei/filelists_db | 3.1 MB 00:00
ipvsadm-1.27-7.el7.x86_64 : Utility to administer the
: Linux Virtual Server
Repo : yei
Matched from:
Filename : /usr/sbin/ipvsadm
[root@DR ~]# yum -y install ipvsadm-1.27-7.el7.x86_64
[root@DR ~]# route add -host 192.168.116.250/32 dev lo
[root@DR ~]# ip addr add 192.168.116.250/32 dev lo
[root@DR ~]# yum provides *bin/rount
[root@DR ~]# ipvsadm -A -t 192.168.116.250:80 -s wrr
[root@DR ~]# ipvsadm -a -t 192.168.116.250:80 -r 192.168.116.181:80 -g
[root@DR ~]# ipvsadm -a -t 192.168.116.250:80 -r 192.168.116.182:80 -g
[root@DR ~]# ipvsadm -S > /etc/sysconfig/ipvsadm
[root@DR ~]# 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.116.250:80 wrr
-> 192.168.116.181:80 Route 1 0 0
-> 192.168.116.182:80 Route 1 0 0
RS配置:
[root@RS1 ~]# vim /etc/sysctl.conf
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
[root@RS1 ~]# sysctl -p
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
[root@RS1 ~]# ip addr add 192.168.116.250/32 dev lo
[root@RS1 ~]# yum -y install net-tools
[root@RS1 ~]# route add -host 192.168.116.250/32 dev lo
[root@RS2 ~]# vim /etc/sysctl.conf
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
[root@RS2 ~]# sysctl -p
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
[root@RS2 ~]# ip addr add 192.168.116.250/32 dev lo
[root@RS2 ~]# yum -y install net-tools
[root@RS2 ~]# route add -host 192.168.116.250/32 dev lo
lvs-dr配置验证:
[root@RS1 ~]# yum -y install httpd
[root@RS1 ~]# cd /var/www/html/
[root@RS1 html]# echo ‘rs1’ > index.html
[root@RS1 ~]# systemctl enable --now httpd
[root@RS2 ~]# yum -y install httpd
[root@RS2 html]# echo ‘rs2’ > index.html
[root@RS2 html]# systemctl enable --now httpd
3.lvs-tun(ip tunneling):ipip
lvs-tun模式不修改请求报文的ip首部,而是通过在原有的ip首部(CIP<-->VIP)之外再封装一个ip首部(DIP<-->RIP)
lvs-tun的特点:(需要较多公网地址)
RIP,DIP,VIP必须是公网地址
RS的网关不能指向DIP
请求报文必须经由director调度,但响应报文必须不能经由director
不支持端口映射
RS的OS必须支持隧道功能
lvs-fullnat:keepalived
director通过同时修改请求报文的目标地址和源地址进行转发
lvs-fullnat:keepalived
director通过同时修改请求报文的目标地址和源地址进行转发
lvs-fullnat的特点:
VIP是公网地址,RIP和DIP是私网地址,RIP与DIP无须在同一网络中
RS接收到的请求报文的源地址为DIP,因此要响应给DIP
请求报文和响应报文都必须经由Director
支持端口映射机制
RS可以使用任意OS
lvs scheduler:lvs调度器,即lvs挑选RS的算法
静态方法:仅根据算法本身进行调度
RR:round robin,轮调
WRR:weighted rr,加权的rr,根据一定的比例进行轮调,比如每次RS1给2个请求,RS2给1个请求
SH:source hash,源地址hash,实现session保持的机制,将来自于同一个IP的请求始终调度至同一RS,每个服务单独调度
DH:destination hash,目标地址hash,将对同一个目标(资源)的请求始终发往同一个RS
动态方法:根据算法及各RS的当前负载状态进行调度,根据指定的算法算出overhead(负载),最终挑选出overhead值最小的则为被选中的RS
LC:Least Connection,最少连接数,算法如下:
overhead = Active * 256 + Inactive
WLC:Weighted LC,加权的LC,算法如下:
overhead=(Active*256+Inactive)/ weight
SED:Shortest Expection Delay,最短期望延迟,算法如下:
overhead = (Active + 1) * 256 / weight
NQ:Nevel Queue,是SED算法的改进,根据SED算法每台主机第一次至少要均分配一次,然后再按SED算法来挑选
LBLC:Locality-Based LC,基于本地的最少连接数,即为动态的DH算法
正向代理情形下的cache server调度
LBLCR:Locality-Based Least-Connection with Replication,带复制功能的LBLC算法
ipvs的集群服务:
支持TCP,UDP,AH,EST,AH_EST,SCTP等诸多协议
ipvs集群服务的特点:
一个ipvs主机可以同时定义多个cluster service(通过端口号的服务)
定义时指明lvs-type(lvs的模式)以及lvs scheduler(调度器)
一个cluster service上至少应该有一个real server
ipvsadm的用法:
管理集群服务:
ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] [-M netmask](添加|修改)
ipvsadm -D -t|u|f service-address(删除)
常见的service-address:
tcp:-t ip:port
udp:-u ip:port
fwm:-f mark
-s scheduler:
默认为wlc
-p [timeout]:定义持久连接,timeout不指定时默认为300秒
管理集群服务中的RS
ipvsadm -a|e -t|u|f service-address -r server-address [-g|i|m] [-w weight] [-x upper] [-y lower]
ipvsadm -d -t|u|f service-address -r server-address
ipvsadm -L|l [options]
server-address:
ip[:port]
lvs-type:
-g:gateway,dr模式
-i:ipip,tun模式
-m:masquerade,nat模式
-w:设定权重,可为0到正无穷数值,设为0时不会被调度,默认为1
权重值越大则表示性能越好,被调度的资源也会更多
清空和查看:
ipvsadm -C 清空
ipvsadm -L|l [options] 查看
options:
-n:numeric,基于数字格式显示地址和端口
-c:connection,显示当前ipvs连接
--stats:统计数据
--rate:输出速率信息
--exact:显示精确值,不做单位换算
保存和重载:
ipvsadm -R 重载
ipvsadm -S [-n] 保存
置零计数器:
ipvsadm -Z [-t|u|f service-address]
[root@DR ~]# ipvsadm -e -t 192.168.116.250:80 -r 192.168.116.181:80 -w 2 -g
[root@DR ~]# 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.116.250:80 wrr
-> 192.168.116.181:80 Route 2 0 0
-> 192.168.116.182:80 Route 1 0 0
通过FWM(FireWalld Mark)定义集群的方式:
功用:将共享一组RS的集群服务统一进行定义,统一进行调度
a) 在director上的netfilter的mangle表的PREROUTING链定义用于“打标”的规则:
iptables -t mangle -A PREROUTING -d $VIP -p $PROTOCOL --dports $PORT -j MARK --set-mark #
$VIP:VIP地址
$PROTOCOL:协议,tcp/udp等
$PORT:端口号
最后的#号表示打标的标记号
b) 基于FWM定义集群服务:
ipvsadm -A -f # -s scheduler
ipvsadm -a -f # -t $VIP[:PORT] -r $RIP -g
session保持的方法有以下三种实现方式:
session绑定:
对某一特定服务:可以使用lvs的sh算法进行session绑定
对多个共享同一组RS的服务器,需要统一进行绑定时:可以使用lvs的persistence持久连接来实现
功能:无论ipvs使用何种调度方法,其都能实现将来自于同一个Client的请求始终定向至第一次调度时挑选出的RS
lvs的persistence通过一个持久连接模板来实现持久连接,这个持久连接模板独立于算法之外,模板样式如下:
sourceip rs timer
持久连接的实现方式:
每端口持久:PPC,单服务持久调度。无论使用何种算法,可以使用此方式实现sh算法的功能,且能定义持久时长
每FWM持久:PFWMC,单FWM持久调度。将多种不同的服务通过iptables打标成同一种标记,然后通过FWM进行统一持久调度
每客户端持久:PCC,单客户端持久调度
director上会将用户的任何请求都识别为集群服务,并向RS进行调度
tcp:1-65535
udp:1-65535
session复制
session服务器:memcached,redis(key-value,kv store)
lvs缺点:
不具备健康状态检查功能,只是一个调度器而已,一般和其它工具连用,强化它的功能,比如nginx;而且lvs和nginx应该高可用