nfs server отказоустойчивый кластер haproxy + lsync

Thank you for reading this post, don't forget to subscribe!

Отка­зо­устой­чи­вость фай­ло­во­го хра­ни­ли­ща дости­га­ет­ся посред­ством HAProxy, кото­рый пере­клю­ча­ет тра­фик меж­ду доступ­ны­ми хоста­ми и Lsyncd, кото­рый выпол­ня­ет репли­ка­цию дан­ных меж­ду нода­ми. В дан­ной реа­ли­за­ции HAProxy каж­дые 10 секунд про­ве­ря­ет доступ­ность сер­ве­ров, пере­чис­лен­ных в дирек­ти­вах backend be_nfs_*. В слу­чае если основ­ной сер­вер ока­жет­ся недо­ступ­ным, то тра­фик пере­клю­ча­ет­ся на резерв­ный, при этом репли­ка­ция фай­лов меж­ду все­ми нода­ми NFS сер­ве­ра рабо­та­ет постоянно.

име­ем сле­ду­ю­щие сервера:

nfs-haproxy-151 - 192.168.1.151 тут будет сто­ять haproxy keepalived(192.168.1.150)
nfs-haproxy-152 - 192.168.1.152 тут будет сто­ять haproxy keepalived(192.168.1.150)
nfs-153 - 192.168.1.153 тут будет сто­ять nfs server
nfs-154 - 192.168.1.154 тут будет сто­ять nfs server

[root@nfs-haproxy-151 ~]# yum install keepalived -y
[root@nfs-haproxy-152 ~]# yum install keepalived -y

[root@nfs-haproxy-151 ~]# cat /etc/keepalived/keepalived.conf

 

 

[root@hfs-haproxy-152 ~]# cat /etc/keepalived/keepalived.conf

 

 

 

[root@nfs-haproxy-151 ~]# echo "net.ipv4.ip_nonlocal_bind = 1" >> /etc/sysctl.conf
[root@nfs-haproxy-151 ~]# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
[root@nfs-haproxy-151 ~]# sysctl -p

[root@nfs-haproxy-152 ~]# echo "net.ipv4.ip_nonlocal_bind = 1" >> /etc/sysctl.conf
[root@nfs-haproxy-152 ~]# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
[root@nfs-haproxy-152 ~]# sysctl -p

[root@nfs-haproxy-151 ~]# systemctl enable keepalived && systemctl start keepalived
[root@nfs-haproxy-152 ~]# systemctl enable keepalived && systemctl start keepalived

теперь ста­вим haproxy

[root@nfs-haproxy-151 ~]# yum install haproxy -y
[root@hfs-haproxy-152 ~]# yum install haproxy -y

кон­фиг хапрок­си оди­на­ко­вый на 2х тачках:
[root@nfs-haproxy-151 ~]# cat /etc/haproxy/haproxy.cfg
[root@nfs-haproxy-152 ~]# cat /etc/haproxy/haproxy.cfg

 

 

[root@nfs-haproxy-151 ~]# systemctl enable haproxy && systemctl start haproxy
[root@nfs-haproxy-152 ~]# systemctl enable haproxy && systemctl start haproxy

 

перейдём к настройке nfs

ста­вим nfs:

[root@nfs-153 ~]# yum -y install nfs-utils
[root@nfs-154 ~]# yum -y install nfs-utils

добав­ля­ем раз­дел для nfs:

pvcreate /dev/sdb
vgextend centos /dev/sdb
mkdir /nfs
lvcreate -n nfs -l 100%FREE centos
mkfs.ext4 /dev/mapper/centos-nfs
mount /dev/mapper/centos-nfs /nfs

cat /etc/fstab | grep nfs
/dev/mapper/centos-nfs /nfs ext4 defaults 1 2

[root@nfs-153 ~]# mkdir /nfs/data
[root@nfs-153 ~]# mkdir /nfs/tmp
[root@nfs-154 ~]# mkdir /nfs/data
[root@nfs-154 ~]# mkdir /nfs/tmp

[root@nfs-153 ~]# chown -R nfsnobody:nfsnobody /nfs/
[root@nfs-154 ~]# chown -R nfsnobody:nfsnobody /nfs/

[root@nfs-153 ~]# echo "/nfs/data *(rw,sync,all_squash,insecure,fsid=0)" >> /etc/exports
[root@nfs-154 ~]# echo "/nfs/data *(rw,sync,all_squash,insecure,fsid=0)" >> /etc/exports

«мож­но заме­нить на ука­за­ние под­се­ти, содер­жа­щей сер­ве­ры при­ло­же­ний (в виде x.y.z.w/n).

[root@nfs-153 ~]# exportfs -a
[root@nfs-154 ~]# exportfs -a

[root@nfs-153 ~]# systemctl enable nfs-server && systemctl start nfs-server
[root@nfs-154 ~]# systemctl enable nfs-server && systemctl start nfs-server

 

перейдём к настройке lsync

Lsyncd про­смат­ри­ва­ет дере­во локаль­ных дирек­то­рий с помо­щью интер­фей­са моду­ля мони­то­рин­га Inotify. Он агре­ги­ру­ет и ком­би­ни­ру­ет собы­тия за несколь­ко секунд и затем запус­ка­ет про­цесс (или несколь­ко про­цес­сов) син­хро­ни­за­ции изме­не­ний. По умол­ча­нию для этих целей исполь­зу­ет­ся rsync. Таким обра­зом, Lyncd – лег­ко­вес­ное реше­ние для зер­ка­ли­ро­ва­ния дан­ных, срав­ни­тель­но лег­кое в уста­нов­ке, не тре­бу­ю­щее спе­ци­фич­ных фай­ло­вых систем или блоч­ных устройств, а так­же не вли­я­ю­щее на про­из­во­ди­тель­ность фай­ло­вой системы.

[root@nfs-153 ~]# yum -y install lsyncd
[root@nfs-154 ~]# yum -y install lsyncd

создай­те дирек­то­рию для кон­фи­гу­ра­ци­он­но­го фай­ла и логов:

[root@nfs-153 ~]# mkdir -p /etc/lsyncd
[root@nfs-153 ~]# mkdir -p /var/log/lsyncd
[root@nfs-154 ~]# mkdir -p /etc/lsyncd
[root@nfs-154 ~]# mkdir -p /var/log/lsyncd

создай­те поль­зо­ва­те­ля, назначь­те пароль, назначь­те пра­ва на ката­лог для поль­зо­ва­те­ля и сге­не­ри­руй­те для него SSH-клю­чи - этот шаг выпол­ни­те на всех нодах выпол­ня­ю­щих роль NFS-сервера:

[root@nfs-153 ~]# mkdir -p /var/log/lsyncd
[root@nfs-153 ~]# adduser nfssync
[root@nfs-153 ~]# setfacl -R -m u:nfssync:rwx /nfs/
[root@nfs-153 ~]# setfacl -R -d -m u:nfssync:rwx /nfs/
[root@nfs-153 ~]# setfacl -R -m u:nfssync:rwx /nfs/
[root@nfs-153 ~]# passwd nfssync   #вве­сти и под­твер­дить пароль, пароль мож­но исполь­зо­вать произвольный

[root@nfs-153 ~]# su - nfssync -c "ssh-keygen -t rsa"
#далее на всех пунк­тах нажать Enter

[root@nfs-154 ~]# mkdir -p /var/log/lsyncd
[root@nfs-154 ~]# adduser nfssync
[root@nfs-154 ~]# setfacl -R -m u:nfssync:rwx /nfs/
[root@nfs-154 ~]# setfacl -R -d -m u:nfssync:rwx /nfs/
[root@nfs-154 ~]# setfacl -R -m u:nfssync:rwx /nfs/
[root@nfs-154 ~]# passwd nfssync
[root@nfs-154 ~]# su - nfssync -c "ssh-keygen -t rsa"

ско­пи­руй­те клю­чи на все ноды, со всех хостов выпол­ня­ю­щих роль NFS-сервера:

[root@nfs-153 ~]# su - nfssync
[nfssync@nfs-153 ~]$ ssh-copy-id nfssync@192.168.1.154
[root@nfs-154 ~]# su - nfssync
[nfssync@nfs-154 ~]$ ssh-copy-id nfssync@192.168.1.153

При­ме­ча­ние
– Необ­хо­ди­мо будет вве­сти пароль поль­зо­ва­те­ля nfssync на ноде к кото­рой будет осу­ществ­лять­ся подключение.

создай­те и отре­дак­ти­руй­те файл

/etc/lsyncd.conf

сле­ду­ю­щим обра­зом на всех нодах. В слу­чае если нод более 2х, добавь­те блок sync {} для после­ду­ю­щих серверов:

[root@nfs-153 ~]# cat /etc/lsyncd.conf

 

 

 

[root@nfs-154 ~]# cat /etc/lsyncd.conf

 

 

 

[root@nfs-153 ~]# systemctl enable lsyncd && systemctl start lsyncd
[root@nfs-154 ~]# systemctl enable lsyncd && systemctl start lsyncd

теперь подключим шару через наш кластер.

ста­вим кли­ен­та и под­клю­ча­ем шару:

[root@ansible ~]# yum install nfs-utils -y
[root@ansible ~]# mkdir /nfs
[root@ansible ~]# mount 192.168.1.150:/nfs/data /nfs

про­ве­ря­ем:

[root@ansible ~]# touch /nfs/file1

[root@nfs-153 ~]# ll /nfs/data/
total 0
-rw-rw-r--+ 1 nfsnobody nfsnobody 0 Jan 17 22:04 file1

[root@nfs-154 ~]# ll /nfs/data/
total 0
-rw-rw-r--+ 1 nfssync nfssync 0 Jan 17 22:04 file1

теперь проведём ряд тестов при падении узлов:
  1. пер­вым поло­жим 192.168.1.153 (в haproxy он явля­ет­ся основным)

[root@nfs-153 ~]# poweroff
созда­ём вто­рой файл на клиенте:
[root@ansible ~]# touch /nfs/file-from-client2
и смот­рим что файл создал­ся на шаре:

[root@nfs-154 ~]# ll /nfs/data/
total 0
-rw-rw-r--+ 1 nfssync nfssync 0 Jan 17 22:04 file1
-rw-rw-r--+ 1 nfsnobody nfsnobody 0 Jan 17 22:06 file-from-client2

как видим он создал­ся с вла­дель­цем и груп­пой nfsnobody  а не nfssync  как при реплицировании.
теперь вклю­чим основ­ной сер­вер nfs и гля­нем что произойдёт.
как ниже видим, вто­рой файл засинковался:
[root@nfs-153 ~]# ll /nfs/data/
total 0
-rw-rw-r--+ 1 nfsnobody nfsnobody 0 Jan 17 22:04 file1
-rw-rw-r--+ 1 nfssync nfssync 0 Jan 17 22:06 file-from-client2

отсю­да вывод мож­но спо­кой­но ложить один из nfs сер­ве­ров, после его вклю­че­ния на него будут под­ки­ну­ты файлы.

2. теперь про­ве­рим что будет если поло­жить сер­вак с хапрок­си на кото­ром вир­ту­аль­ный айпишник.

[root@nfs-haproxy-151 ~]# poweroff

про­ве­ря­ем что айпиш­ник переехал:
[root@hfs-haproxy-152 ~]# ip a | grep vip
inet 192.168.1.150/32 scope global enp0s3:vip

смот­рим на кли­ен­те под­мон­ти­ро­ван­ную директорию:
[root@ansible ~]# ll /nfs/
total 0
-rw-rw-r--+ 1 nfsnobody nfsnobody 0 Jan 17 22:04 file1
-rw-rw-r--+ 1 1004 1004 0 Jan 17 22:06 file-from-client2

всё ок, созда­ём новый файл:

[root@ansible ~]# touch /nfs/22

ииии всё ок, файл создан:

[root@ansible ~]# ll /nfs/
total 0
-rw-rw-r--+ 1 nfsnobody nfsnobody 0 Jan 17 22:13 22
-rw-rw-r--+ 1 nfsnobody nfsnobody 0 Jan 17 22:04 file1
-rw-rw-r--+ 1 1004 1004 0 Jan 17 22:06 file-from-client2

3. теперь поло­жим nfs сер­вер 153 (ито­го вир­ту­аль­ный айпиш­ник пере­ехал, основ­ной nfs сер­вак поло­жен) созда­ём кучу фай­лов и пароч­ку больших
[root@ansible ~]# for i in {1..1000}; do touch /nfs/$i; done
[root@ansible ~]# dd if=/dev/urandom of=/nfs/1GB.file bs=1048576 count=1024
[root@ansible ~]# dd if=/dev/urandom of=/nfs/1.1GB.file bs=1048576 count=1024

после вклю­че­ния 192.168.1.153 сер­ва­ка, фай­лы вре­мен­но пере­ме­ща­ют­ся в дирек­то­рию /nfs/tmp/
[root@nfs-153 ~]# ll /nfs/tmp/
total 937988
-rw-------+ 1 nfssync nfssync 960495616 Jan 17 22:29 1.1GB.file.mLvZXq

и толь­ко после того как файл пол­но­стью ско­пи­ру­ет­ся во вре­мен­ную дирек­то­рию он пере­ме­ща­ет­ся в основную.