NFS高可用介绍


 1、NFS高可用生成业务需求

    在企业实际生产应用场景中,NFS网络文件存储系统是中小型企业最常用的存储架构解决方案之一。该架构方案部署简单,维护方便,并且只需要通过配置Inotify(rsync+inotify)简单而高效的数据同步方式就可以实现对NFS存储系统的数据进行异机主从同步已经实现数据读写分离(类似Mysql的从同步方式),且多个从NFS存储系统还可以通过LVS或者HAPROXY等代理实现业务负载均衡,即分担大并发读数据的压力,同时又排除了从NFS存储的单点问题。

    在高可用的存储系统架构中,虽然从NFS存储系统是多个,但是主的NFS存储系统仅一个,也就是说主的NFS存储系统一旦宕机,所有的写业务都会终止,而从NFS存储系统宕机1个就没什么大影响,那么如何解决这个主NFS存储系统单点的问题呢,其实,可以做好业务的服务监控,然后,当主NFS存储系统宕机后,报警管理员来人为手工根据同步的日志记录选择最快的从NFS存储系统改为主,然后让其他从NFS存储系统和新主NFS存储同步,这个方案简单可行,但是需要人工处理。

    这里我们可以采用NFS+DRBD+Heartbeat高可以服务解决方案,这个解决方案可以有效解决主NFS存储系统单点的问题,当主NFS存储宕机后,可以实现把主NFS存储系统从一个主节点切换到另外一个备节点,而新的主NFS存储系统还会自动和所有其他的从NFS存储系统进行同步,且新主NFS存储系统的数据和宕机瞬间的主NFS存储系统几乎完全一致,这个切换过程完全是自动进行的,从而实现了NFS存储系统的热备方案


 2、NFS高可以生产需求描述

 本案例假设有3台NFS存储系统服务器,他们的IP分别是

 NFS1 10.0.0.3
 NFS2 10.0.0.4
 NFS3 10.0.0.5

 NFS1的NFS存储系统目录为/data,前端提供的访问VIP是10.0.0.103

 配置目标:一段主NFS存储系统服务器NFS1宕机,该服务器上的NFS存储系统和虚拟IP会自动切换当热备服务器NFS2S上继续提供服务,从而达到NFS存储系统高可用宕机后无业务影响的目的

 

 这里会有一个特别的问题,就是以前的多个从NFS存储服务器如何能和新的主NFS存储系统同步,经过实践,通过DRBD的方式同步的数据NFS存储系统,已经做从NFS存储系统是使用和主NFS系统对外提供服务的VIP为同步VIP,当主NFS存储系统宕机后,VIP漂移到热备主NFS存储系统,默认情况在几秒内,新的主NFS存储系统就可以启动同步程序把数据同步到所以的从NFS存储系统中

 

 提示:本文讲解的NFS数据库服务主备高可用模式,对于NFS数据库服务高可用,也可以是主主的双向高可用模式。


 3、系统环境

##NFS_M
eth0:10.0.0.3      #管理IP,用于LAN内数据转发
eth1:172.16.1.3#NFS服务器间心跳连接(直链)
VIP:10.0.0.103    #用于提供对外NFS存储系统服务VIP
##NFS_S
eth0:10.0.0.4
eth1:172.16.1.4
##server
eth0:10.0.0.5


同时在NFS_M需要添加一个1G的磁盘,NFS_S需要添加一个1.5G的磁盘。测试用


4、部署前准备


#要配置主机名和hosts文件.

主机名称要以uname -n为准

[root@NFS_S ~]# uname -n
NFS_S
[root@NFS_S ~]# uname -m
x86_64
[root@NFS_S ~]# 
================================
NFS_M
cp /etc/hosts /etc/hosts.bak
cp /etc/sysconfig/network /etc/sysconfig/network.bak
sed -i '$a 10.0.0.3 NFS_M' /etc/hosts
sed -i '$a 10.0.0.4 NFS_S' /etc/hosts
sed -i '/HOSTNAME=/d' /etc/sysconfig/network 
sed -i '/$/aHOSTNAME=NFS_M' /etc/sysconfig/network
===============================
NFS_S
sed -i '$a 10.0.0.3 NFS_M' /etc/hosts
sed -i '$a 10.0.0.4 NFS_S' /etc/hosts
sed -i '/HOSTNAME=/d' /etc/sysconfig/network 
sed -i '/$/aHOSTNAME=NFS_S' /etc/sysconfig/network
############################start测试:
[root@NFS_S ~]# ping NFS_M
PING NFS_M (10.0.0.3) 56(84) bytes of data.
64 bytes from NFS_M (10.0.0.3): icmp_seq=1 ttl=64 time=0.347 ms
64 bytes from NFS_M (10.0.0.3): icmp_seq=2 ttl=64 time=0.297 ms
^C
--- NFS_M ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1424ms
rtt min/avg/max/mdev = 0.297/0.322/0.347/0.025 ms
[root@NFS_S ~]# ping NFS_S
PING NFS_S (10.0.0.4) 56(84) bytes of data.
64 bytes from NFS_S (10.0.0.4): icmp_seq=1 ttl=64 time=0.027 ms
64 bytes from NFS_S (10.0.0.4): icmp_seq=2 ttl=64 time=0.043 ms
^C
--- NFS_S ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1226ms
rtt min/avg/max/mdev = 0.027/0.035/0.043/0.008 ms
[root@NFS_S ~]#
===========================
[root@NFS_M ~]# ping NFS_S
PING NFS_S (10.0.0.4) 56(84) bytes of data.
64 bytes from NFS_S (10.0.0.4): icmp_seq=1 ttl=64 time=0.720 ms
64 bytes from NFS_S (10.0.0.4): icmp_seq=2 ttl=64 time=0.346 ms
64 bytes from NFS_S (10.0.0.4): icmp_seq=3 ttl=64 time=0.329 ms
^C
--- NFS_S ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2150ms
rtt min/avg/max/mdev = 0.329/0.465/0.720/0.180 ms
[root@NFS_M ~]# ping NFS_M
PING NFS_M (10.0.0.3) 56(84) bytes of data.
64 bytes from NFS_M (10.0.0.3): icmp_seq=1 ttl=64 time=0.022 ms
64 bytes from NFS_M (10.0.0.3): icmp_seq=2 ttl=64 time=0.131 ms
^C
--- NFS_M ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1388ms
rtt min/avg/max/mdev = 0.022/0.076/0.131/0.055 ms
[root@NFS_M ~]#
###########################end

#两台服务器都添加下面的心跳路由   生产环境建议加route。现在不加也不影响搭建.

/sbin/route add -host 172.16.1.4 dev eth1
/sbin/route add -host 172.16.1.3 dev eth1
echo '/sbin/route add -host 172.16.1.3 dev eth1' >> /etc/rc.local 
echo '/sbin/route add -host 172.16.1.4 dev eth1' >> /etc/rc.local 
#######测试
[root@NFS_M ~]# ping 172.16.1.4
PING 172.16.1.4 (172.16.1.4) 56(84) bytes of data.
64 bytes from 172.16.1.4: icmp_seq=1 ttl=64 time=1.56 ms
64 bytes from 172.16.1.4: icmp_seq=2 ttl=64 time=0.310 ms
^C
--- 172.16.1.4 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1267ms
rtt min/avg/max/mdev = 0.310/0.935/1.561/0.626 ms
[root@NFS_M ~]#
============================
[root@NFS_S ~]# /sbin/route add -host 172.16.1.3 dev eth1
[root@NFS_S ~]# 
[root@NFS_S ~]# ping 172.16.1.3
PING 172.16.1.3 (172.16.1.3) 56(84) bytes of data.
64 bytes from 172.16.1.3: icmp_seq=1 ttl=64 time=0.391 ms
^C
--- 172.16.1.3 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 897ms
rtt min/avg/max/mdev = 0.391/0.391/0.391/0.000 ms
[root@NFS_S ~]# 
###########################end


5、安装heartbeat

a、下载并安装epel包.两台服务器都要操作

mkdir -p /home/deng/tools && cd /home/deng/tools
wget http://mirrors.opencas.cn/epel/6/x86_64/epel-release-6-8.noarch.rpm
rpm -qa |grep epel
[ epel-release-6-8.noarch.rpm ]&& rpm -ivh epel-release-6-8.noarch.rpm
rpm -qa |grep epel

b、安装heartbeat,下面是在centos版本系统中部署,.两台服务器都要操作。所有用yum install heartbeat* -y

yum install heartbeat -y


c、拷贝ha的配置文件,资源文件以及授权文件到/etc/ha.d/下面

ll /usr/share/doc/heartbeat-3.0.4/
cd /usr/share/doc/heartbeat-3.0.4/
cp ha.cf haresources  authkeys /etc/ha.d/


d、开始配置

cd /etc/ha.d
mv ha.cf ha.bak
mv authkeys authkeys.bak
mv haresources haresources.bak

 

注意点:下面ha.cf、authkeys、haresources这三个文件在主备都是一样的

########配置ha.cf

cat>/etc/ha.d/ha.cf<<eof
#the start by lvnian 20150881
debugfile /var/log/ha-debug
logfile /var/log/ha-log
#logfacility local1
keepalive 2
deadtime 30
warntime 10
initdead 60
#bcast eth1
mcast eth1 225.0.0.181 694 1 0
#ucast eth1 172.16.1.4
auto_failback off          #服务器正常后,不接管备用设备资源
node NFS_M
node NFS_S
crm  no
#the end by lvnian 20150881
eof
####配置authkeys
cat >/etc/ha.d/authkeys<<eof
auth 1
1 sha1 b900cbbdfa0a850444fa3dae47a9d354   #这个字符串是随便写的,但是需要主备都是一样的
eof
chmod 600 /etc/ha.d/authkeys
#####配置haresources
cat > /etc/ha.d/haresources <<eof
#lvnian services
#10.0.0.103 www.etianetian.org
NFS_M IPaddr::10.0.0.103/24/eth0
#NFS_M IPaddr::10.0.0.103/24/eth0 httpd
#10.0.0.104 bbs.etianetian.org
NFS_S IPaddr::10.0.0.104/24/eth0
#mysql NFS_M mysqlm.etianetian.org
#NFS_M IPaddr::10.0.0.103/24/eth0
#NFS_M IPaddr::10.0.0.103/24/eth0 mysqld
#mysql slave mysqlm.etianetian.org
#NFS_S IPaddr::10.0.0.104/24/eth0
eof
#########

f、启动heartbeat 服务

/etc/init.d/heartbeat start
/etc/init.d/heartbeat stop
/etc/init.d/heartbeat restart


g、设置开机自启动heartbeat


chkconfig heartbeat on


用ip add 查看vip

查看 cat /var/log/ha-log日志文件

检查:出现虚拟VIP才算部署heartbeat成功

[root@NFS_M ~]# ip addr |grep 10.0.0
    inet 10.0.0.3/24 brd 10.0.0.255 scope global eth0
    inet 10.0.0.103/24 brd 10.0.0.255 scope global secondary eth0
[root@NFS_M ~]# 
============================
[root@NFS_S ha.d]# ip addr |grep 10.0.0
    inet 10.0.0.4/24 brd 10.0.0.255 scope global eth0
    inet 10.0.0.104/24 brd 10.0.0.255 scope global secondary eth0
[root@NFS_S ha.d]#

出现上面的VIP,代表Heartbeat部署没问题

 

6、对磁盘进行分区,这里模拟大于2T硬盘进行分区

###NFS_M
parted /dev/sdb mklabel gpt
yes
parted /dev/sdb mkpart primary 0 600
Ignore
parted /dev/sdb p
parted /dev/sdb mkpart primary 600 1024
Ignore
parted /dev/sdb p
###NFS_S
parted /dev/sdb mklabel gpt                   ##创建一个分区表
yes
parted /dev/sdb mkpart primary 0 1024 ##创建一个主分区
Ignore
parted /dev/sdb p
parted /dev/sdb mkpart primary 1024 1500
Ignore
parted /dev/sdb p
===========================
[root@NFS_M ~]# parted /dev/sdb p
Model: VMware, VMware Virtual S (scsi)
Disk /dev/sdb: 1074MB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Number  Start   End     Size   File system  Name     Flags
 1      17.4kB  600MB   600MB               primary
 2      600MB   1024MB  424MB               primary
[root@NFS_M ~]# 
===============================
[root@NFS_S ha.d]# parted /dev/sdb p
Model: VMware, VMware Virtual S (scsi)
Disk /dev/sdb: 1611MB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Number  Start   End     Size    File system  Name     Flags
 1      17.4kB  1024MB  1024MB               primary
 2      1024MB  1500MB  476MB                primary
[root@NFS_S ha.d]# 
================================

7、正式开始部署DRBD。两台服务器都要部署。操作相同

mkdir -p /home/lvnian/tools/
cd /home/lvnian/tools/
export LC_ALL=C
echo $LC_ALL
cd /home/lvnian/tools/
wget http://oss.linbit.com/drbd/8.4/drbd-8.4.4.tar.gz
ll drbd-8.4.4.tar.gz
tar xf drbd-8.4.4.tar.gz
cd drbd-8.4.4
./configure --prefix=/application/drbd-8.4.4  --with-km --with-heartbeat --sysconfdir=/etc/
make KDIR=/usr/src/kernels/$(uname -r)
make install


##加载drbd到内核

lsmod |grep drbd
modprobe drbd        
lsmod |grep drbd

  

#这个加载,在重启之后失效,可以把它放在rc.local中。但也可以用heartbeat挂载

##设置开机自启动挂载drbd


echo 'modprobe drbd' >>/etc/rc.local


##配置drbd.conf 两个服务去的配置文件时一样的

cat>/etc/drbd.conf <<eof
global {
  usage-count no;
}
common {
  syncer { 
rate 10M;
    verify-alg crc32c;
  } 
}
resource data {
  protocol C;
  disk{
  on-io-error  detach;
  }
  on NFS_M {
    device    /dev/drbd0;
    disk      /dev/sdb1;
    address   10.0.0.3:7788;
    meta-disk  /dev/sdb2[0];
  }
  on NFS_S {
    device    /dev/drbd0;
    disk      /dev/sdb1;
    address   10.0.0.4:7788;
    meta-disk  /dev/sdb2[0];
  }
}
eof
cat /etc/drbd.conf
#######初始化话meta data分区
drbdadm create-md data
##drbd 启动
mkdir -p /application/drbd-8.4.4/var/run/drbd
drbdadm up data
cat /proc/drbd 
############################################
报错:
[root@DRBD2 ~]# drbdadm up data
/application/drbd-8.4.4/var/run/drbd: No such file or directory
/application/drbd-8.4.4/var/run/drbd: No such file or directory
[root@DRBD2 ~]# 
解决:
mkdir -p /application/drbd-8.4.4/var/run/drbd
drbdadm up data
#指定其中一台为主drbd(注意。选其中一台为主)
drbdadm -- --overwrite-data-of-peer primary data
#格式化分区:
mkfs.ext4 -b 4096 /dev/drbd0 
tune2fs -c -1 /dev/drbd0 
#挂载分区:
mkdir /data
mount /dev/drbd0 /data   ##用drbd0挂载,而不是用/dev/sdb2物理分区挂载。

注意:仅仅是在主drbd中挂载,但是需要分别在进行主备切换,看能不能都成功进行挂载,只要能手工切换准备,并且能成功挂载,才算成功。才能继续下面的整合。


#修改heartbeat,也就是仅仅修改这个文件就可以了,其他不用变

cat >/etc/ha.d/haresources<<eof
#lvnian services
#10.0.0.103 www.etianetian.org
NFS_M IPaddr::10.0.0.103/24/eth0 drbddisk::data Filesystem::/dev/drbd0::/data::ext4
#NFS_M IPaddr::10.0.0.103/24/eth0 httpd
#10.0.0.104 bbs.etianetian.org
NFS_S IPaddr::10.0.0.104/24/eth0
#mysql NFS_M mysqlm.etianetian.org
#NFS_M IPaddr::10.0.0.103/24/eth0
#NFS_M IPaddr::10.0.0.103/24/eth0 mysqld
#mysql slave mysqlm.etianetian.org
#NFS_S IPaddr::10.0.0.104/24/eth0
eof
===================================================

##解析下面命令:

NFS_M IPaddr::10.0.0.103/24/eth0 drbddisk::data Filesystem::/dev/drbd0::/data::ext4
上面命令相对于依次在主节点上执行下面命令,如果主节点宕机了,就依次在被节点上执行
/etc/ha.d/resource.d/IPaddr 10.0.0.103/24/eth0 start/stop 
/etc/ha.d/resource.d/drbddisk data start/stop 
/etc/ha.d/resource.d/Filesystem /dev/drbd0 /data ext4 start/stop 
依次在主备上单独在命令行上面执行上面的命令。如果都能成功,那就可以用heartbeat使用了。
注意drbd需要在up状态在执行上面的命令。也就是先执行drbdadm up data 再执行上面的命令


#在重启heartbeat之前,必须把drbd的给启动起来,可以都是从

/etc/init.d/heartbeat stop
/etc/init.d/heartbeat restart


用下面命令,查看是否成功。之后左右重启服务器,切换主备。和用命令切换主备,让其能正常切换,才算成功

df
cat /proc/drbd
/usr/share/heartbeat/hb_standby 
/usr/share/heartbeat/hb_takeover


##注意要drbd设置开启自启动,只有设置开启自启动,heartbeat才能管理他,不然他无法挂载/dev/drbd0/,因为开机的是否,如果drbd不启动,就不存在/dev/drbd0分区。

所以heartbeat和drbd都要设置开机自启动。


但是在生产环境中,最好还是不要设置drbd和heartbeat开启自启动,我们仅仅需要让主服务故障的时候能够切换到备用设备就好了。这时候主的修复,最好还是人工介入。

但是这个实验为了能够体现主备可以相互接管等,在服务器出现故障重启,也能正常接管,所以设置了开启自启动



对于heartbeat配合drbd联合调试小结

1、主或备节点有heartbeat控制的资源的启动顺序是相同,资源启动顺序为

  a、vip的启动

  b、drbd启动和设置

  c、drbd分区的挂载

2、发生切换时主或备节点释放资源的顺序是相同,但是和上面启动的顺序是相反的。

  a、drbd分区的卸载

  b、drbd服务角色等变为slave

  c、vip的停止  

  所以/etc/ha.d/haresources里面的资源顺序是不可以表的,必须如下:

  NFS_M IPaddr::10.0.0.103/24/eth0 drbddisk::data Filesystem::/dev/drbd0::/data::ext4

 

故障解决思路:

出现故障,就根据分别执行下面命令,看日志,看哪里出错,之后进行处理

/etc/ha.d/resource.d/IPaddr 10.0.0.103/24/eth0 start/stop 
/etc/ha.d/resource.d/drbddisk data start/stop 
/etc/ha.d/resource.d/Filesystem /dev/drbd0 /data ext4 start/stop

8、配置nfs服务 (两台服务器都要安装和配置nfs服务)


#分别在两台服务器上都安装nfs服务

yum install nfs-utils  rpcbind -y


#分别在两台服务器上配置nfs服务

mkdir /data
chmod -R 777 /data
echo "/data 10.0.0.*(rw,sync)" >>/etc/exports


#重启nfs服务

/etc/init.d/rpcbind stop 
/etc/init.d/rpcbind start
/etc/init.d/nfs stop
/etc/init.d/nfs start
#/etc/init.d/nfs reload命令等同于 exportfs -r



#nfs客户端只需要安装rpcbind服务就可以了

/etc/init.d/rpcbind restart
chkconfig rpcbind on
chkconfig --list |grep rpcbind

#查看是否配置成功(在nfs客户端上操作,也就是10.0.0.5服务器上)

showmount -e 10.0.0.3
showmount -e 10.0.0.4
mount -t nfs 10.0.0.3:/data /data
mount -t nfs 10.0.0.4:/data /mnt
df

如果都能成功挂载,那nfs安装成功,把它们都卸载下来。

只要安装成功nfs才能继续下面的操作,和heartbaeat+DRBD配置

umount /mnt/
umount /data/
df

#手工切换drbd中的nfs服务器,看客户端nfs服务器是否正常

mount -t nfs 10.0.0.103:/data /data
/etc/init.d/nfs stop 
/etc/init.d/nfs start 
/usr/share/heartbeat/hb_standby
/usr/share/heartbeat/hb_takeover


##如果用nfs自动脚本,关闭nfs较慢的情况下,可以使用下面的脚本,强制关闭nfs。你也可以用系统自动的脚本,那样在下面的haresources文件中,就直接用nfs,而不用nfsd。

cat > /etc/ha.d/resource.d/nfsd <<eof
#!/bin/bash   
#   
case $1 in
   start)
      /etc/init.d/nfs restart
    ;;
   stop)
       /etc/init.d/nfs stop
      for proc in rpc.mountd rpc.rquotad nfsd nfsd  
         do
             killall -9 $proc
         done
    ;;
esac
eof
==================
chmod 755 /etc/ha.d/resource.d/nfsd 
ll /etc/ha.d/resource.d/nfsd 
cat /etc/ha.d/resource.d/nfsd 
#修改/etc/ha.d/haresources
cat >/etc/ha.d/haresources<<eof
#gao services
#10.0.0.103 www.etianetian.org
NFS_M IPaddr::10.0.0.103/24/eth0 drbddisk::data Filesystem::/dev/drbd0::/data::ext4 nfsd 
#NFS_M IPaddr::10.0.0.103/24/eth0 httpd
#10.0.0.104 bbs.etianetian.org
BACKUP IPaddr::10.0.0.104/24/eth0
#mysql NFS_M mysqlm.etianetian.org
#NFS_M IPaddr::10.0.0.103/24/eth0
#NFS_M IPaddr::10.0.0.103/24/eth0 mysqld
#mysql slave mysqlm.etianetian.org
#BACKUP IPaddr::10.0.0.104/24/eth0
eof
##
##
drbdadm -- --overwrite-data-of-peer primary data

下面命令解析

NFS_M IPaddr::10.0.0.103/24/eth0 drbddisk::data Filesystem::/dev/drbd0::/data::ext4 nfsd
NFS_M--> 为主机名,表示初始转态会在NFS_M 绑定IP 10.0.0.103
IPaddr<--为heartbeat配置IP的默认脚本,其后的IP等都是其参数。
10.0.0.103/24/eth0<--为集群提供对外的VIP,初始化启动在NFS_M上,#24是子网掩码,eth0为IP绑定的实际物理网卡,为heartbeat提供对外服务的通讯接口。
NFS_M IPaddr::10.0.0.103/24/eth0 这一段配置相当于执行下面命令
/etc/ha.d/resource.d/IPaddr 10.0.0.103/24/eth0 stop/start
drbddisk::data <---启动drbd data 资源,drbddisk::data这段内容这里相当于执行
/etc/ha.d/resource.d/drbddisk data stop/start 相当于drbdadm up data或者drbdadm down data
Filesystem::/dev/drbd0::/data::ext4 <--drbd分区挂载到/data 这段内容在这里相当于执行
/etc/ha.d/resource.d/Filesystem /dev/drbd0  /data ext4 
相对于mount /dev/drbd0 /data
nfsd<--启动nfs脚本服务,这里相当于执行/etc/init.d/rsdata start/stop

  

上面高可用的NFS方案的难点是客户端连接到新主的问题。

思路:

a、nfs客户端,监控本地读NFS,如果读不了,重新挂载

b、nfs客户端,监控远程主备是否发生切换,如果切换重新挂载。(可以监控VIP是否漂移)