Keepalived高可用

什么是高可用

在我们常见的架构中,都存在重要业务服务器单点问题,一旦出现单点故障,整个业务就会中断,从而造成经济损失。为了解决重要业务的单点故障的问题,通常做法是重要业务多台部署,多台运行,主从式,一旦某台服务器出现故障,另一台备用服务器可以马上顶替,这种做法我们通常叫做高可用(High Available),而高可用性负载均衡通常是指keepalived+nginx proxykeepalived+LVS等。

常用的HA组建工具

Keepalived
Keepalived
Heartbeat
Heartbeat

注: Heartbeat通常和DRBD搭配使用。

目前常使用keepalived做高可用设计,keepalived基于VRRP虚拟路由冗余协议(Virtual Router Redundancy Protocol RFC2338),通过在系统上添加VIP(虚拟IP)地址实现,在master出现问题无法访问时可平滑切换到backup主机上面,这一切的动作对于用户来说均是无感的,非常适用于对业务持续可访问性要求较高的场合。

安装

RHEL类系统下的安装:

yum install keepalived -y
#或
dnf install keepalived

Debian类系统下的安装:

sudo apt install keepalived

配置

keepalived的配置文件主要有两个,分别是:

  • /etc/keepalived/keepalived.confkeepalived服务主配置文件
  • /etc/sysconfig/keepalivedkeepalived选项配置文件,日志和运行服务相关

keepalived工作模式

  • 抢占式
  • 非抢占式

配置文件详解

/etc/keepalived/keepalived.conf

! 叹号为注释
global_defs {							#全局定义
	router_id lb01						#定义一个唯一的身份ID
}
vrrp_instance VI_1 {
	state MASTER						#指定身份角色
	interface eth0						#指定绑定的物理网卡
	virtual_router_id 50				#指定一个虚拟路由ID
	priority 150						#指定优先级,谁大谁优先级高
	advert_int 1						#心跳检测间隔时间
	authentication {					#身份认证配置
		auth_type PASS					#认证类型:明文
		auth_pass 1111					#设置密码
	}
	virtual_ipaddress {					#指定VIP地址
		10.0.0.3
	}
}

抢占式

在此模式下,两台服务器具有不同的身份,分别为:MASTERBACKUP,通常MASTER的权重设定的较高,服务主要由MASTER提供,当MASTER宕机时,VIP会自动漂移至BACKUP主机,此时此VIP对应的物理网卡地址是BACKUP主机,所有服务由BACKUP主机提供,当MASTER主机服务恢复时,VIP会被重新绑定于MASTER主机,BACKUP会释放该地址。在抢占模式下切换主从通常会引起一定的丢包,通常抢占式高可用主要用于主/备服务器硬件配置有差异的场合,主服务器配置较高,备用服务器配置低的情况。

典型示例

MASTER配置:

global_defs {
	router_id lb01
}
vrrp_instance VI_1 {
	state MASTER
	interface eth0
	virtual_router_id 50
	priority 150
	advert_int 1
	authentication {
		auth_type PASS
		auth_pass 1111
	}
	virtual_ipaddress {
		10.0.0.3
	}
}

BACKUP的配置:

global_defs {
	router_id lb02
}
vrrp_instance VI_1 {
	state BACKUP
	interface eth0
	virtual_router_id 50
	priority 100
	advert_int 1
	authentication {
		auth_type PASS
		auth_pass 1111
	}
	virtual_ipaddress {
		10.0.0.3
	}
}

配置完成后使用systemctl start keepalived启动服务即可,也可加入开机自启。

非抢占式

在此模式下,两台服务器互为主从,身份均为BACKUP,当服务器A宕机时,备用服务器B立即接管,当A恢复时,自动成为备机身份,除非服务器B宕机了,否则不会进行身份切换;这样的好处是,业务始终处于可用状态,不会丢包,这一切对于用户都是无感的。

注:无论是抢占式还是非抢占式,主备服务器都是互相监视状态,检查对方的存活状态,一旦被检测方没有响应,检测方会立即绑定VIP地址到自己的网卡上,如果,对方存活但没有心跳回复,此时备机还是会进行VIP绑定,这种现象叫做脑裂,会引起服务不正常,此时应衡量利弊后KILL任意一个即可。

典型示例

在非抢占式模式下,有几个必须指定项:

  • 两台服务器的state均指定为BACKUP
  • 两台服务器都必须指定nopreempt(不抢占)参数
  • 尽量将其中一台的priority值设高一些

A主机配置:

global_defs {
	router_id lb01
}
vrrp_instance VI_1 {
	state BACKUP
	nopreempt
	interface eth0
	virtual_router_id 50
	priority 150
	advert_int 1
	authentication {
		auth_type PASS
		auth_pass 1111
	}
	virtual_ipaddress {
		10.0.0.3
	}
}

B主机配置:

global_defs {
	router_id lb02
}
vrrp_instance VI_1 {
	state BACKUP
	nopreempt
	interface eth0
	virtual_router_id 50
	priority 100
	advert_int 1
	authentication {
		auth_type PASS
		auth_pass 1111
	}
	virtual_ipaddress {
		10.0.0.3
	}
}

组建高可用性负载均衡

通过将keepalivednginx这两个软件结合使用,可以组建4/7层负载均衡,广泛应用于高并发高可用性场合(此处nginx工作于代理模式),由于keepalived只能检测当前主机是否宕机(死机等),并不能知晓nginx服务是否可用,因为这是两个独立且互不相干的软件,故需要使用脚本来进行nginx服务运行检测,使用keepalived周期性执行该脚本,根据脚本的检测逻辑执行对应的一些动作。

脚本:check_nginx_service.sh

#!/bin/sh
#File Name: check_nginx_service.sh
#发送邮件功能依赖send_mail.sh

count=$(ps -C nginx --no-header | wc -l)
#统计输出,如果结果为0,则nginx未运行
if [ $count -eq 0 ]; then
#判断,如果为0则尝试启动nginx,等待3s
	systemctl start nginx
	sleep 3
	count=$(ps -C nginx --no-header | wc -l)
	#再次检查nginx状态
	if [ $count -eq 0 ]; then
	#再次判断,如果nginx还是未启动,则停止本机keepalived服务
		systemctl stop keepalived
		. /scripts/send_mail.sh "nginx服务异常!已停止本机的keepalived服务!"
		#发送邮件通知管理员处理
	fi
fi	

将此脚本添加到keepalived配置文件中以实现定时调用

如果使用了抢占式高可用,则此文件在MASTER上定期调用,如果是非抢占式高可用,则此文件需在两台BACKUP上都运行,定时调用的实现如下,在/etc/keepalived/keepalived.conf文件中添加下面配置:

global_defs {
	router_id lb01
}
;定义脚本
vrrp_script check_nginx_service {
	script "/scripts/check_nginx_service.sh"
	interval 5
	;Run once in 5 seconds
}
vrrp_instance VI_1 {
	state BACKUP
	;根据方式设置合适的state
	nopreempt
	interface eth0
	virtual_router_id 50
	priority 150
	advert_int 1
	authentication {
		auth_type PASS
		auth_pass 1111
	}
	virtual_ipaddress {
		10.0.0.3
	}
	;调用脚本
	track_script {
		check_nginx_service
	}
}

其他

裂脑检测

通过编写脚本,检查是否发生了裂脑的情况,基本思路是:在备机上循环执行检测脚本,使用ping命令检查对方存活状态,如果在能pingMASTER的情况下BACKUPVIP也存在,则认为是产生了裂脑,此时调用mail命令发送邮件或使用echo打印报警信息。

脚本:check_split_brain.sh

#!/bin/sh
#File Name: check_split_brain.sh
#发送邮件功能依赖send_mail.sh
vip=10.0.0.3
master_ip=10.0.0.5					#定义master的真实IP
while true;
do
    ping -c 2 -W 3 $master_ip &>/dev/null
    if [ $? -eq 0 -a `ip addr | grep "$vip" | wc -l` -eq 1 ]; then
    #检查ping的结束返回值是否为0且本机具有VIP
        #wall -n "HA is split brain.warning."
        #发送广播消息,所有已登录的用户都会收到
        . /scripts/send_mail.sh "裂脑!"
        #邮件通知
    fi
sleep 5
done

**注:**脚本可放于后台,或者创建符号链接到/etc/systemd,也可使用screen命令放于后台执行。

脚本:send_mail.sh

#!/bin/bash
#file name: send_mail.sh
#系统通知邮件统一发送调用脚本
#需配置好本机的/etc/mail.rc文件,且本机可以发出邮件

head_format=$HOSTNAME_$(date +%F).tmp
tmp_dir=/tmp
dest=$tmp_dir/$head_format
inbox_addr=定义收件邮箱

touch $dest
echo -e "来自$HOSTNAME的通知邮件:\n" > $dest
echo -e "----------------------------------------\n" >> $dest
echo -e "在 $(date +%T) 发生了 $1 \n" >> $dest
echo -e "敬请知悉!\n" >> $dest
echo -e "----------------------------------------\n" >> $dest

/usr/bin/mail -s "系统通知" $inbox_addr < $dest;
rm -f $dest

关于开启防火墙下的keepalived实现

如果开启了firewalld防火墙,在未设置任何放行规则的情况下,会立即发生脑裂(典型情况下,一般我们会在负载均衡的前端加入物理防火墙,云上环境不需要keepalived来做高可用),我的测试是基于虚拟机的,添加富规则: Master侧firewalld规则配置:

firewall-cmd --add-rich-rule='rule family=ipv4 source address=MASTER_IP accept' --permanent
#放行MASTER_IP的数据包进站,该参数需根据个人设置来改,未指定协议,则全部,默认情况下,不加--permanent参数的规则重启后一律失效,--permanent参数将该参数加入永久规则
#完事后重启防火墙
systemctl restart firewalld

Backup侧的frewalld规则配置:

firewall-cmd --add-rich-rule='rule family=ipv4 source address=BACKUP_IP accept' --permanent
#放行BACKUP_IP的数据包进站,该参数需根据个人设置来改,未指定协议,则全部,默认情况下,不加--permanent参数的规则重启后一律失效,--permanent参数将该参数加入永久规则
#简单理解就是,MASTER放行BACKUP的,BACKUP放行MASTER的
#完事后重启防火墙
systemctl restart firewalld
# HA 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×