LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统。本项目在1998年5月由章文嵩博士成立,是中国国内最早出现的自由软件项目之一。
组成部分:ipvs(真正工作在内核中),ipvsadm
ipvs工作于netfilter的INPUT链路:
ipvsadm用于在ipvs上定义集群服务;同时也得定义此集群服务对应于有哪个后端主机可用;根据所指定的调度方法(算法)作出调度决策;
LVS体系结构如下图所示:
lvs中的常用术语约定:
Host:
Director:调度器
Real Server:RS,后端真正提供服务的主机
IP:
Client:CIP (客户端IP)
Director Virtual IP:VIP(与客户端主机通信的地址)(也被称为流动IP地址)
Director IP:DIP(与后端主机通信的地址)
Real IP:RIP(后端真正提供服务的地址)
负载均衡技术有很多实现方案,有基于DNS域名轮流解析的方法,有基于客户端调度访问的方法,还有基于应用层系统负载的调度方法,还有基于ip地址的调度方法。在这些负载调度算法中,执行效率最高的是IP负栽均衡技术。
LVS 的IP负载均衡技术是通过IPVS模块来实现的。IPVS是LVS集群系统的核心软件, 它的主要作用是:安装在Director Server上,同时在Director Server上虚拟出一个IP地址,用户必须通过这个虚拟的IP地址访问服务器,这个虚拟IP—般称为LVS的VIP,即Virtual IP 。访问的请求首先经过VIP到达负载调度器,然后由负载调度器从Real Server列表中选取 一个服务节点响应用户的请求。
在用户的请求到达负载调度器后,调度器如何将请求发送到提供服务的Real Server节点,Real Server节点如何返回数据给用户,是IPVS实现的重点技术。
IPVS实现负载均衡的方式有4种:
lvs-nat:masquerade
lvs-dr:direct routing
lvs-tun:tunneling
lvs-fullnet:(淘宝研发的) fullnat
IPVS/NAT :即 Virtual Server via NetworkAddress Translation,也就是网络地址翻译技术实现虚拟服务器。当用户请求到达调度器时,调度器将请求报文的目标地址(即虚拟IP地址)改写成选定的Real Server地址,同时将报文的目标端口也改成选定的Real Server的相应端口,最后将报文请求发送到选定的RealServer。在服务器端得到数据后,Real Server将数据返回给用户时,需要再次经过负载调度器将报文的源地址和源端口改成虚拟IP地址和相应端口,然后把数据发送给用户,完成整个负载调度过程。可以看出在NAT方式下,用户请求和响应报文都必须经过Director Server地址重写,当用户请求越来越多时,调度器的处理能力将成为瓶颈.
架构特性:
(1)RS应该使用私有地址,即RIP应该为私有地址;各RS的网关必须指向DIP;
(2)请求和响应报文都经由Director转发;高负载场景中,Director易于成为系统瓶颈;
(3)支持端口映射;
(4)RS可以使用任意类型的OS;
(5)RS的RIP必须与Director的DIP在同一网络;
VS/DR: 即Virtual Server via DirectRouting,也就是用直接路由技术实现虚拟服务器。 这种方式的连接调度和管理与前两种一样,但它的报文转发方法又有所不同,VS/DR 通过改写请求报文的MAC地址,将请求发送到Real Server,而Real Server将响应直接返回给客户.免去了VS/TUN中的IP隧道开销,这种方式是3种负莪调度方式中性能最好的,但是要求Director Server与Real Server必须由一块网卡连在同一物理网段上。
LVS-DR:直接路由
Director在实现转发时不修改请求的IP首部,而是通过直接封装MAC首部完成转发;
目标MAC是Director根据调度方法挑选出某RS的MAC地址;拓扑结构有别NAT类型;
架构特性:
(1) 保证前端路由器将目标地址为VIP的请求报文通过ARP地址解析后送往Director;
解决方案:
静态绑定:在前端路由直接将VIP对应的目标MAC静态配置为Director的MAC地址;
arptables:在各RS上,通过arptables规则拒绝其响应对VIP的ARP广播请求;
内核参数(常用方法):在RS上修改内核参数,并结合地址的配置方式实现拒绝响应对VIP的ARP广播请求;
(2) RS的RIP可以使用私有地址:但也可以使用公网地址,此时可以通过互联网上的主机 直接对此RS发起管理操作;
(3) 请求报文必须经由Director调度,但响应报文必须不能经由Director;
(4) 各RIP必须与DIP在同一个物理网络中;
(5) 不支持端口映射;
(6) RS可以使用大多数的OS;
(7) RS的网关一定不能指向Director;
lvs-tun:不修改请求报文IP首部,而是通过IP隧道机制在原有的IP报文之外再封装IP首部, 经由互联网把请求交给选定的RS;CIP;VIP DIR;RIP.
架构特性:
(1) RIP,DIP,VIP都是公网地址;
(2) RS的网关不能,也不可能指向DIP;
(3) 请求报文由Director分发,但响应报文直接由RS响应给Client;
(4) 不支持端口映射;
(5) RS的OS必须得支持IP隧道;
lvs-fullnat:通过修改请求报文的源地址为DIP,目标为DIP来实现转发;对于响应报文而言,修改源地址为VIP,目标地 址为CIP来实现转发;
架构特性:
(1) RIP,DIP可以使用私有地址;
(2) RIP,DIP可以不在同一个网络中,且RIP的网关未必需要指向DIP;
(3) 支持端口映射;
(4) RS的OS可以使用任意类型;
(5) 请求报文经由Director,响应报文经由Director;
lvsscheduler:调度算法
静态方法:仅根据算法本身实现调度;(起点公平)
rr:Round Robin # 即轮询
wrr:WeR # 即加权ighted R轮询 算法:Overhead=conn/weight
sh:Source Hashing # 即来源IP地址hash
dh: Destination ip Hashing # 目标地址哈希;把来自同一地址请求,统统定向至此前选定的RS;把访问同一个目标地址 的请求,统统定向至此前选定的某RS;
动态方法:根据算法及后端RS当前的负载状况实现调度;(结果公平)
LC:least connection(最少连接)
Overhead=Active*256+Inactive (计算当前负载状态的值)
WLC(默认调度算法,用的最多的):weighted least connection(加权最小连接)
Overhead=(Active*256+Inactive)/weight
SED:Shorted Expection Delay(最短期望延迟)
Overhead=(Active+1)*256/weight权重 (第一个请求一定会给权重最大的;
问题前几个请求会一直给权重较大的主机而权重小的主机一直得不到请求,)
NQ:Never queue 永不排队;
LBLC: Local-Based Least Connection,动态方式的DH算法;
LBLCR:Replicated LBLC; 带复制的LBLC,共享缓存内容,(复制是有限的,复制特定的目标)
session 保持:
session sticky:(会话粘性):sh;基于源ip绑定,基于cookie绑定;
session replication cluster:session复制
在各server之间以多播方式”复制“各session信息,从而每个server会持有所有的 session;(tomcat)
session server:引入第三方存储,专用于共享存储session信息;(redis,memcached)
常用命令:
创建或修改:
ipvsadm -A|E -t|u|f service-address [-sscheduler]
-A:在内核的虚拟服务器表中添加一条新的虚拟服务器记录。也就是增加一台新的虚拟服务器。
-E: 修改,编辑内核虚拟服务器表中的一条虚拟服务器记录。 修改定义过的集群服务
-t:承载的应用层协议为基于TCP协议提供服务的协议;其service-address的格式为“VIP:PORT”,如“172.16.8.100:80”;
-u:承载的应用层协议为基于UDP协议提供服务的协议;其service-address的格式为“VIP:PORT”,如“172.16.8.100:53”
-f:承载的应用层协议为基于TCP或UDP协议提供服务的协议,但此类报文会经由iptables/netfilter打标记,即为防火墙标记;其 service-address的格式为“FWM”, 例如“10”;
-s scheduler:指明调度方法;默认为WLC;有这样几个选项rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq
-p --persistent [timeout] :持久稳固的服务。这个选项的意思是来自同一个客户的多次请求,将被同一台真实的服务器 处理。timeout的默认值为360秒。
-D :删除指定集群服务
# ipvsadm -A172.16.8.100:80 [-s WLC] 定义服务;
删除: ipvsadm -D -t|u|f service-address
# ipvsadm-D -t 172.16.8.100:80 删除服务定义
# ipvsadm-L –n 查看服务定义
查看LVS上当前的所有连接
# ipvsadm -Lcn
或者
#cat /proc/net/ip_vs_conn
查看虚拟服务和Real Server上当前的连接数、数据包数和字节数的统计值,则可以使用 下面的命令实现:
# ipvsadm -L --stats
查看包传递速率的近似精确值,可以使用下面的命令:
# ipvsadm -L --rate
管理集群服务上的RS:
添加或修改:
ipvsadm -a|e -t|u|f service-address -rserver-address [-g|i|m] [-w weight] [-x upper] [-y lower]
-r server-address:指明RS,server-address格式一般为”IP[:PORT]“;
注意,只支持端口映射的lvs类型中才应该显示定义此处端口;
-a --add-server: 在内核虚拟服务器表的一条记录里添加一条新的真实服务器记录。也就是在一个虚拟服务器中增加一台新的 真实服务器。向指定的CS中添加RS
-t service-address: 说明虚拟服务器提供的是tcp的服务
-u service-address: 说明虚拟服务器提供的是udp的服务
-f:承载的应用层协议为基于TCP或UDP协议提供服务的协议,但此类报文会经由 iptables/netfilter打标记,即为防火墙标记;其service-address的格式为“FWM”, 例如“10”;
-r --real-server server-address: 真实的服务器[Real-Server:port],只有支持端口 映射的LVS类型才允许此处使用跟集群服务中不同的端口LVS 类型:
-g : gateway,DR # 指定集群类型为LVS/DR
-i ipip,TUN # 指定集群类型为LVS/TUN
-m:masquerade,NAT # 指定集群类型为 NAT
-w:指定RS权重:
-e:修改指定的RS属性
-d :从指定的集群服务中删除某RS
例如: -r 192.16.1.7:80
[-g|i|m]:指明lvs类型
-g:gateway,意为dr类型;(默认类型)
-i:ipip,意为tun类型;
-m:masquerade,意为nat类型;
[-w weight]:当前RS的权重;
注意: 仅对于支持加权调度的scheduler,权重才有意义;
例:# ipvsadm -A -t172.16.8.100:80 添加一个集群服务;
# ipvsadm -L -n
# ipvsadm -a -t 172.16.8.100:80-r 192.168.1.7[:8080] -m -w 2
# ipvsadm -a -t 172.16.8.100:80-r 192.168.1.8[:8080] -m -w 5
删除:
ipvsadm -d -t|u|fservice-address -r server-address
# ipvsadm -d -t 172.16.8.100:80-r 192.168.1.7
# ipvsadm -L –n
清空所有集群服务的定义:ipvsadm -C
清空所有服务定义:# ipvsadm -C
#ipvsadm -L -n
保持集群服务及RS的定义:
ipvsadm -S >/etc/sysconfig/ipvsadm
ipvsadm-save > /etc/sysconfig/ipvsadm
service ipvsadm save 直接保存到配置文件中.
===========================================================================
NAT模型:
环境要求:
两台内部的RS服务地址:
RS1:192.168.1.2 默认网关:192.168.1.1
RS2:192.168.1.3 默认网关:192.168.1.1
Director主机:VIP:172.16.8.100
RIP:192.168.1.1
配置:
RS1:
# vim/var/www/html/index.html
RS1.blue.com
# service httpd start
设定默认网关指向Director 主机:
# route add defaultgw 192.168.1.1
# route -n 进行验证
RS2:
# vim/var/www/html/index.html
RS2.blue.com
# service httpd start
设定默认网关指向Director 主机:
# route add defaultgw 192.168.1.1
# route -n 进行验证
Director主机:进行验证;
注意: 确保iptables 是放行状态,还有SELINUX是关闭的;
[root@localhost ~]# curlhttp://192.168.1.2
RS1.blue.com
[root@localhost~]# curl http://192.168.1.3
RS2.blue.com
配置ipvsadm规则:
# iptables -L -n -v 确保iptables规则都是空的;
# ipvsadm -A -t172.16.8.100:80 -s rr 轮询;
# ipvsadm -a -t172.16.8.100:80 -r 192.168.1.2 -m -w 1
# ipvsadm -a -t172.16.8.100:80 -r 192.168.1.3 -m -w 3
# ipvsadm -L -n
现在访问还是不能访问,查看核心转发是否打开了;
# cat/proc/sys/net/ipv4/ip_forward
0
开启,并让它永久生效:
# vim /etc/sysctl.conf
修改成:
net.ipv4.ip_forward = 1
# sysctl -p 立即生效;
访问:172.16.8.100
[root@localhost ~]# ipvsadm -L -n --stats
IP Virtual Server version 1.2.1(size=4096)
Prot LocalAddress:Port Conns InPkts OutPkts InBytes OutBytes
-> RemoteAddress:Port
TCP 172.16.8.100:80 198 976 949 127437 95539
-> 192.168.1.2:80 99 486 473 63414 47482
->192.168.1.3:80 99 490 476 64023 48057
修改调度算法类型:
# ipvsadm -E -t 172.16.8.100:80 -s wrr
[root@localhost ~]# ipvsadm -ln 权重比是1比3;
IP Virtual Server version 1.2.1(size=4096)
Prot LocalAddress:Port SchedulerFlags
-> RemoteAddress:Port Forward Weight ActiveConn InActConn
TCP 172.16.8.100:80 wrr
-> 192.168.10.2:80 Masq 1 0 31
->192.168.10.3:80 Masq 3 0 93
[root@localhost ~]# ipvsadm -L -n--stats
IP Virtual Server version 1.2.1(size=4096)
Prot LocalAddress:Port Conns InPkts OutPkts InBytes OutBytes
-> RemoteAddress:Port
TCP 172.16.8.100:80 323 1604 1572 210534 149387
-> 192.168.10.2:80 130 643 628 84202 63137
-> 192.168.10.3:80 193 961 944 126332 86250
# ab -n 10000 -c 100http://172.16.8.100/index.html
[root@localhost~]# ipvsadm -L -n --stats
IP Virtual Server version 1.2.1(size=4096)
Prot LocalAddress:Port Conns InPkts OutPkts InBytes OutBytes
-> RemoteAddress:Port
TCP 172.16.8.100:80 10353 51756 51722 3801354 5776205
-> 192.168.10.2:80 2637 13178 13163 981708 1469564
-> 192.168.10.3:80 7716 38578 38559 2819646 4306641
抓包方法:
#tcpdump -i eth0
# tcpdump -i eth0 src host 172.16.8.1
#tcpdump -i eth0 src host 172.16.8.1 and tcp port 80
============================================================================
Lvs-DR模型:
(1)各RS要直接响应Client,因此,各RS均得配置VIP;但仅能够让Director上的
VIP能够与本地路由直接通信;
(2)Director 不会拆除或修改请求报文的IP首部,而是通过封装新的帧首部
(源MAC为Director的MAC,目标MAC为挑选出的RS的MAC)完成调度;
示例:
RS1:RIP,eth0:17.16.8.11
VIP,lo0:172.16.8.200
RS2:RIP,eth0:17.16.8.12
VIP,lo:0: 172.16.8.200
DIP: eth017.16.8.100
VIP,eth0:0 : 172.16.8.200
RS1: lo接口可以,eth0接口也可以;
# cd/proc/sys/net/ipv4/conf/
# ls
# echo 1 >/proc/sys/net/ipv4/conf/all/arp_ignore
# echo 1 >/proc/sys/net/ipv4/conf/lo/arp_ignore
# echo 2 >/proc/sys/net/ipv4/conf/lo/arp_announce
#echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
# sysctl -a | grep arp 验证结果;
配置地址:
# ifconfig lo:0 172.16.8.200broadcast 172.16.8.200 netmask 255.255.255.255 up
# ifconfig
# ping 172.16.8.200
# arp -a 查看 MAC地址是谁的;
# ss -tnl 查看 http服务 是否启动;
物理机进行访问: 验证web服务是否正常;
172.16.8.11
172.16.8.12
添加路由条目:
# route add -host 172.16.8.200dev lo:0
RS2: lo接口可以,eth0接口也可以;
# cd/proc/sys/net/ipv4/conf/
# ls
# echo 1 >/proc/sys/net/ipv4/conf/all/arp_ignore
# echo 1 >/proc/sys/net/ipv4/conf/lo/arp_ignore
# echo 2 >/proc/sys/net/ipv4/conf/lo/arp_announce
# echo 2 >/proc/sys/net/ipv4/conf/all/arp_announce
# sysctl -a | grep arp 验证结果;
配置地址:
# ifconfig lo:0 172.16.8.200broadcast 172.16.8.200 netmask 255.255.255.255 up
# ifconfig
添加路由条目:
# route add -host 172.16.8.200dev lo:0
DIP:
配置VIP:
# ifconfig eth0:0 172.16.8.200netmask 255.255.255.255 broadcast 172.16.8.200 up
# ifconfig 限制广播范围;
# ipvsadm -C
# iptables -F
# route add -host 172.16.8.200 deveth0:0
#sysctl -a | grep ip_forward
打开转发功能:
# cat/proc/sys/net/ipv4/ip_forward
0
开启,并让它永久生效:
# vim /etc/sysctl.conf
修改成:
net.ipv4.ip_forward =1
# sysctl -p
添加规则:
# ipvsadm -A -t 172.16.8.200:80-s rr
# ipvsadm -a -t 172.16.8.200:80-r 172.16.8.11 -g -w 1
# ipvsadm -a -t 172.16.8.200:80-r 172.16.8.12 -g -w 3
# ipvsadm -Ln
==============================================================================
示例: 不在同一网络中;(根据上面示例进行修改即可;)
路由器地址:打开了路由间转发的功能的;
172.16.0.1
192.168.0.254
192.168.1.254
RS1:RIP,eth0:192.168.0.11
VIP,lo0:172.16.8.200
网关要指向:192.168.0.254
# ifconfig eth0192.168.0.11/24 up
# ping 192.168.0.254
# route add defaultgw 192.168.0.254
RS2:RIP,eth0:192.168.0.12
VIP,lo:0:172.16.8.200
网关要指向:192.168.0.254
# ifconfig eth0192.168.0.12/24 up
# ping 192.168.0.254
# ping 172.16.0.1
# route add defaultgw 192.168.0.254
DIP: eth0:192.168.0.10
VIP,eth0:0 :172.16.8.200
# ipvsadm -C
# ifconfig eth0192.168.0.10/24 up
# ifconfig
# ping 192.168.0.254
# ipvsadm -A -t172.16.100.7:80 -s rr
# ipvsadm -a -t172.16.100.7:80 -r 192.168.0.11 -g -w 1
# ipvsadm -a -t172.16.100.7:80 -r 192.168.0.12 -g -w 3
# ipvsadm -Ln
浏览器:172.16.100.7 进行访问;
======================================================================
DR类型RS脚本示例:
#!/bin/bash
#
vip=172.16.100.7
interface="lo:0"
case $1 in
start)
echo 1 >/proc/sys/net/ipv4/conf/all/arp_ignore
echo 1 >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
echo 2 >/proc/sys/net/ipv4/conf/lo/arp_announce
ifconfig $interface $vipbroadcast $vip netmask 255.255.255.255 up
route add -host $vip dev$interface
;;
stop)
echo0 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 0 >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo 0 >/proc/sys/net/ipv4/conf/all/arp_announce
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
ifconfig $interface down
;;
status)
if ifconfig lo:0 |grep $vip&> /dev/null; then
echo "ipvs isrunning."
else
echo "ipvs isstopped."
fi
;;
*)
echo "Usage: `basename $0` {start|stop|status}"
exit 1
esac
=============================================================================
lvs的persistence: lvs持久连接
无论使用哪一种调度方法,持久连接功能都能保证在指定时间范围之内,
来自于同一个IP的请求将始终被定向至同一个RS;
persistencetemplate:持久连接模板
PPC:每端口持久,持久连接的生效范围仅为单个集群服务;如果有多个集群服务,每服务 被单独持久调度;
例:
#ipvsadm -A -t 172.16.100.7 -s rr –p [#]
-p:不管是什么服务都被调度到同一个客户端上; 默认时长360秒;
PCC:每客户端持久;持久连接生效范围为所有服务;定义集群服务时,其TCP或UDP协议 的目标端口要使用0;
例:
# ipvsadm -A -t172.16.100.7:0 -s rr -p
0:表示持久一个客户端; 不管是什么服务都被调度到同一个客户端上;
PFWM:每FWM持久;持久连接生效范围为定义为同一个FWM下的所有服务;