当前位置: 首页 > 科技观察

一次keepalived高可用事故,让我又学会了!_0

时间:2023-03-14 16:03:48 科技观察

上次遇到MySQL故障事件,这次又遇到奇葩问题:Keepalived高可用组件虚拟IP不断漂移,导致MySQL主从不断切换,进而导致MySQL主从数据同步失败。虽然无法重现Keepalived的问题,但是我还是深入研究了Keepalived的原理,对核心配置参数做了很多实验。悟空带大家看看Keepalived是怎么工作的,为什么可以高可用。一、Keepalived和LVS概述1.1Keepalived概述说到Keepalived,给人的印象就是用在高可用架构中,保证一个服务不会失效。事实上,它还有很多其他的功能。Keepalived是Linux系统下一个比较轻量级的高可用方案。这种轻量化是相对于Heartbeat等组件来说的。Heartbeat虽然功能齐全,专业性强,但是安装部署不像Keepalived那么简单。Keepalived只需要一个配置文件。大多数企业选择Keepalived作为高可用组件。1.2LVS概述Keepalived最初是由AlexandreCassen用C语言编写的一个开源软件项目。该项目的目的是简化LVS项目的配置,增强LVS的稳定性。简单的说,Keepalived是对LVS的扩展和增强。LVS(LinuxVirtualServer)译为LinuxVirtualServer,由张文松博士开发的开源负载项目。目前,LVS已经集成到Linux内核模块中。LVS主要用于负载均衡。例如,如果Web客户端要访问后端服务,Web请求首先会经过LVS调度器,调度器根据预设算法决定如何分发到所有后端服务器。1.3LVS基本原理LVS基本原理如下图所示:LVS基本原理LVS的核心功能是提供负载均衡,负载均衡技术有多种:基于DNS域名轮换解析方案。根据客户端安排访问计划。基于应用层系统的调度方案。基于IP地址的调度方案。最有效的调度方案是基于IP地址。其实就是把请求转发到对应的IP地址+端口号。它的效率非常高。LVS的IP负载均衡技术是通过IPVS模块实现的。IPVS是LVS集群系统的核心软件。LVS负载均衡器会虚拟出一个IP(VIP)。对于客户端来说,它事先只知道VIP,客户端会向VIP发送请求,然后LVS负载均衡器将请求转发给后端服务器,其中一台服务器称为RealServer(真实服务器)。转发规则是通过设置LVS的负载均衡算法得到的,比如随机分配、权重分配等,后端服务器提供的功能需求是一致的,无论转发到哪个服务器,最终的结果都是同样,那么对于客户端来说,它并不关心有多少后端服务器在提供服务,它只关心有多少VIP正在访问。那么后端服务处理完请求后如何将数据返回给客户端呢?根据不同的LVS模式,会选择不同的方式返回数据给客户端。LVS有三种工作模式:NAT模式、TUN模式和DR模式。这将在后面的路由机制中讨论。2、Keepalived流量转发原理Keepalived为Linux系统提供负载均衡和高可用能力。负载均衡能力来源于Linux内核中的LVS工程模块IPVS(IPVirtualServer)。Keepalived运行在Linux系统上,它在内核中启动LVS服务来创建一个虚拟服务器。比如我们在两台服务器上都启动一个Keepalived服务,然后LVS会虚拟出一个IP(VIP),但是只有一个Keepalived会接管这个VIP,也就是说客户端的请求只会到MasterKeepalived节点。这样流量只会走一个keepalived,然后keepalived可以配置几个真实的服务IP地址和端口,通过负载调度算法把流量分配给这些服务。对于另一个BackupKeepalived节点,处于待机状态,没有流量接入。3、Keepalived是如何选主的?那么以上两个Keepalived服务是如何选择其中一个作为Master节点的呢?我们一般运行在两主备服务器或者一主多备服务器上。而这些多台服务器遵循VRRP。3.1VRRP协议VRRP的全称是VirtualRouterRedundancyProtocol,虚拟路由器冗余协议。它是一种容错协议,为了解决局域网中单点路由失败的问题。比如之前我们使用路由器进行路由转发。如果这台路由器出现故障,整个路由转发链路将中断,服务将不可用。VRRP协议的主要功能:虚拟路由器和虚拟IP。Master广播ARP数据包。Backup选出新的Master。现在我们配置多台路由器(一主多备),每台路由器都有自己的IP地址,它们组成一个路由器组,其中一台为Master,其余为Backup。然后这些路由器会虚拟出一条单独的路由,有自己的IP地址,即VirtualIP,简称VIP。客户端可以访问这个虚拟IP地址。当主路由器发生故障时,备份路由器将通过选举机制选举出新的主路由器,继续为客户端提供路由服务,实现路由功能的高可用性。路由器使能VRRP功能后,根据配置的优先级进行选举。优先级最高的路由器将成为主(Master)路由器,其他路由器将成为备份(Backup)路由器。Master路由器周期性地向Backup路由器发送VRRP通知消息,告诉它们我工作正常,你不需要再跑新的Master路由器了。Master和Backup之间的通信原理其实很简单,就是心跳机制,只不过这个和Eureka的心跳机制不同。Eureka是client周期性向Eureka注册中心发送心跳的机制,而Keepalived是Master周期性向Backup发送心跳的机制。备份路由器的任务是定期监控通知。如果在这段时间内没有收到通知,就认为Master失败了,然后根据优先级进行选举。选举出新的Master后,会周期性的发送VRRP通知报文。到备份路由器。(尤里卡心跳机制:唐太宗把微服务的“心跳机制”发挥到了极致!)通过这个VRRP协议,可以提高系统的可用性,避免单点故障导致的服务不可用。出现故障时,无需手动修改网络连接信息即可访问新的Master路由器。如下图,Backup切换为Master。选的配置主要看vrrp_instance和vrrp_script两个字段。3.2vrrp_instance配置Keepalived选主有3个重要参数:state:可选值为MASTER和BACKUP。priority:节点的优先级,可选值为[1-255]。nopreempt:无抢占模式,如果配置了,当优先级高的时候,会把自己设为Master。vrrp_instanceVI_1{#节点为BACKUP状态BACKUP#优先级为100priority100#无抢占模式nopreempt}当一个设为master,另一个设为BACKUP时,当MASTER失效时,BACKUP会成为新的MASTER,而当oldmaster恢复后,会抢占成为新master,接管VIP的流量,造成不必要的主备倒换。为了避免这种主备切换,我们可以将两个Keepalived都设置为BACKUP,将优先级高的Keepalived设置为不可抢占nopreempt。3.2vrrp_script配置的优先级可以增减,可以通过vrrp_script配置:vrrp_scriptrestart_mysql{#监控并重启mysql容器,如果MySQL服务正常或者MySQL失败script"/usr/local/keepalived/restart_mysql.sh"interval5weight-20}这个是定时执行脚本的配置,脚本配置会监控mysql服务是否异常。这是一个自定义脚本,你可以写你自己的返回值。我这里写的逻辑是mysql服务正常就返回0,不正常就返回1。(1)当权重为正数且脚本返回0(服务正常)时,则增加优先级=优先级+权重;否则,保持设置的优先级值。切换策略:如果MASTER节点的vrrp_script脚本检测失败,如果MASTER节点的优先级值小于BACKUP节点的权重+优先级,就会发生主备切换。如果MASTER节点的vrrp_script脚本检测成功,如果MASTER节点的优先级值大于BACKUP节点的权重+优先级,则不会发生主备切换。(2)当权重为负且脚本返回非零(服务异常)时,则priority=priority-|weight|;否则,保持设置的优先级值。切换策略:如果MASTER节点的vrrp_script脚本检测失败,如果优先级-|weight|MASTER节点的值小于BACKUP节点的优先级值,就会发生主备倒换。如果MASTER节点的vrrp_script脚本检测成功,如果MASTER节点的优先级值大于BACKUP节点的优先级值,则不会发生主备倒换。注意:增加或减少优先级的范围是[1,254]。例如:两个keepalived的状态都配置为BACKUP,其中一个服务器node1的keepalived优先级设置为100,不抢占模式,另一个node2的优先级设置为90,抢占模式。node1节点配置优先级高,成为Master节点。当Master节点监控的MySQL服务出现故障时,优先级会从100降为80,另外一个优先级为90,当收到比自己低优先级的ARP广播时,就会成为新的Master节点。node1节点将成为备份节点。当node1监听到MySQL服务恢复后,优先级会变为配置的优先级100,但不会被抢占。如下图所示:node1上的keepalived虽然重启mysql成功,优先级也恢复到100,但是并没有成为master,依然保持backup状态。而node2仍然是master节点,定时向node1发送vrrp通知,如下图:如果node2的mysql宕机,它的优先级会从90降到70,即便如此,也没有master-standbyswitchover,因为我们配置的策略是node1不会抢占。这种情况下如果要切换到node1,只能主动停止node2的keepalived,这个在failover中间部分会提到。4.Keepalived的负载均衡机制4.1转发机制要了解Keepalived的负载均衡机制,就必须了解IPVS,即IPVirtualServer,IP虚拟服务器。IPVS模块是Keepalived推出的第三方模块。目的是解决单一IP多台服务器的工作环境。通过IPVS可以实现基于IP的负载均衡集群。IPVS默认包含在LVS软件中,而LVS软件又包含在Linux系统中。所以Keepalived在Linux系统上可以直接使用LVS的功能。LVS的作用是虚拟出一个IP,也就是VIP。客户端请求首先到达VIP,然后从服务器集群中选择一个服务器节点,将流量转发到这个节点,由该节点处理请求。如图:Keepalived是一个运行在用户空间的LVS路由(LVSRouter)进程。Keepalived在MASTER角色中称为ActiveRouter,在BACKUP角色中的Keepalived称为SLAVERouter。只有ActiveRouter在工作,其他Router处于StandBy(待机状态)。Active路由器和Backup路由器通过VRRP协议进行切换。ActiveRouter会在内核中启动LVS服务创建一个虚拟服务器。虚拟服务器有一个虚拟IP(VIP)。例如下图中的VIP为192.168.56.88。ActiveRouter也会设置IPVSTABLES(服务器列表),记录后端服务器地址和服务运行状态。负载均衡从服务器列表中选择一个可用的服务进行转发。这些后端服务是在Keepalived的virtual_server配置项中配置的。如下图,配置了三个real_server,对应三个后端服务器。virtual_server192.168.56.8880{delay_loop6lb_algorrlbkindNATprotocoltcp#服务器1real_server192.168.56.1180{TCP_CHECK{connecttimeout10}#服务器2real_server192.168.56.1280{TCP_CHECK{connecttimeout10}#服务器3real_server192.168.56.1380{TCP_CHECK{connecttimeout10}4.2loadschedulingalgorithmconfiguration中有一个字段lb_algo,就是负载调度算法,可以配置为rr,wrr,lc,wlc,sh,dh等,常用的使用的是rr和wrr。rr,就是Round-Robin,循环算法,每个服务器都是平等的,依次调度。wrr,WeightedRound-Robin,加权轮询调度算法,权重值越大,转发的请求越多。例如,如果某些服务器的硬件能力较弱,则可以将权重值配置得较低。lc是Least-Connection,最少连接算法。请求被转发到活动连接较少的服务器。连接数通过IPVS表动态跟踪。wlc,加权最少连接数。根据权重+连接数分配请求。sh,目的地址哈希算法,服务器通过查询静态哈希表中的目的IP地址来决定转发请求。这类算法主要用于缓存代理服务器。dh,源地址哈希算法,通过查询静态哈希表中的源IP地址来决定服务器转发请求。这类算法主要用在防火墙的LVSRouter中。5.总结Keepalived作为一个高可用和高性能的组件,在集群环境下使用还是比较多的,所以了解Keepalived的底层原理,也可以学到很多高可用和负载均衡的通用原理.本文介绍Keepalived的IPVS功能,启动一个虚拟服务器,虚拟出一个VIP来接收客户端请求,然后通过负载调度算法将流量转发到真实服务器。Keepalived一般用于一主一备或一主多备的场景,通过配置state、priority、nopreemt、weight字段实现master的选举。下一篇文章,我们来看看真实服务器在处理完请求后,是如何将数据返回给客户端的。这就涉及到LVS的路由规则了。而监控和故障转移也是Keepalived的核心功能,有必要深入探讨。