我们前面有文章介绍了MySQL主主数据同步热备的配置,今天我们来给大家演示使用keepalived实现MySQL主主高可用,就是在主主中任意一台MySQL挂掉后,keepalived会自动切换到另一台MySQL上提供服务,从而保证业务正常可用,这个过程不需要人工干预,人工要做的只是修复发生故障的服务器。
准备环境
准备两台虚拟机,CentOS7。
节点DB1:192.168.11.31。
节点DB2:192.168.11.32。
假设我们已经把MySQL安装好,并已实现了主主同步功能,详见本站文章:《MySQL/MariaDB主主数据同步配置》。
接下来我们要做的是,安装Keepalived,并配置实现MySQL高可用。就是要实现功能:两个节点中有一个发生故障会自动切换到另一个节点上。
安装Keepalived
安装依赖:
yum -y install libnl libnl-devel
yum -y install libnfnetlink-devel
知识兔编译安装:
tar -zxvf keepalived-1.3.4.tar.gz
cd keepalived-1.3.4
./configure --prefix=/usr/local/keepalived
make && make install
知识兔安装完成后做成服务模式,方便开启和关闭:
cp /usr/local/keepalived/sbin/keepalived /usr/sbin
cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
cp /usr/local/keepalived/sbin/keepalived /etc/init.d/
知识兔设置开机自动启动:
systemctl enable keepalived.service
知识兔两台机器都要安装Keepalived。
配置Keepalived
keepalive通过组播,单播等方式(自定义),实现keepalive主备推选。工作模式分为抢占和非抢占(通过参数nopreempt来控制)。
抢占模式:当优先级高的主节点发生故障时,由被节点接管服务,但是当优先级高的主节点故障恢复时,立马抢占回VIP资源,继续提供主节点服务。配置时,看节点中谁的priority优先级高,(一般而言,state为MASTER的优先级要高于BACKUP)。根据priority优先级来决定谁抢占vip资源。
非抢占模式:不分主备节点,当其中一节点发生故障时,另一节点立马接管VIP服务,即使优先级高的那一节点故障恢复后也不会主动抢回vip,只能等到对方发生故障,才会将vip切回来。非抢占模式中state状态都设置成backup,配置nopreempt参数,那么就不会去考虑priority优先级了,是非抢占模式!
本实验我们采用非抢占模式,分别配置两个节点的配置文件。
mkdir /etc/keepalived
cd /etc/keepalived/
知识兔我们使用vim编辑:/etc/keepalived/keepalived.conf文件。
! Configuration File for keepalived
global_defs {
notification_email {
该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。
}
notification_email_from 该邮件地址已受到反垃圾邮件插件保护。要显示它需要在浏览器中启用 JavaScript。
smtp_server smtp.163.com
smtp_connect_timeout 30
router_id LVS_DEVEL
}
# 检测mysql是否正常运行
vrrp_script check_mysql {
script "/etc/keepalived/check_mysql.sh"
interval 5
}
vrrp_instance VI_1 {
state BACKUP # BACKUP MASTER 两台都配置为backup,非抢占模式
interface eno16777736 #绑定虚拟IP的网卡接口
#VRRP组名,两个节点设置一样,以指明各个节点同属一VRRP组
virtual_router_id 61
priority 100 #优先级,另一台设为90
advert_int 1 ##组播信息发送间隔,两个节点需一致
nopreempt #不抢占,只在优先级高的机器上设置,优先级低的不设置
#设置密码验证信息,两个节点需一致
authentication {
auth_type PASS
auth_pass zhishitu
}
#指定虚拟IP,两个节点需设置一样
virtual_ipaddress {
192.168.11.30
}
#检测mysql状态
track_script {
check_mysql
}
}
知识兔这里注意,我们设置为非抢占模式,节点1中的优先级最高,并设置nopreempt
意为不抢占,那么在节点2上就不要设置这个参数了,并且把优先级设为90即可。
此外我们使用Keepalived设置一个虚拟IP,即VIP,统一以VIP对外,就是说,外部访问连接通过VIP:192.168.11.30连接即可。注意VIP一定不能被其他机器占用。
配置好后,我们还需要设置keepalived 主备通信,添加防火墙vrrp 协议,eno16777736- 网卡名。
firewall-cmd --direct --permanent --add-rule ipv4 filter INPUT 0 --in-interface eno16777736 --destination 224.0.0.18 --protocol vrrp -j ACCEPT
知识兔如果不执行以上命令的话,会导致两个节点都有VIP的情况。当然你也可以关闭防火墙。
MySQL状态脚本检测
我们使用脚本检测Mysql的运行状态,脚本路径:/etc/keepalived/check_mysql.sh。
#!/bin/bash
counter=$(netstat -na|grep "LISTEN"|grep "3306"|wc -l)
if [ "${counter}" -eq 0 ]; then
systemctl stop keepalived
fi
知识兔我们监听3306端口,如果3306端口挂掉了,说明Mysql发生故障,这个时候停止本机Keepalived服务,另一节点就会接管VIP服务。
当然这个检测脚本有点暴力,有可能其他原因导致MySQL故障,而3306端口又是正常运行的情况,所以我们写了个比较平滑的检测代码:
#!/bin/bash
MYSQL=/usr/local/mariadb/bin/mysql
MYSQL_HOST=localhost
MYSQL_USER=root
MYSQL_PASSWORD=grandhonor.net12358
CHECK_TIME=3
#mysql is working MYSQL_OK is 1 , mysql down MYSQL_OK is 0
MYSQL_OK=1
function check_mysql_helth (){
$MYSQL -h $MYSQL_HOST -u $MYSQL_USER -p${MYSQL_PASSWORD} -e "show status;" >/dev/null 2>&1
if [ $? = 0 ] ;then
MYSQL_OK=1
else
MYSQL_OK=0
fi
return $MYSQL_OK
}
while [ $CHECK_TIME -ne 0 ]
do
let "CHECK_TIME -= 1"
check_mysql_helth
if [ $MYSQL_OK = 1 ] ; then
CHECK_TIME=0
exit 0
fi
if [ $MYSQL_OK -eq 0 ] && [ $CHECK_TIME -eq 0 ]
then
pkill keepalived
exit 1
fi
sleep 1
done
知识兔保存好脚本文件后,记得给执行权限:
chmod +x /etc/keepalived/check_mysql.sh
知识兔最后两台机器上都开启Keepalived服务:
systemctl start keepalived
知识兔高可用测试
1.我们先使用命令ip a
查看两台节点的VIP情况,发现节点1:192.168.11.31目前接手了VIP:192.168.11.30,而节点2并没有VIP。
2.关闭或者重启节点1或者重启节点1上的Keepalived服务,查看节点2是否接手VIP。
如图所示,如果在节点2上能看到VIP了说明VIP已经变更到节点2上了。
3.我们接着在两个节点机上的Mysql建立新的用户,允许任意机器连接(实际可以指定具体IP)。
grant all privileges on myzhishitu.* to keep@'%' identified by '123456';
知识兔4.关闭接手VIP服务节点的mysql服务,检验是否能从其他机器上通过终端连接192.168.11.30上的数据库。如果可以在测试往数据库中添加数据,再检测数据是否正常。