目录
1.说明
2.现状
3.高可用方案
3.1.部署架构
3.2.高可用说明
3.2.1. keepalived服务故障
3.2.2 . 主机宕机ived服务故障
3.2.3. nfs服务故障
3.2.4. 客户端重新挂载
4.实施条件
4.1 系统权限
4.2.IP地址申请
5.实施步骤
5.1.服务部署
5.1.1.keepalived部署
5.1.2.nfs部署
5.1.3 编译安装inotify-tools
5.1.4.rsync部署
5.2.功能测试
5.3.性能测试
5.4.存储迁移
5.4.1.数据同步
规划采用keepalived+rsync+NFS组合来实现存储的高可用,如图所示,单纯的nfs存在单点故障,通过浮动IP管理和rsync文件同步满足高可用需求。
按照所示架构,再辅助服务端检测脚本,高可用能够满足以下4种故障的服务切换:
1:nfs服务主机在一个主机宕机情况下,浮动ip切换到另外一台主机
2:一台主机的keepalived服务故障,导致网络不通时候也进行切换。
3:配置辅助检测脚本,自动后台运行,在网络、主机正常情况下,如果nfs服务存在问题,自动拉起,如果拉起不成功,终止keepalived服务,强制浮动ip漂移
4:由于nfs浮动IP切换,会导致客户端原有挂载目录故障,需要在客户端配置检测脚本,检测到挂载的nfs不正常时候,强制卸载本地挂载目录,然后重新挂载。
备注:keepalived有两种模式(抢占模式、非抢占模式),
抢占模式下,依赖两个节点的权重配置,权重高的抢占主节点,只有当主节点失败后,权重低的节点才能做为主节点,当权重高的节点恢复后,再次夺回主节点;
非争抢模式下,两个节点,谁先启动谁做为主节点,当主节点故障后,主节点切换,故障修复后,主节点不再移动,保持当前位置;
本方案部署的为非争抢模式,区别在于keepalived的配置文件,通过不同参数可以修改模式。
该情况下,浮动IP由当前节点移动到备用节点,由于物理属相改变,客户端挂载nfs目录失效,检测脚本自动进行卸载和重新挂载。
当主节点keepalived服务修复后,浮动ip再次移动回来,客户端脚本自动再次重新运行,恢复到故障前状态。
该情况和第一种后台处理动作基本相同,待主机恢复后,所有服务恢复正常,浮动IP会再次恢复到主节点上。
该情况下,nfs服务检测脚本会尝试自动拉起nfs服务,拉取失败后,主动关闭keepalived服务,强制浮动IP移动到备用节点,随后客户端重新卸载和挂载nfs目录。
待主节点恢复正常后,所有回重新恢复原状。
由于浮动IP移动后,客户端连接的实际物理设备更换,会导致自身挂载的共享nfs目录失效,所以该情况下,需要对mount的共享目录执行umountum后重新mount.该操作皆由脚本来实现。
按照规划的方式,需要申请一个浮动IP地址,该地址同两台存储服务主机IP地址同属于一个网段。已申请ip地址位192.168.187.242
=========安装==root=========================
#mkdir -p /home/aitp/keepalived-app
ftp文件(keepalived-2.0.20.tar.gz)到新创建目录
#cd /home/aitp/keepalived-app
#tar -zxvf keepalived-2.0.20.tar.gz
#cd keepalived-2.0.20
#./configure
#make && make install
chown –R aitp:aitp /home/aitp/keepalived-app
备注:编译过程提示缺少ipv6支持,yum install libnl* 解决
======编辑配置文件=root=============================
vi /usr/local/etc/keepalived/keepalived.conf
清空该文件内容,复制粘贴以下即可,复制前删除下边的备注信息
主节点主机Keepalived配置文件脚本:
! Configuration File for keepalived
global_defs {
router_id lb02
}
unicast_src_ip 192.168.187.48 #主节点IP
unicast_peer {
192.168.187.49 #备节点ip
}
vrrp_instance VI_1 {
state BACKUP #两个节点均为BACKUP
nopreempt
interface bond0 #主节点对应ip地址的网卡名称
virtual_router_id 51
priority 102
advert_int 2
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.187.242 #浮动ip
}
}
备节点主机Keepalived配置文件脚本:
! Configuration File for keepalived
global_defs {
router_id lb02
}
unicast_src_ip 192.168.187.49
unicast_peer {
192.168.187.48
}
vrrp_instance VI_1 {
state BACKUP
nopreempt
interface bond0
virtual_router_id 51
priority 100
advert_int 2
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.187.242
}
}
=======配置为服务=root===========================
mkdir /etc/keepalived
cp /home/aitp/keepalived-app/keepalived-2.0.20/keepalived/etc/init.d/keepalived /etc/init.d/
cp /home/aitp/keepalived-app/keepalived-2.0.20/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
cp /usr/local/sbin/keepalived /usr/sbin/
cp /usr/local/etc/keepalived/keepalived.conf /etc/keepalived/
chown aitp:aitp /etc/keepalived/keepalived.conf
#修改属主方便后续aitp用户编辑
=======服务启停操作==可以在全部配置完毕后执行==root==============
systemctl start keepalived.service #启动
systemctl status keepalived.service #查看服务状态
systemctl stop keepalived.service #停止服务
========服务端增加sudo权限==root===============================
先执行which systemctl 查看路径再配置
aitp ALL=(ALL) NOPASSWD: /usr/bin/systemctl
========服务端配置服务检测crontab配置===aitp===============
脚本文件放到/home/aitp/keepalived-app/check_nfs_ser.sh文件内:
#!/bin/bash
#nfs check
#if no nfsserver then start nfs
#if start nfs fail then stop keepalived
for i in `seq 14`;do
counter=`ps -aux | grep '\[nfsd\]' | wc -l`
if [ $counter -eq 0 ];then
sudo systemctl restart nfs
fi
sleep 2
counter=`ps -aux | grep '\[nfsd\]' | wc -l`
if [ $counter -eq 0 ];then
sudo systemctl stop keepalived.service
fi
sleep 2
done
编辑自动服务
crontab –e
插入下行,保存退出
* * * * * /home/aitp/keepalived-app/check_nfs_ser.sh &> /dev/null
========客户端增加sudo权限==root===============================
先执行which umount 查看路径再配置
aitp ALL=(ALL) NOPASSWD: /usr/bin/umount,/usr/bin/mount
========客户端配置服务检测=aitp=================================
脚本文件放到/home/aitp/keepalived-app/check_nfs.sh文件内:
#!/bin/bash
for i in `seq 29`;do
df -Th &> /dev/null
if [ `echo $?` -ne 0 ];then
sudo umount -lf /home/share && sudo mount -a
fi
sleep 2
done
编辑自动服务
crontab –e
插入下行,保存退出
* * * * * /home/aitp/keepalived-app/check_nfs.sh &> /dev/null
=======服务启动==aitp==============
sudo systemctl start keepalived.service #启动
sudo systemctl status keepalived.service #查看服务状态
说明:使用root用户,按如下1~4步骤,分别在192.168.187.48和192.168.187.49主机上执行。
主节点配置共享目录
#修改nfs服务器端配置文件/etc/exports
vi /etc/exports
#指定要共享的目录及权限
/home/newnfs *(rw,sync,no_root_squash,no_subtree_check,no_all_squash)
设置共享目录生效
#使用exportfs命令重新挂载
exportfs -rv
重启nfs服务
systemctl restart nfs
检查共享目录
showmount -e 192.168.187.48
showmount -e 192.168.187.49
1)解包inotify-tools-3.13.tar.gz文件
tar -zxvf inotify-tools-3.13.tar.gz -C /usr/src/
2)配置./configure
#进入源码目录
cd /usr/src/inotify-tools-3.13
#执行配置操作
./configure
3)编译make
make
4)安装make install
make install
cp /usr/local/bin/inotifywait /usr/bin/
5)inotifywait 参数说明:
-m,–monitor:始终保持事件监听状态 # 重要参数
-r,–recursive:递归查询目录 # 重要参数
-q,–quiet:只打印监控事件的信息 # 重要参数
-exclude:排除文件或目录时,不区分大小写
-t,–timeout:超时时间
–timefmt:指定时间输出格式 # 重要参数
–format:指定时间输出格式 # 重要参数
-e,–event:后面指定删、增、改等事件 # 重要参数
6)inotifywait events 事件说明:
access:读取文件或目录内容
modify:修改文件或目录内容
attrib:文件或目录的属性改变
close_write:修改真实文件内容 # 重要参数
close_nowrite:文件或目录关闭,在只读模式打开之后关闭的
close:文件或目录关闭,不管读或是写模式
open:文件或目录被打开
moved_to:文件或目录移动到
moved_from:文件或目录从移动
move:移动文件或目录移动到监视目录 # 重要参数
create:在监视目录下创建文件或目录 # 重要参数
delete:删除监视目录下的文件或目录 # 重要参数
delete_self:文件或目录被删除,目录本身被删除
unmount:卸载文件系统
使用root用户,执行数据同步脚本,实现主、从nfs服务器共享目录数据同步。
一、 在nfs服务器端(192.168.187.48)操作
说明:使用root用户,按如下1~8步骤,在192.168.187.48主机上执行。
1、配置rsyncd.conf文件
vim /etc/rsyncd.conf
uid = root
gid = root
use chroot = no
max connections = 100
pid file = /root/rsyncscript/rsync/run/rsyncd.pid
lock file = /root/rsyncscript/rsync/run/rsync.lock
log format = %t %a %m %f %b
log file = /root/rsyncscript/rsync/logs/rsyncd.log
transfer logging = yes
timeout = 900
ignore nonreadable = yes
hosts allow = *
[sync_file]
path = /home/newnfs
list = no
ignore errors
read only = no
secrets file = /root/rsyncscript/rsyncd.passwd
comment = rsync /home/newnfs’s folder and files to backupserver
2、创建password-file文件
mkdir -p /root/rsyncscript
cd /root/rsyncscript
touch rsyncd.passwd
vim rsyncd.passwd
#设置免密访问
nfsha:1qaz!QAZ
3、启动rsync守护进程
rsync –daemon –config /etc/rsyncd.conf
4、创建同步脚本,并设置执行权限
cd /root/rsyncscript
touch startnfsha.sh
chmod +x startnfsha.sh
vim startnfsha.sh
#!/bin/bash
####################################################
#function name: startnfsha.sh
#function 把该节点的${SRC_PATH}数据同步到${REMOTE_HOST}节点的${DST_PATH}目录
###################################################
#init parameter
STARTTIME=`date +"%Y-%m-%d %H:%M:%S"`
SRC_PATH=/home/newnfs/
DST_PATH=sync_file
[email protected]
LOG_PATH=/root/rsyncscript/rsyncnfsha.log
#execute command
echo "${STARTTIME}开始执行文件同步操作" >>${LOG_PATH}
rsync -vzrtopglLu --password-file=/root/rsyncscript/rsyncd.passwd ${SRC_PATH} ${REMOTE_HOST}::${DST_PATH} >>${LOG_PATH}
ENDTIME=`date +"%Y-%m-%d %H:%M:%S"`
echo "${ENDTIME}结束执行文件同步操作" >>${LOG_PATH}
5、 执行全量同步脚本
cd /root/rsyncscript
nohup ./startnfsha.sh &
6、 创建脚本checkKeepAlived.sh,监测浮动IP是否在当前节点
cd /root/rsyncscript
touch checkKeepAlived.sh
chmod a+x checkKeepAlived.sh
vi checkKeepAlived.sh
#!/bin/bash
# 把浮动IP的查询结果存入变量IsVIP
IsVIP=`ip addr | grep 172.18.237.252 | wc -l`
# 获取当前时间
CurTime=`date +"%Y-%m-%d %H:%M:%S"`
# 脚本存放路径
ScriptPath=/root/rsyncscript
# 监测日志,存放监测记录
LogFile=/root/rsyncscript/log/checkKeepAlived.log
# 把数据同步进程查询结果存入变量RsyncProcess_NUM,inotifywait进程查询结果存入变量InotifyProcess_NUM
RsyncProcess_NUM=`ps aux | grep startRsync.sh | grep -v grep | awk '{print $2}' | wc -l`
InotifyProcess_NUM=`ps -ef | grep inotify | grep -v grep | wc -l`
# 判断是否是MASTER节点
if [[ ${IsVIP} == 1 ]]; then
kill -9 `ps aux | grep startRsync.sh | grep -v grep | awk '{print $2}'`
kill -9 `ps aux | grep startRsync.sh | grep -v grep | awk '{print $2}'`
echo "${CurTime} kill startRsync.sh successed." >> ${LogFile}
killall inotifywait
echo "${CurTime} kill inotifywait successed." >> ${LogFile}
elif [[ ${RsyncProcess_NUM} -gt 0 && ${InotifyProcess_NUM} -gt 0 ]]; then
echo "${CurTime} 实时同步任务运行中......" >> ${LogFile}
else
kill -9 `ps aux | grep startRsync.sh | grep -v grep | awk '{print $2}'`
kill -9 `ps aux | grep startRsync.sh | grep -v grep | awk '{print $2}'`
echo "${CurTime} kill startRsync.sh successed." >> ${LogFile}
killall inotifywait
echo "${CurTime} kill inotifywait successed." >> ${LogFile}
echo "${CurTime} 重启实时同步任务完成." >> ${LogFile}
cd ${ScriptPath}
./startRsync.sh
fi
7、 创建脚本startRsync.sh,实时数据同步启动脚本
说明:登陆192.168.187.48主机,创建该文件。
cd /root/rsyncscript
touch startRsync.sh
chmod a+x startRsync.sh
vi startRsync.sh
#!/bin/bash
# 实时监测路径
Path=/home/newnfs
# 脚本存放路径
ScriptPath=/root/rsyncscript
# 备份服务器IP地址
BackupServer=192.168.187.49
# rsyncd.conf文件的uid值
User=nfsha
# rsyncd.conf文件的模块名称
module=sync_file
monitor() {
/usr/bin/inotifywait -mrq --format '%w%f' -e create,close_write,modify,delete,attrib,moved_to,moved_from,move_self $1 | while read line; do
if [ -f $line ]; then
rsync -avz $line --delete --ignore-errors ${User}@${BackupServer}::${module} --password-file=${ScriptPath}/rsyncd.passwd
else
cd $1 &&
rsync -avz ./ --delete --ignore-errors ${User}@${BackupServer}::${module} --password-file=${ScriptPath}/rsyncd.passwd
fi
done
}
monitor $Path;
8、 设置定时任务
设置定时任务,使用脚本checkKeepAlived.sh每分钟监测浮动IP是否在该服务器,如果浮动IP在该服务器,自动执行脚本startRsync.sh启动实时数据同步任务,把该服务器/home/newnfs目录下的数据同步到备份服务器/home/newnfs的相同目录下。
crontab -e
*/1 * * * * /root/rsyncscript/checkKeepAlived.sh
二、 在nfs服务器端(192.168.187.49)操作
说明:使用root用户,按如下1~8步骤,在192.168.187.49主机上执行。
1、配置rsyncd.conf文件
vim /etc/rsyncd.conf
uid = root
gid = root
use chroot = no
max connections = 100
pid file = /root/rsyncscript/rsync/run/rsyncd.pid
lock file = /root/rsyncscript/rsync/run/rsync.lock
log format = %t %a %m %f %b
log file = /root/rsyncscript/rsync/logs/rsyncd.log
transfer logging = yes
timeout = 900
ignore nonreadable = yes
hosts allow = *
[sync_file]
path = /home/newnfs
list = no
ignore errors
read only = no
secrets file = /root/rsyncscript/rsyncd.passwd
comment = rsync /home/newnfs’s folder and files to backupserver
2、创建password-file文件
mkdir -p /root/rsyncscript
cd /root/rsyncscript
touch rsyncd.passwd
vim rsyncd.passwd
#设置免密访问
nfsha:1qaz!QAZ
3、启动rsync守护进程
rsync –daemon –config /etc/rsyncd.conf
4、创建同步脚本,并设置执行权限
cd /root/rsyncscript
touch startnfsha.sh
chmod +x startnfsha.sh
vim startnfsha.sh
#!/bin/bash
####################################################
#function name: startnfsha.sh
#function 把该节点的${SRC_PATH}数据同步到${REMOTE_HOST}节点的${DST_PATH}目录
###################################################
#init parameter
STARTTIME=`date +"%Y-%m-%d %H:%M:%S"`
SRC_PATH=/home/newnfs/
DST_PATH=sync_file
[email protected]
LOG_PATH=/root/rsyncscript/rsyncnfsha.log
#execute command
echo "${STARTTIME}开始执行文件同步操作" >>${LOG_PATH}
rsync -vzrtopglLu --password-file=/root/rsyncscript/rsyncd.passwd ${SRC_PATH} ${REMOTE_HOST}::${DST_PATH} >>${LOG_PATH}
ENDTIME=`date +"%Y-%m-%d %H:%M:%S"`
echo "${ENDTIME}结束执行文件同步操作" >>${LOG_PATH}
5、 执行全量同步脚本
cd /root/rsyncscript
nohup ./startnfsha.sh &
6、 创建脚本checkKeepAlived.sh,监测浮动IP是否在当前节点
cd /root/rsyncscript
touch checkKeepAlived.sh
chmod a+x checkKeepAlived.sh
vi checkKeepAlived.sh
#!/bin/bash
# 把浮动IP的查询结果存入变量IsVIP
IsVIP=`ip addr | grep 172.18.237.252 | wc -l`
# 获取当前时间
CurTime=`date +"%Y-%m-%d %H:%M:%S"`
# 脚本存放路径
ScriptPath=/root/rsyncscript
# 监测日志,存放监测记录
LogFile=/root/rsyncscript/log/checkKeepAlived.log
# 把数据同步进程查询结果存入变量RsyncProcess_NUM,inotifywait进程查询结果存入变量InotifyProcess_NUM
RsyncProcess_NUM=`ps aux | grep startRsync.sh | grep -v grep | awk '{print $2}' | wc -l`
InotifyProcess_NUM=`ps -ef | grep inotify | grep -v grep | wc -l`
# 判断是否是MASTER节点
if [[ ${IsVIP} == 1 ]]; then
kill -9 `ps aux | grep startRsync.sh | grep -v grep | awk '{print $2}'`
kill -9 `ps aux | grep startRsync.sh | grep -v grep | awk '{print $2}'`
echo "${CurTime} kill startRsync.sh successed." >> ${LogFile}
killall inotifywait
echo "${CurTime} kill inotifywait successed." >> ${LogFile}
elif [[ ${RsyncProcess_NUM} -gt 0 && ${InotifyProcess_NUM} -gt 0 ]]; then
echo "${CurTime} 实时同步任务运行中......" >> ${LogFile}
else
kill -9 `ps aux | grep startRsync.sh | grep -v grep | awk '{print $2}'`
kill -9 `ps aux | grep startRsync.sh | grep -v grep | awk '{print $2}'`
echo "${CurTime} kill startRsync.sh successed." >> ${LogFile}
killall inotifywait
echo "${CurTime} kill inotifywait successed." >> ${LogFile}
echo "${CurTime} 重启实时同步任务完成." >> ${LogFile}
cd ${ScriptPath}
./startRsync.sh
fi
7、 创建脚本startRsync.sh,实时数据同步启动脚本
说明:登陆192.168.187.49主机,创建该文件。
cd /root/rsyncscript
touch startRsync.sh
chmod a+x startRsync.sh
vi startRsync.sh
#!/bin/bash
# 实时监测路径
Path=/home/newnfs
# 脚本存放路径
ScriptPath=/root/rsyncscript
# 备份服务器IP地址
BackupServer=192.168.187.49
# rsyncd.conf文件的uid值
User=nfsha
# rsyncd.conf文件的模块名称
module=sync_file
monitor() {
/usr/bin/inotifywait -mrq --format '%w%f' -e create,close_write,modify,delete,attrib,moved_to,moved_from,move_self $1 | while read line; do
if [ -f $line ]; then
rsync -avz $line --delete --ignore-errors ${User}@${BackupServer}::${module} --password-file=${ScriptPath}/rsyncd.passwd
else
cd $1 &&
rsync -avz ./ --delete --ignore-errors ${User}@${BackupServer}::${module} --password-file=${ScriptPath}/rsyncd.passwd
fi
done
}
monitor $Path;
8、 设置定时任务
设置定时任务,使用脚本checkKeepAlived.sh每分钟监测浮动IP是否在该服务器,如果浮动IP在该服务器,自动执行脚本startRsync.sh启动实时数据同步任务,把该服务器/home/newnfs目录下的数据同步到备份服务器/home/newnfs的相同目录下。
crontab -e
*/1 * * * * /root/rsyncscript/checkKeepAlived.sh
在功能测试的基础上,进行磁盘读写性能压力测试,分别测试磁盘在不同并发、数据块的情况下磁盘的读写速度、以及IOPS指标。
使用sysbench工具进行测试,编写循环脚本分为2G,8G,两类大小文件进行,分别从顺序读、顺序写、随机读,随机写、随机读写,设置4K,16K文件块大小,使用1、4、8、16、32线程进行测试。
测试脚本伪代码如下:
for 2G总文件大小、8G总文件大小 循环1
for 顺序读、顺序写、随机读、随机写、随机读写 循环2
for 4K文件块、16K文件块 循环3
for 1线程、4线程、8线程、16线程、32线程 循环4
开始测试准备,每组合测试2次
for 测试第一次、测试第二次 循环5
执行测试语句
循环5结束
循环4结束
循环3结束
循环2结束
循环1结束
1测试结果数据无导出;
2测试48、49主机数据基本一致,无大差别;
3各项数据较多,根据数据,和可参考数据,仅做如下两个数据对比截图
在测试完毕基础上,使用rsync功能配置数据同步,配置现网/home/newnfs/目录 到存储主节点的/home/newnfs/目录,同时主节点保持先前的同步不变,自动把数据同步到备用节点,在数据和生产追平的情况下,保持服务常在,直到进行割接。
5.4.2.存储割接
6.其他