LVS 纯理论:
VRRP协议与工作原理
在现实的网络环境中,主机之间的通信都是通过配置静态路由或者(默认网关)来完成的,而主机之间的路由器一旦发生故障通信就会失效,因此这种通信模式当中,路由器就成了一个单点瓶颈,为了解决这个问题就引入了VRRP协议,VRRP是一种主备模式的协议,通过VRRP可以在网络发生故障时透明的进行设备切换而不影响主机之间的数据通信,这其中涉及到两个概念:物理路由器和虚拟路由器;
VRRP可以将两台或者多台物理路由器设备虚拟成一个虚拟路由器,这个虚拟路由器通过虚拟IP(一个或者多个)对外提供服务,而在虚拟路由器内部N个物理路由器协同工作,同一时间只有一台物理路由器对外提供服务,这台物理路由设备被称为:主路由器(Master角色),一般情况下Master是由选举算法产生,它拥有对外服务的虚拟IP,提供各种网络功能,如:ARP请求,ICMP 数据转发等,
其它的物理路由器不具备Master的特性,只仅仅接收MASTER的VRRP状态通告信息,这些路由器被统称为“BACKUP的角色”,当主路由器失败时,处于BACKUP角色的备份路由器将重新进行选举来定义一个新的主路由器充当MASTER角色继续提供对外服务,整个切换对用户来说是完全透明的;
每个虚拟路由器都有一个唯一的标识号,称为VRID,一个VRID与一组IP地址构成一个虚拟路由器,在VRRP协议中,所有的报文都是通过IP多播方式发送,而在一个虚拟路由器中,只有处于Master角色的路由器会一直发送VRRP数据包,BACKUP角色的路由器只会接受Master角色发送过来的报文信息用来监控Master运行状态,而当MASTER不可用时,BACKUP也就无法收到Master发过来的信息,于是就认为Master出现故障,接着多台BAKCUP就会进行选举,优先级最高的BACKUP将称为新的MASTER,这种选举角色切换非常之快,因而保证了服务的持续可用性;
LVS后端服务健康状态检查:
elinks -dump http://..... #加dump是不显示交互式模式,把网页的内容下载,显示出来后就退出命令了,
curl --connect-timeout 1 http://.... #最多等待1秒钟,否则就不再访问
curl -I http://.... #使用head方法去请求,不获取网页的真正内容,只获取网页的响应首部
echo $0
curl的非0值有很多,man curl能查到非0值代表的意思
bash数组
RS=("192.168.0.2" "192.168.0.3") // 这个就是数组,array、element,也可以不加引号
echo ${RS[0]} //引用数组的第一个元素
echo $RS //默认引用数组的第一个元素
echo ${#RS} //统计变量长度
echo ${#RS[*]} //统计数组中元素的个数
vim health_check.sh (先运行脚本再重启或开启RIP服务)
#!/bin/bash
VIP=192.168.0.3
CPORT=80 //集群服务的端口是80
FALL_BACK=127.0.0.1 //定义备用主机,就是director主机自身
RS=(192.168.0.7 192.168.0.8)
decalare -a RSSTATUS
RW=(2 1)
RPORT=80 //real port
TYPE=g
CHKLOOP=3 //检查次数
LOG=/val/log/ipvsmoitor.log
addrs() {
ipvsadm -a -t $VIP:$CPORT -r $1:$RPORT -$TYPE -w $2
[ $? -eq 0 ] && return 0 || return 1
}
delrs() {
ipvsadm -d -t $VIP:$CPORT -r $1:$RPORT
[ $? -eq 0 ] && return 0 || return 1
}
checkrs() {
local I= 1
while [ $I -le $CHKLOOP ]; do
if curl --connect-timeout 3 http://$I &> /dev/null; then
return 0
fi
let I++
done
return 1
}
initstatus() {
local I
local COUNT0;
for I in ${RS[*]}; do
if checks $I; then
RSSTATUS[$COUNT]=1
else
RSSTATUS[$COUNT]=0
fi
let COUNT++
done
}
initstatus
while :; do
let COUNT =0
for I in ${RS[*]}; do
if checks $I; then
if [${RSSTATUS[$COUNT]} -eq 0 ]; then
addrs $I ${RW[$COUNT]}
[ $? -eq 0 ] && RSSTATUS[$COUNT]=1 && echo "`date + '%F %H:%M:S'`,$I is back." >> $LOG
fi
else
if [ ${RSSTATUS[$COUNT]} -eq 1 ]; then
delrs $I
[ $? -eq 0 ] && RSSTATUS[$COUNT]=0 && "`date + '%F %H:%M:%S'`,$I is gone." >> $LOG
fi
fi
let COUNT++
done
sleep 5
done
持久连接模板(就是内存缓冲区):
每一次连接都会检查这个模板,如果第一个连接的客户端在这模板且未超时就会把第一次分配给客户端的RS再次分给客户端
PPC: (持久端口连接)
将来自于同一个客户端对同一个集群服务的请求,始终定向至此前选定的RS
PCC: (持久客户端连接)
将来自同一个客户端对同一个集群服务的请求所有端口的请求始终定向至此前选定的RS
PNMPP:(持久防火墙标记连接)
定义端口间的姻亲关系
PPC持久链接步骤:
ipvsadm -E-t 192.168.1.x:80 -s rr //改算法,将wlc改为rr
ipvsadm -E-t 192.168.1.x:80 -s rr -p 600 //持久化链接, 将默认的300秒改为600秒
ipvsadm -L -n --persisten-conn // 查看持久链接(PersistConn持久链接,InActConn命中率)
ipvsadm -A -t 集群地址+端口 -s rr //例:把23号端口添加到集群中
ipvsadm -a -t 集群地址+端口 -r RIP地址 -g -w 2 //添加RIP的地址到集群中
ipvsadm -C //清空所有规则
PCC持久链接步骤:(把所有端口统统定义为集群服务,一律向RS转发)
ipvsadm -A -t 集群地址:0 -s rr
ipvsadm -a -t 集群地址:0 -s RIP地址 -g -w 2 //0端口意味着所有端口的请求统统都是集群服务
ipvsadm -L -n -c //查看连接请求
PNMPP持久链接步骤:(一般80和443协同绑定使用)
例:所有对VIP上的80和23号端口的请求都打同一个标记
iptables -t mangle -A PREROUTING -d VIP地址 -p tcp --dport 80 -j MARK --set-mark (0-99之间的整数)
iptables -t mangle -A PREROUTING -d VIP地址 -p tcp --dport 443 -j MARK --set-mark 5
//这一样就定义了一个防火墙为5的标记
ipvsadm -A -f 5 -s rr
ipvsadm -E -f 5 -s rr -p 600 //定义持久连接
ipvsadm -a -f 5 -r RIP地址 -g -w 2
ipvsadm -a -f 5 -r RIP地址 -g -w 2
//也就是说每当客户端用80、443来连接集群时都将进入轮询算法,其他连接DIP将作出响应,rr算法中权重不受影响
sersync比inotify+rsync要强,sersync支持多线程并发访问并支持大文件传输,由金山用c++开发
LVS本身没有故障转移的功能,如果realserver出了故障后ipvsadm能切换或者剔除realserver,当然这只是针对realserver。
如果director出了问题那.....
为了解决这种单点故障才引入了keepalived,原本是用在网络领域中,Keepalived 是运行在lvs的基础上,能实现真机的故障隔离及负载均衡器间的失败切换及提供健康检查,提高系统的可用性;
LVS的持久连接
无论使用哪种算法,LVS都能实现将来自于同一个客户端的请求,在一定时间内始终定向到同一个real server上的这种机制就叫做持久连接。
只要是持久连接都会破坏负载均衡的效果。。。。。。
之所以web要用到持久连接就是因为session、cookie,如果能在realserver之间通过集群将session共享的话可以不用持久连接
共享持久连接,php支持用memcached做缓存服务器来将所有session保存在缓存服务器中,memcached是高性能的缓存服务器它能给各种场景提供缓存功能,memcached本身不是服务而是一个编程的API
DR原理:
DR和REALSERVER都使用同一个IP对外服务。但只有DR对ARP请求进行响应,所有REALSERVER对本身这个IP的ARP请求保持静默,
也就是说网关会把对这个服务IP的请求全部定向给DR,而DR收到数据包后根据调度算法找出对应的REALSERVER,把目的MAC地址改为 REALSERVER的MAC并发给这台REALSERVER。
这时REALSERVER收到这个数据包,则等于直接从客户端收到这个数据包而已,处理后 直接 返回给客户端,由于DR要对二层包头进行改换,所以DR和REALSERVER之间必须在一个广播域,也可以简单的理解为在同一台交换机上
DR模式:
每个集群节点跟dr必须在同一个物理网络(局域网)当中(dr和web不能隔了有路由器);
VIP可以使用公网地址,实现远程管理和监控;
director只负责处理进站请求,响应的请求封装后直接由Relserver发给客户端;
Realserver不能将Direc当作网关。只能选择前当网关;
Direc不能支持端口映射。VIP的端口必须和WEB服务端口一致;
大多数的操作系统都可以应用在relserver上;
Director性能比NAT在处理速度提高N倍;
LVS负载均衡的三种模式:NAT、TUN、DR
LVS负载均衡的八种调度算法(依次按顺序)
rr算法:
轮询调度(Round-RobinScheduling)
wrr算法:
加权轮询调度(WeightedRound-RobinScheduling)
lc算法:
最小连接调度(Least-ConnectionScheduling)
wlc算法:
加权最小连接调度(WeightedLeast-ConnectionScheduling)
lblc算法:
基于局部性的最少链接(Locality-BasedLeastConnectionsScheduling)
lblcr算法:
带复制的基于局部性最少链接(Locality-BasedLeastConnectionswithReplicationScheduling)
dh算法:
目标地址散列调度(DestinationHashingScheduling)
sh算法:
源地址散列调度(SourceHashingScheduling)
其中rr、wrr、sh、dh是静态的,其他是动态的
Keepalvied的工作原理
Keepalived通过VRRP来实现高可用性,而Keepalived作为一个高性能集群软件,它还能实现对集群中服务器运行状态的监控以及故障隔离;
Keepalived对服务器运行状态和故障隔离的工作原理:
Keepalived工作在TCP/IP 参考模型的 三层、四层、五层(网络层、传输层、应用层)根据TCP、IP参数模型隔层所能实现的功能
Keepalived运行机制:
在网络层: 网络层运行这4个重要的协议,
IP协议、
互联网络可控制报文协议ICMP、
地址转换协议ARP、
反向地址转换协议RARP
在网络层Keepalived采用的最常见的工作方式是通过ICMP协议向集群中的每一个节点发送一个ICMP数据包(有点类似与Ping的功能),如果某个节点没有返回响应数据包,那么认为该节点发生了故障,Keepalived将报告这个节点失效,并从服务器集群中剔除故障节点;
在传输层: 提供了两个主要的协议:
传输控制协议TCP
用户数据协议UDP,
TCP可以提供可靠的数据输出服务、IP地址和端口,代表TCP的一个连接端,要获得TCP服务,需要在发送机的一个端口和接收机的一个端口上建立连接,而Keepalived在传输层里利用了TCP协议的端口连接和扫描技术来判断集群节点的端口是否正常,比如对于常见的WEB服务器80端口(或者22端口),Keepalived一旦在传输层探测到这些端口号没有数据响应和数据返回,就认为这些端口发生异常,然后强制将这些端口所对应的节点从服务器集群中剔除掉;
在应用层:可以运行FTP,TELNET,SMTP,DNS等各种不同类型的高层协议,Keepalived的运行方式也更加全面化和复杂化,用户可以通过自定义Keepalived工作方式(编写程序或脚本来运行Keepalived)而Keepalived将根据用户的设定参数检测各种程序或者服务是否允许正常,如果Keepalived的检测结果和用户设定的不一致时,Keepalived将把对应的服务器从服务器集群中剔除;
Keepalived 是运行在lvs 的基础上,主要功能是实现真实机的故障隔离及负载均衡器间的失败切换,提高系统的可用性;
Keepalived体系结构:
Keepalived起初是为LVS设计的,由于Keeplalived可以实现对集群节点的状态检测,而IPVS可以实现负载均衡功能,因此,Keepalived借助于第三方模块IPVS就可以搭建一套负载均衡系统,(坑1:Keepalived不是单纯的是一个负载均衡软件,在Keepalived当中IPVS模块是可配置的,如果需要负载均衡功能,可以在编译Keepalived时开打负载均衡功能,也可以通过编译参数关闭)
用户空间层,主要有4个部分:
Scheduler I/O Multiplexer: 是一个I/O复用分发调度器,它负责安排Keepalived所有内部的任务请求;
Memory Mngt:是一个内存管理机制,该框架提供访问内存的一些通用方法;
Control Plane: 是keepalived的控制版面,可以实现对配置文件编译和解析;
Core componets: 这部分主要保护了6个部分:
Watchdog:是计算机可靠领域中极为简单又非常有效的检测工具,Keepalived正是通过它监控Checkers和VRRP进程的;
Checkers: 这是Keepalived最基础的功能,也是最主要的功能,可以实现对服务器运行状态检测和故障隔离;
VRRP Stack: 这时keepalived后来引用VRRP功能,可以实现HA集群中失败切换功能;
IPVS wrapper: IPVS功能的一个实现,IPVS warrper模块将设置好的IPVS规则发送的内核空间并且提供给IPVS模块来实现IPVS模块的负载功能;
Netlink Reflector:用来实现高可用集群Failover时虚拟IP(VIP)的设置和切换 ;
Netlink Reflector的所有请求最后都发送到内核空间层的NETLINK 模块来完成;
使用负载均衡技术的理由:
假如有一个咨询类的网站,只允许100个用户同时在线访问,网站上线初期,由于知名度比较小只有几个用户经常上线,后期知名度提高了,百度和谷歌又收录了该网站,于是同时在线的用户量上升,很快达到了上千人,于是网站负荷加重了,经常会“反应迟钝”,这时用户开始抱怨,为了不影响用户的使用,就一定要想办法解决这个问题,试想如果有几台或者几十台相同配置的机器,前端放一个转发器,轮流转发客户对网站的请求,每台机器将用户数控制在100以内,那么网站的反应速度就会大大提高,即使其中的某台服务器因为硬件故障了挂了也不会影响用户的访问,这里说的转发器就是负载均衡(Director),也就是说通过负载均衡器可以实现N台廉价的Linux服务器并行处理(带宽、吞吐量等),来达到小型机或者大型机计算能力,这也是为何负载均衡如此流行的原因;
向上扩展: 就是硬件升级,硬件升级的弊端就是如果架构设计不好性能不但不会提升而且会下降
向外扩展: 就是Load Balancing:LB (负载均衡技术)
Ø 系统高可用性
Ø 系统可扩展性
Ø 负载均衡能力
LVS+keepalived能很好的实现以上的要求,LVS提 供负载均衡,keepalived提供健康检查,故障转移,提高系统的可用性!采用这样的架构对以后 很容易对现有系统进行扩展,只要在后端添加或者减少realserver 和更改lvs的 配置文件即可
LVS(开源)Linux Virtual Server(Linux虚拟服务器)
这里只说DR模式,因为其他2个不怎么常用.....(记住NAT和TUN模式都是工作在网络层上(三层),DR模式工作在数据链路层(二层)就行)
keepalived详解:
nginx是个轻量级的web同时也是一个轻量级的web反向代理
harproxy是非常轻量级高性能的web反向代理
keepalived + nginx
keepalived + harproxy
//这两种是常见的高可用解决方案
在keepalived.conf中的virtual_server中添加sorry_server
格式:127.0.0.1 80 //就是说如果所有的realserver都挂了就添加sorry_server,该目的只用在所有realserver都挂了的时候,客户来访问时都访问不到后来方位DIP上的80端口,如写个维护的标语等情况
ps auxf //f可以显示进程树
自写检测脚本完成维护模式切换:
vim keepalived.conf //master端和salve端都得写
vrrp_svript chk_schedown {
script "[ -e /etc/keepalived/down ] && exit 1 || exit 0" //如果keepalived目录中有了down文件就认为挂了
inerval 3 //每隔多少秒时间检测一次
weight -2 //一旦检测失败了权重就减2
fall 2 //检测2次后都失败了才认为realserver挂了
rise 1 //如果检测成功了就立即成功
}
//该方法定义脚本时一定要在keepalived.conf中的实例之外定义,chk_schedown可以换名字
//然后在virtual_address下面定义什么时候执行上面定义好的脚本,如下:
track_script {
chk_schedown
}
service keepalived restart 后生效
在master端的/etc/keepalived/目录中touch一个down文件,tail以下/var/log/messages,会有消息说master端因优先级低而被slave端剔除
在vrrp事故发生时发邮件给指定的管理员
vim /etc/keepalived/new_notify.sh //主备上相同的位置都要有这个脚本
contack='root@localhost'
Usage(){
ehco "Usage:`basename $0` {master | backup |fault} VIP"
}
Notify(){
subject="`hostname`'s state changed to $1"
mailbody="`date "+%F %T"`:`hostname`'s state change to $1,$vip floating."
echo $mailbody | mail -s "$subject" $contact
}
[ $# -lt 2 ] && Usage exit
VIP=$2
case $1 in
master)
Notify master
;;
backup)
Notify backup
;;
fault)
Notify fault
;;
*)
Usage
exit1
;;
esac
bash -n new_notify.sh
bash -x new_notify.sh
bash -x new_notify.sh master 1.1.1.1 //进行测试
在track_script 下面加入:
notify-master "/etc/keepalived/new_notify.sh master master地址"
notify-backup "/etc/keepalived/new_notify.sh backup master地址"
notify-fault "/etc/keepalived/new_notify.sh fault master地址"
//主备都要添加这3句
service keepalived restart