龙空技术网

干货 | 基于keepalived高可用的应用实战

思快奇 1012

前言:

如今姐妹们对“脑裂 keepalived”大致比较关切,同学们都想要剖析一些“脑裂 keepalived”的相关知识。那么小编在网摘上搜集了一些有关“脑裂 keepalived””的相关资讯,希望各位老铁们能喜欢,姐妹们一起来了解一下吧!

文章来源:思快奇(微信公众号)

背景

最近由于监管合规之反洗钱要求,上线了OCR身份证识别系统,但是供应商提供的架构方案中有单点故障的不完美之处,虽然以现有的交易规模和业务模式来讲,单套服务具备承接业务峰值的能力,但是作为集群服务和高可用遍地的互联网时代,高效的架构不仅可以避免单点故障(不会出现某个服务或者某台服务器故障导致整个应用不可使用),还可以提高系统运维质量,确保服务的高可用(High Availability)。

负载均衡

说到高可用,就要先说说负载均衡。常见的互联网架构最外面的F5就是典型的负载均衡处理设备。负载均衡器是数据中心的切入点,处于后续一切服务的关键路径。这部分的应用也很多,如果是比较小的网站(日PV<1000万),用nginx就完全可以了,如果机器也不多,访问量不大,也可以用DNS轮询;大型网站或者重要的服务,可以考虑利用LVS或者商用F5设备。一般四层负载使用LVS软件或F5硬件实现,七层负载使用nginx实现,至于网络四层负载和七层负载的区别以及nginx、LVS和F5等的区别有兴趣的可以研究下。下图便是经典的负载实现架构:

高可用

回到高可用,我们选择了Keepalived,其期初是专为LVS负载均衡软件设计的,用来管理并监控LVS系统各个服务节点的状态,后来加入了可以实现高可用的VRRP功能。因此Keepalived除了能管理LVS软件外,还可以作为其他服务(例如:Nginx、Haproxy、Mysql等)的高可用解决方案软件。Keepalived的作用是检测服务器的状态(注意是服务器层面不是应用层面),如果有一台web服务器宕机,或工作出现故障,Keepalived将检测到,并将有故障的服务器从系统中剔除,同时使用其他服务器代替该服务器的工作,当服务器工作正常后Keepalived自动将服务器加入到服务器群中,这些工作全部自动完成,不需要人工干涉,需要人工做的只是修复故障的服务器。它能够保证当个别节点宕机时,整个网络可以不间断的运行。

一般来讲,直接在需要实现高可用的服务器中部署Keepalived即可,但是本次的OCR服务是C/S实现的Windows服务,而keepalived是linux的专有软件,所以必须在OCR服务之前架设高可用转发服务,我们选择了nginx的stream转发模块来完整这个处理,并且将原来的一路OCR服务分成多路,通过NAS盘共享存储和nginx负载均衡来达到集群效果。从理论值来做一个架构优化后的对比,假设原单路OCR处理能力是100并发,现在因一台nginx的最大并发量达50000,所以并发限制在分了N路负载决定,处理能力提升N倍,且不会有单点故障(之前的日志分析平台ELK架构中也可以引入改HA模式)。

脑裂问题

高可用一般有一个数据安全的隐患就是脑裂问题。在高可用(HA)系统中,当联系2个节点的“心跳线”断开时,本来为一整体动作协调的HA系统,就分裂成为2个独立的个体。由于相互失去了联系,都以为是对方出了故障。两个节点上的HA软件像“裂脑人”一样,争抢“共享资源”、争起“应用服务”,就会发生严重后果,比如共享资源被瓜分、2边“服务”都起不来了;或者2边“服务”都起来了,但同时读写“共享存储”,导致数据损坏。

Keepalived软件主要是通过VRRP协议实现高可用功能的。VRRP是Virtual Router Redundancy Protocol(虚拟路由冗余协议)的缩写,其用IP组播的方式(默认组播地址: 224.0.0.18), 实现服务节点间的通信,定期向服务器群中的服务器发送一个ICMP的数据包(既Ping程序),如果发现某台服务的IP地址没有激活,Keepalived便报告这台服务器失效, 通过一种竞选机制来将路由任务交给某台VRRP路由器. 工作时主节点发送VRRP协议报文, 备节点接收报文, 若一段时间(默认3个报文发送时间)备节点接收不到主节点发送的报文, 就会启动接管程序接管主节点的资源. 备节点可以有多个, 通过优先级竞选。从原理上也可以看出VRRP协议出现的目的就是为了解决静态路由单点故障问题。

从上述工作原理知道, 备节点接收不到报文时, 如两者间的网络不通了, 备节点就会启动接管程序接管主节点的资源, 对外提供服务, 表现形式就是备节点上出现了虚拟IP, 此时主节点也是持有虚拟IP的.出现脑裂问题,对付HA系统“裂脑”的对策,目前大概有以下方式:

1)添加冗余的心跳线。例如:双线条线(心跳线也HA),尽量减少“裂脑”发生几率;

2)启用磁盘锁。正在服务一方锁住共享磁盘,“脑裂”发生时,让对方完全“抢不走”共享磁盘资源。但使用锁磁盘也会有一个不小的问题,如果占用共享盘的一方不主动“解锁”,另一方就永远得不到共享磁盘。现实中假如服务节点突然死机或崩溃,就不可能执行解锁命令。后备节点也就接管不了共享资源和应用服务。于是有人在HA中设计了“智能”锁。即:正在服务的一方只在发现心跳线全部断开(察觉不到对端)时才启用磁盘锁。平时就不上锁了。

3)设置仲裁机制。例如设置参考IP(如网关IP),当心跳线完全断开时,2个节点都各自ping一下参考IP,不通则表明断点就出在本端。不仅“心跳”、还兼对外“服务”的本端网络链路断了,即使启动(或继续)应用服务也没有用了,那就主动放弃竞争,让能够ping通参考IP的一端去起服务。更保险一些,ping不通参考IP的一方干脆就自我重启,以彻底释放有可能还占用着的那些共享资源。

实施过程

有了相关理论的调研,我们将知识点和可能碰到的问题梳理清楚便可以实施,主要涉及nginx的安装、keepalived部署及脑裂处理三个步骤

1、Nginx安装:

--检查安装环境,是否符合 nginx默认安装的时候无法加载流stream模块,需要在启动参数里加上-–with-stream。./configure --with-stream make && make install 配置服务并开机启动(systemctl enable nginx) /lib/systemd/system/nginx.service [Unit] Description=nginx After=network.target [Service] Type=forking ExecStart=/usr/local/nginx/sbin/nginx ExecReload=/usr/local/nginx/sbin/nginx reload ExecStop=/usr/local/nginx/sbin/nginx quit PrivateTmp=true [Install] WantedBy=multi-user.target --启动nginx systemctl start nginx.service --结束nginx systemctl stop nginx.service --重启nginx systemctl rest

2、keepalived部署

HA模式

Ip(安全考虑这里为非真实IP)

VIP

192.168.1.10

主机(master node)

192.168.1.8

备机(backup nod)

192.168.1.7

配置yum源(点击参考),如果是离线的挂载ios盘,默认系统安装即可

yum install -y keepalived

主机关键配置(注意keepalived 的global_defs模块中vrrp_strict 参数会严格执行VRRP协议规范,此模式不支持节点单播,如果配置会引起vip无法ping通,建议去掉)

备机关键配置

注.由于keepalived是四层服务,只有ping不通的情况才会切换到备机,当Nginx宕机,会导致用户请求失败,但是keepalived不会进行切换,所以要在主备机的配置中增加一个nginx的脚本监控,防止转发服务不可用。

3、脑裂处理

关闭防火墙或者加入防火墙过滤规则

-A INPUT -s 192.168.1.0/24 -d 224.0.0.18 -jACCEPT #允许组播地址通信

-A INPUT -s 192.168.1.0/24 -p vrrp -jACCEPT #允许VRRP(虚拟路由器冗余协)通信

根据vrrp的原理,在备机添加监控脚本如下(注意脚本的编码格式):

简单解释下处理逻辑,如果备机和主机能ping通,而且在备机上也发现了VIP的漂移,那么就判断为脑裂产生了,关闭keepalived服务,如果备机和主机不能ping通,且在备机上发现了VIP的漂移,我们认为是正常的HA切换。互联网上还有一种方案通过网关仲裁的方式判断,说如果自己的网关参考不通,那么表示脑裂,也不失为一种方案,但是这个我们认为可以纳入服务监控的范畴了,连服务器断网都发生了,脑裂就已经不重要了,不是吗?

综上所述,一个优秀的系统最终都是向人类智慧靠近,这里的高可用就好比人行走的两条腿,左脚为主机,右脚为备机,每一次的跨步行走都是流畅的主备切换,如果两条腿同时迈出去肯定会摔倒的,就好比HA的脑裂问题了。

参考资料:

CSDN:keepalived是如何解决或者防止脑裂问题的?

百度百科:LVS

其他网络资料

标签: #脑裂 keepalived