1. 简述
本篇文章主要是使用 DRBD+HEARTBEAT 来保证 NFS 的高可用。使用 DRBD 来保证主从服务器的文件一致, 使用 HEARTBEAT 来做热切换。
2. 硬件和网络需求
需要两台服务器, 并且分别单独挂载硬盘或者硬盘分区。 同时有一个 VIP 能够对外统一提供 NFS 服务
3. 安装 DRBD
3.1 安装 DRBD
两台服务器都进行添加的磁盘分区格式化, 如果是有已存在的分区可以忽略
parted /dev/sdb mklabel gpt
parted /dev/sdb mkpart primary 0 1024
parted /dev/sdb mkpart primary 1025 2146
parted /dev/sdb p
mkfs.ext4 /dev/sdb1
安装 和初始化 drbd
rpm -Uvh http://www.elrepo.org/elrepo-release-6-8.el6.elrepo.noarch.rpm
yum install -y drbd84-utils kmod-drbd84
modprobe drbd
3.2 编辑配置文件
创建文件 /etc/drbd.d/r0.res
172.16.1.31 和 172.16.1.32 分别为两台服务器 IP
resource r0 {
net {
protocol C;
cram-hmac-alg "sha1";
shared-secret "c4f9375f9834b4e7f0a528cc65c055702bf5f24a";
}
device /dev/drbd0;
disk /dev/sdb1;
meta-disk /dev/sdb2[0];
on nfs {
address 172.16.1.31:7788;
}
on nfs-s {
address 172.16.1.32:7788;
}
}
3.3 初始化设备
drbdadm create-md r0
drbdadm up r0
cat /proc/drbd
NFS 主服务器提升
drbdadm -- --overwrite-data-of-peer primary r0
将主 NFS 服务器的 drbd0 格式化供使用
mkfs.ext4 /dev/drbd0
测试一下
mkdir /data
mount /dev/drbd0 /data
4 NFS 服务安装
4.1 安装服务
yum install -y rpcbind nfs-utils
4.2 配置
修改配置文件
echo "/data 10.0.0.0/24(rw,sync,anonuid=502,anongid=502,all_squash)" >/etc/exports
创建用户个用户组 , 赋予权限,这里的 502 是 创建的 nginx 用户的 UID
useradd -s /sbin/nologin -u 502 -M nginx
chown -R nginx.nginx /data
启动 NFS 服务
/etc/init.d/rpcbind start
/etc/init.d/nfs start
5. 安装 heartbeat
5.1 安装
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo
yum repolist
yum install -y heartbeat
5.2 修改配置
5.2.1 修改总体配置 /etc/ha.d/ha.cf
如下
## 日志文件
logfile /var/log/ha-log
logfacility local0
keepalive 2
deadtime 30
warntime 10
initdead 60
# 对方的IP
mcast eth0 225.0.0.31 694 1 0
auto_failback on
node nfs
node nfs-s
5.2.2 修改双机验证文件 /etc/ha.d/authkeys
auth 1
1 sha1 c4f9375f9834b4e7f0a528cc65c055702bf5f24a
修改一下权限
chmod 600 /etc/ha.d/authkeys
5.2.3 修改集群资源文件配置 /etc/ha.d/haresources
nfs 10.0.0.30 drbddisk::r0 Filesystem::/dev/drbd0::/data::ext4 nfs
注意这里配置的 IP 是 VIP, 两台服务器都一致
5.3 启动
/etc/init.d/heartbeat start
客户端挂载它
客户端需要安装nfs库,不然会提示下面这样的报错:
[root@nfsclient ~]# mount -t nfs 192.168.1.7:/nfs /database/
mount: wrong fs type, bad option, bad superblock on 192.168.1.7:/nfs,
missing codepage or helper program, or other error
(for several filesystems (e.g. nfs, cifs) you might
need a /sbin/mount.<type> helper program)
In some cases useful info is found in syslog - try
dmesg | tail or so
出现上面的报错后,安装nfs-utils
[root@nfsclient ~]# yum -y install nfs-utils
安装完之后挂载nfs,使用vip
[root@nfsclient ~]# showmount -e 192.168.1.100
clnt_create: RPC: Program not registered #出现这个错误的话,去nfs服务器上确认是否NFS服务正常启动,重启下即可
[root@nfsclient ~]# showmount -e 192.168.1.100
Export list for 192.168.1.100:
/nfs 192.168.1.0/255.255.255.0
[root@localhost ~]# mount -t nfs 192.168.1.100:/nfs /database/
[root@localhost ~]# df -hT
Filesystem Type Size Used Avail Use% Mounted on
/dev/sda2 ext4 28G 2.9G 24G 11% /
tmpfs tmpfs 491M 0 491M 0% /dev/shm
/dev/sda1 ext4 283M 28M 240M 11% /boot
192.168.1.100:/nfs nfs 9.8G 23M 9.2G 1% /database
# 挂载成功。
6、模拟Nfs-server故障
我们把NFSmaster关机,此时客户端不管是df ,还是进入到/database下面,都是卡死的。解决办法是在/etc/mtab里面删除最后一行:
[root@nfsclient ~]# cat /etc/mtab
/dev/sda2 / ext4 rw 0 0
proc /proc proc rw 0 0
sysfs /sys sysfs rw 0 0
devpts /dev/pts devpts rw,gid=5,mode=620 0 0
tmpfs /dev/shm tmpfs rw 0 0
/dev/sda1 /boot ext4 rw 0 0
none /proc/sys/fs/binfmt_misc binfmt_misc rw 0 0
vmware-vmblock /var/run/vmblock-fuse fuse.vmware-vmblock rw,nosuid,nodev,default_permissions,allow_other 0 0
nfsd /proc/fs/nfsd nfsd rw 0 0
sunrpc /var/lib/nfs/rpc_pipefs rpc_pipefs rw 0 0
192.168.1.100:/nfs /database nfs rw,addr=192.168.1.100 0 0 #删除这一行即可。
由此可见,这个heartbeat虽然会让VIP进行漂移,但是呢nfs客户端依然是不可用的。所以我们需要采用另外一种方法来来export共享目录。
删除export里面的内容,使用命令exporfs申明要共享的目录
我们删除/etc/exports里面的内容,然后通过exportfs来申明要共享的目录。
[root@nfsmaster ~]# > /etc/exports
[root@nfsmaster ~]# exportfs -o rw,sync,all_squash,mp,fsid=2 192.168.1.0/24:/nfs/
上面这种exportfs的方法同样可以申明共享目录,nfsclient也同样正常使用。
7、高可用方案
经过dbrd+heartbeat+NFS的搭建,以及exportfs的简单使用,下面我们就开始做高可用了。
说道高可用,不得不说exportfs这个命令,如果我们使用exportfs这个命令来申明需要共享目录的话,那么我们就不需要到/etc/exports里面再次添加这个要申明的目录了。
对于NFS高可用,我们需要使用exportfs来关闭共享的目录和打开共享的目录,这样做的好处就需要修改/etc/exports文件了,大大提高了方便性。对此,我们通过exportfs命令写了一个脚本,由heartbeat来接管这个脚本,当nfsmaster服务器宕机时,nfsbackup的heartbeat开始就执行脚本,脚本通过exportfs来共享目录,此时VIP也已经飘过去了,所以nfsclient受影响很小。达到了高可用的目的。更多关于exportfs的资料,可以参考man exportfs。下面就看看这个脚本的内容:
[root@nfsbackup ~]# cat /etc/ha.d/resource.d/rsdata1.sh #必须放在/etc/ha.d/resource.d下面
#!/bin/bash
FSID="1"
EXPORT_DIR="/nfs"
EXPORT_OPTIONS="-o rw,sync,all_squash,mp,fsid=2"
EXPORT_CLIENT="192.168.1.0/24"
exportfs_usage() {
cat <<EOF
USEAGE: $0 {start|stop}
EOF
}
exportfs_start()
{
fn="/nfs"
service rpcbind stop &>/dev/null
service rpcbind start &>/dev/null
service nfs restart &>/dev/null
echo "=======nfs restart========"
exportfs ${EXPORT_OPTIONS} ${EXPORT_CLIENT}:${EXPORT_DIR} 2>1& #通过exportfs来申明共享目录
rc=$?
if [ $rc -ne 0 ];then
echo "export resource ${EXPORT_DIR} error"
exit $rc
else
echo "export resource ok"
exit 0
fi
}
exportfs_stop()
{
fn="/nfs"
service rpcbind stop &>/dev/null
service rpcbind start &>/dev/null
service nfs restart &>/dev/null
echo "=======nfs restart========"
exportfs -u ${EXPORT_CLIENT}:${EXPORT_DIT} 2>1& 通过exportfs来取消共享目录
rc=$?
if [ $rc -ne 0 ];then
echo "export resource ${EXPORT_DIR} error"
exit $rc
else
echo "umount resource ok"
exit 0
fi
}
if [ $# -lt 1 ];then
exportfs_usage
exit 1
fi
case $1 in
start)
exportfs_start
;;
stop)
exportfs_stop
;;
*)
exit 1
;;
esac
这个脚本必须赋予可执行权限,且必须是LSB规范。同时在/etc/ha.d/haresources添加上这个脚本
[root@nfsmaster ~]# cat /etc/ha.d/haresources
nfsbackup IPaddr::192.168.1.100/24/eth0 drbddisk::r0 Filesystem::/dev/drbd0::/nfs::ext4 rsdata1.sh #尾部添加rsdata1.sh这个脚本名
上面的操作主备都需要操作。脚本主备都要有。
测试高可用性
此时VIP在nfsmaster上面,我们在nfsclient端首先挂载NFS共享目录后创建一些文件:
[root@nfsclient /]# mount -t nfs 192.168.1.100:/nfs /database #
[root@nfsclient /]# cd /database/
[root@nfsclient database]# touch {1..10}
[root@nfsclient database]# ls
1 10 2 3 4 5 6 7 8 9 lost+found readme
关闭nfsmaster的电源,模拟宕机。此时等待VIP漂移到nfsbackup上面。待漂移到位后,我们继续在nfsclient上操作:
[root@nfsclient database]# ls # 可以查看目录下的文件
1 10 2 3 4 5 6 7 8 9 lost+found readme
[root@nfsclient database]# rm -f {1..5} # 也可以删除文件。
[root@nfsclient database]# ls
10 6 7 8 9 lost+found readme