简介
LVS是四层调度(OSI模型的下四层),不支持应用层协议内部调度; lvs是内核级功能,工作于内核空间; lvs是内核级功能,所以性能比应用级功能强,因为lvs不受socket限制(IP加端口号),一个IP支持0——65535个端口 lvs用户空间管理工具是ipvsadm,用于管理集群服务及RealServer lvs并发量大(可以达到几百万并发),性能好; 所以一般lvs当做最外层调度,第二级调度才使用nginx或者haproxy; lvs:Linux Virtual Server,阿里四层SLB (Server Load Balance)使用 nginx:支持七层调度,阿里七层SLB使用Tengine haproxy:支持七层调度
会话保持:负载均衡
(1) session sticky:同一用户调度固定服务器(session绑定) Source IP:LVS sh算法(对某一特定服务而言)(SNAT) Cookie(每个用户的cookie是不同的;每个用户访问不同的网站,会分配不同的cookie),cookie属于应用层,lvs实现不了代理 (2) session replication:每台服务器拥有全部session(session复制) session multicast cluster (3) session server:专门的session服务器 Memcached,Redis
LVS工作原理
VS: Virtual Server,负责调度 RS: Real Server,负责真正提供服务 用户通过DNS解析获取到LVS的公网IP(用户以为对外提供服务的是LVS服务器的IP),把请求发送给LVS代理服务器,LVS通过调度算法,把用户请求调度到后端的真实服务器
lvs的四种工作模式
lvs-nat:
工作过程: 用户的请求报文发送到lvs服务器的内核空间,内核空间的prerouting负责接收用户请求的包,通过查看路由表,把数据包发送到本地的input链,lvs监听在input链上,当lvs发现有数据包发送到input链,则进行截断,把发送至input链上的数据包通过postrouting链进行转发;如果不在input链上进行截断,则会通过input链把请求信息发送到对应的应用中,但lvs没有对应的应用,则会失败; lvs相当于路由器,所以也需要开启路由器转发功能;路由器如果不开启转发,如果发现不是发给本网段的数据包,则直接进行抛弃 lvs-nat:修改请求报文的目标IP,多目标IP的DNAT 本质是多目标IP的DNAT,通过将请求报文中的目标地址和目标端口修改为某挑出的RS的RIP和PORT实现转发 (1)RIP和DIP应在同一个IP网络,且应使用私网地址;RS的网关要指向DIP (2)请求报文和响应报文都必须经由Director转发,Director易于成为系统瓶颈 (3)支持端口映射,可修改请求报文的目标PORT (4)VS必须是Linux系统,RS可以是任意OS系统
lvs-dr:
lvs-dr:操纵封装新的MAC地址 LVS-DR:Direct Routing,直接路由,LVS默认模式,应用最广泛,通过为请求报文重新封装一个MAC首部进行转发,源MAC是DIP所在的接口的MAC,目标MAC是某挑选出的RS的RIP所在接口的MAC地址;源IP/PORT,以及目标IP/PORT均保持不变 (1)Director和各RS都配置有VIP (2)确保前端路由器将目标IP为VIP的请求报文发往Director (3)RS的RIP使用私网地址;RIP与DIP在同一IP网络;RIP的网关不能指向DIP,以确保响应报文不会经由Director (4)RS和Director要在同一个物理网络 (5)请求报文要经由Director,但响应报文不经由Director,而由RS直接发往Client (6)不支持端口映射(端口不能修败) (7)RS可使用大多数OS系统
lvs-tun:
lvs-tun:在原请求IP报文之外新加一个IP首部;一般用于异地机房 转发方式:不修改请求报文的IP首部(源IP为CIP,目标IP为VIP),而在原IP报文之外再封装一个IP首部(源IP是DIP,目标IP是RIP),将报文发往挑选出的目标RS;RS直接响应给客户端(源IP是VIP,目标IP是CIP) (1) DIP, VIP, RIP都应该是公网地址 (2) RS的网关一般不能指向DIP (3) 请求报文要经由Director,但响应不经由Director (4) 不支持端口映射 (5) RS的OS须支持隧道功能
lvs-fullnat:
lvs-fullnat:修改请求报文的源和目标IP CIP --> DIP VIP --> RIP (1) VIP是公网地址,RIP和DIP是私网地址,且通常不在同一IP网络;因此,RIP的网关一般不会指向DIP (2) RS收到的请求报文源地址是DIP,因此,只需响应给DIP;但Director还要将其发往Client (3) 请求和响应报文都经由Director (4) 支持端口映射 注意:此类型kernel默认不支持
调度算法
静态算法
静态方法:仅根据算法本身进行调度,不考虑后端服务器负载状态 1、RR:roundrobin,轮询 2、WRR:Weighted RR,加权轮询 3、SH:Source Hashing,实现session sticky,源IP地址hash;将来自于同一个IP地址的请求始终发往第一次挑中的RS,从而实现会话绑定 4、DH:Destination Hashing;目标地址哈希,第一次轮询调度至RS,后续将发往同一个目标地址的请求始终转发至第一次挑中的RS,典型使用场景是正向代理缓存场景中的负载均衡,如:宽带运营商
动态算法
动态方法:主要根据每RS当前的负载状态及调度算法进行调度Overhead(负载值)=value较小的RS将被优先调度 1、LC(最短连接算法):least connections 适用于长连接应用 Overhead=activeconns*256+inactiveconns(连接上,但没有数据传输)没有考虑后端服务器的处理能力 2、WLC:Weighted LC LVS默认调度方法 Overhead=(activeconns*256+inactiveconns)/weight 权重越大,负载值越小,调度几率也就越大 3、SED:Shortest Expection Delay 初始连接高权重优先,但调度不平均 Overhead=(activeconns+1)*256/weight 保证初始连接不为0,如果初始连接为0,0除以所有权重则都为0,所有人的调度几率都一样 4、NQ:Never Queue,第一轮均匀分配,后续SED 5、LBLC:Locality-Based LC,动态的DH算法,使用场景:根据负载状态实现正向代理 6、LBLCR:LBLC with Replication,带复制功能的LBLC,解决LBLC负载不均衡问题,从负载重的复制到负载轻的RS
LVS用户空间的管理工具选项用法(ipvsadm)
ipvsadm核心功能:
集群服务管理:增、删、改 集群服务的RS管理:增、删、改 查看
管理集群服务:增、改、删
-A:添加集群服务 -E:修改集群服务 -D:删除集群服务 -t: TCP协议的端口,VIP:TCP_PORT -u: UDP协议的端口,VIP:UDP_PORT -f:firewall MARK,标记,一个数字 -s:指定集群的调度算法,默认为wlc -p [timeout]:持久连接;实现无论使用任何调度算法,默认是360s之内,能够实现将来自同一个地址的请求始终发往同一个RS ipvsadm -A|E -t|u|f service-address [-s scheduler] [-p [timeout]] ipvsadm -D -t|u|f service-address
管理集群上的RS:增、改、删
-a:添加real-server -e:修改real-server -d:删除real-server -r:指定real-server的ip,后面可以跟端口号(如 :80),但根据lvs的工作模式而定;dr模式和tun模式不支持端口映射 -g: gateway, dr类型,默认 -i: ipip, tun类型 -m: masquerade, nat类型 -w weight:权重 ipvsadm -a|e -t|u|f service-address -r server-address [-g|i|m] [-w weight] 需要指定集群服务 ipvsadm -d -t|u|f service-address -r server-address 指定集群服务
查看及其余指令
--numeric, -n:以数字形式输出地址和端口号 --exact:扩展信息,精确值 --connection,-c:当前IPVS连接输出 --stats:统计信息 --rate :输出速率信息 ipvsadm -L|l [options] 清空计数器:ipvsadm -Z [-t|u|f service-address] 清空定义的所有内容:ipvsadm –C ipvs规则:/proc/net/ip_vs ipvs连接:/proc/net/ip_vs_conn
实现lvs-nat工作模式
实现所需要的配置情况
实现需要四台机器 client:使用桥接网卡(192.168.3.7) LVS:准备一个桥接网卡(192.168.3.17),一个NAT网卡(192.168.38.7) RS1:NAT网卡(192.168.38.37) RS2:NAT网卡(192.168.38.47)
client配置
[root@client ~]# route -n #客户端不需要配网关,因为和lvs的VIP在同一个网段 192.168.3.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0 [root@client ~]# while :;do curl 192.168.3.17;sleep 0.5;done #执行死循环一直访问LVS
RS1配置
[root@rs1 ~]# systemctl start httpd #开启HTTP服务 [root@rs1 ~]# echo RS1 > /var/www/html/index.html #简单设置个RS1网页,容易看效果 [root@rs1 ~]# route -n #并且RS1的网关需要指到LVS的DIP 0.0.0.0 192.168.38.7 0.0.0.0 UG 100 0 0 eth0 192.168.38.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
RS2配置
[root@rs2 ~]# systemctl start httpd [root@rs2 ~]# echo RS2 > /var/www/html/index.html [root@rs2 ~]# route -n #和RS1配置一样 0.0.0.0 192.168.38.7 0.0.0.0 UG 100 0 0 eth0 192.168.38.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
LVS配置
[root@lvs ~]# vim /etc/sysctl.conf #/proc/sys/下的文件都是由这个文件进行管理,想要永久生效,则需要修改这个文件; net.ipv4.ip_forward=1 #LVS也需要开启路由器转发功能 [root@lvs ~]# sysctl -p #让修改的配置生效 [root@lvs ~]# route -n #LVS不需要有网关;实际工作中VIP须得有网关 [root@lvs ~]# ipvsadm -A -t 192.168.3.17:80 -s rr #添加集群服务,指定调度算法;配置完之后LVS也不会开启端口,LVS不是由应用层协议实现的,而是由内核实现的,所以不会打开80端口 [root@lvs ~]# ipvsadm -a -t 192.168.3.17:80 -r 192.168.38.37 -m #添加real-server,指定集群服务,指定工作模式为nat [root@lvs ~]# ipvsadm -a -t 192.168.3.17:80 -r 192.168.38.47 -m [root@lvs ~]# ipvsadm -Ln #列出集群服务和real-server
实现lvs-nat模式下的https和http的统一调度
[root@lvs ~]# iptables -t mangle -A PREROUTING -d 192.168.3.17 -p tcp -m multiport --dports 80,443 -j MARK --set-mark 100 #添加防火墙标签,当访问lvs的vip的80和443端口时,都在通过prerouting链时贴上标签数字100 [root@lvs ~]# ipvsadm -A -f 100 -s rr #指定集群服务为标签100 [root@lvs ~]# ipvsadm -a -f 100 -r 192.168.38.37 -m #real-server不要指定端口号,让LVS认为不管是443还是80,都是一个服务,进行统一调度 [root@lvs ~]# ipvsadm -a -f 100 -r 192.168.38.47 -m
找一台客户端机器进行测试
[root@client ~]# while :;do echo http;curl 192.168.3.17;echo https;curl -k https://192.168.3.17;done http #轮询时访问80端口调度到rs2上,访问443调度到rs1上,rs2和rs1变成一个整体,则以后调度只要访问443就调度到rs1,访问80就调度到rs2上 RS2 #实现https需要安装mod_ssl模块,安装完重启httpd服务 https RS1 http RS2 https RS1
保存lvs的策略
[root@lvs ~]# cat /usr/lib/systemd/system/ipvsadm.service #会发现停止服务会把策略保存到文件中,启动服务会加载文件中的策略 ExecStop=/bin/bash -c "exec /sbin/ipvsadm-save -n > /etc/sysconfig/ipvsadm" ExecStart=/bin/bash -c "exec /sbin/ipvsadm-restore < /etc/sysconfig/ipvsadm"
实现lvs-dr工作模式(单网段)
试验需要准备五台机器 client:192.168.3.7/24 route:192.168.3.17/24、192.168.38.7/24 lvs:192.168.38.6/24、192.168.38.100/32(VIP) RS1:192.168.38.37/24 RS2:192.168.38.47/24 因为是lvs的dr模型,所有RS1和RS2都需要有LVS的VIP,所以把LVS的VIP绑定在RS1、2的网卡上,相当于一个网卡两个IP,并且VIP和DIP、RSIP都在同一个网段
client端配置:
[root@client ~]# route -n #网关要指向route的192.168.3.17这个IP 0.0.0.0 192.168.3.17 0.0.0.0 UG 100 0 0 eth0 192.168.3.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0 [root@client ~]# while :;do curl 192.168.38.100;sleep 1;done #执行死循环一直访问LVS的VIP
route
[root@route ~]# route -n #route不需要网关,配置通向两个目标的网段就可 192.168.3.0 0.0.0.0 255.255.255.0 U 101 0 0 eth1 192.168.38.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0
LVS配置
[root@centos6 ~]# route add default gw 192.168.38.123 #LVS的dr模型下,其实网关是没有参与工作的,但是不配不行;如果LVS不配置网关的话,当它收到一个来自192.168.3网段的报文后,发现自己没有网关,会认为自己没有回复报文的能力,就会不接收报文,所以需要配置网关(随意配即可) [root@centos6 ~]# ip a a 192.168.38.100 dev eth0 #添加个VIP,添加到eth0网卡上 [root@centos6 ~]# ipvsadm -A -t 192.168.38.100:80 -s rr #添加集群服务 [root@centos6 ~]# ipvsadm -a -t 192.168.38.100:80 -r 192.168.38.37 -g #往集群服务中添加real-server,并且指定工作模式为dr [root@centos6 ~]# ipvsadm -a -t 192.168.38.100:80 -r 192.168.38.47 -g [root@centos6 ~]#iptables -F #如果有防火墙规则,需要情况防火墙规则
RS1配置
[root@rs1 ~]# echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore #忽略ARP广播 [root@rs1 ~]# echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce #关闭重启网卡时发送的免费ARP广播 [root@rs1 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce [root@rs1 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore [root@rs1 ~]# route -n #网关指向route的192.168.38.7这个IP 0.0.0.0 192.168.38.7 0.0.0.0 UG 100 0 0 eth0 192.168.38.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0 [root@rs1 ~]# echo RS1 > /var/www/html/index.html #指定个简单页面,记得启动http服务
RS2配置
[root@rs2 ~]# echo 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignore [root@rs2 ~]# echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore [root@rs2 ~]# echo 2 > /proc/sys/net/ipv4/conf/eth0/arp_announce [root@rs2 ~]# echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce [root@rs2 ~]# route -n 0.0.0.0 192.168.38.7 0.0.0.0 UG 100 0 0 eth0 192.168.38.0 0.0.0.0 255.255.255.0 U 100 0 0 eth0 [root@rs2 ~]# echo RS2 > /var/www/html/index.html