Rengeteg cikk szól az interneten arról, hogy webes szolgáltatásokat, milyen egyszerűen lehet haproxy segítségével skálázhatóbbá és ezáltal magasabb rendelkezésre állásúvá tenni. Én magam is beszámoltam róla egy írásban, itt, hogyan is lehet ezt összehozni. Arról viszont gyakorlatilag 0 cikket találtam, hogy haproxy-t lehet-e használni NFS backend-ekkel. Márpedig én most csináltam egyet, ami működik.
NFSv3 vs. NFSv4
Az NFS mindig is ellensége volt a tűzfallal foglalkozó kollégáknak Rengeteg port, amiket nagyon nehéz leszorítani valamilyen elfogadható számosságra. Korlátozások esetében pedig szinte garantált volt, hogy nem fog valami működni. Ez volt a helyzet egészen a hármas verzióig.
Erre nyújt többek között az NFS 4-es verziója némi megoldást. Ugyanis az NFS-t négyes verzióban használva megoldható, hogy egyetlen porton át működjön a kapcsolat.
# mount -t nfs4 -o proto=tcp,port=2049 10.0.0.58:/drbd/user1 /home/user1
root@xorp-nfs1:~# rpcinfo -p
program vers proto port service
100000 4 tcp 111 portmapper
100000 3 tcp 111 portmapper
100000 2 tcp 111 portmapper
100000 4 udp 111 portmapper
100000 3 udp 111 portmapper
100000 2 udp 111 portmapper
100024 1 udp 56757 status
100024 1 tcp 52530 status
100003 2 tcp 2049 nfs
100003 3 tcp 2049 nfs
100003 4 tcp 2049 nfs
100227 2 tcp 2049
100227 3 tcp 2049
100003 2 udp 2049 nfs
100003 3 udp 2049 nfs
100003 4 udp 2049 nfs
100227 2 udp 2049
100227 3 udp 2049
100021 1 udp 60468 nlockmgr
100021 3 udp 60468 nlockmgr
100021 4 udp 60468 nlockmgr
100021 1 tcp 40629 nlockmgr
100021 3 tcp 40629 nlockmgr
100021 4 tcp 40629 nlockmgr
100005 1 udp 47966 mountd
100005 1 tcp 36291 mountd
100005 2 udp 34060 mountd
100005 2 tcp 60121 mountd
100005 3 udp 41937 mountd
100005 3 tcp 34414 mountd
Ha viszont egyetlen portra le lehet szűkíteni az NFS kapcsolatot, akkor miért ne próbálnám meg, hogy a Haproxy tcp mode-ja segítségével több gép segítségével tegyem High Availabile szolgáltatássá az NFS-t.
Követelmények
Természetesen szükségünk lesz két backend szerverre. Viszont nem lesz elég csupán az, hogy kettő lesz belőllük. Az NFS által megosztott adatokat együtt kell kezelniük. Így gondoskodnunk kell arról, hogy vagy egy közös Shared volume legyen felmountolva mindkét helyre konkurens módon, vagy használhatjuk az Tamás kollégám által bemutatott DRBD dual primary + OCFS2 megoldást.
Tehát fontos, hogy mindkét helyen ugyan azok az adatok legyen elérhetőek, és bármelyik oldalon módosítunk a megosztott állományokon, az azonnal elérhető legyen a másik oldalon is. Innentől feltételezem, hogy ez már elérhető.
Előkészületek
Először is telepítsük fel a szükséges NFS csomagot mindkét backend gépre.
nfs1# apt-get install nfs-kernel-server
nfs2# apt-get install nfs-kernel-server
Majd egyből állítsuk is le.
nfs1# /etc/init.d/nfs-kernel-server stop
nfs2# /etc/init.d/nfs-kernel-server stop
Egyik gépen helyezzük át a /var/lib/nfs könyvtárat és teljes tartalmát a DRBD területre. Majd linkeljük vissza.
nfs1# mv /var/lib/nfs /drbd
nfs1# ln -s /drbd/nfs /var/lib/nfs
A másik oldalon csak archiváljuk le a régi /var/lib/nfs könyvtárat, majd itt is linkeljünk a már létező DRBD könyvtárra.
nfs2# ln -s /drbd/nfs /var/lib/nfs
Mindkét helyen szerkesszük meg a /etc/export file-t és állítsuk be a megosztani kívánt könyvtárat. Ami fontos, hogy ez is a DRBD területen legyen.
nfs1 # vi /etc/export
# /srv/nfs4/homes gss/krb5i(rw,sync,no_subtree_check)
#
/drbd/user1/ 10.0.0.40(rw,async,insecure,root_squash)
nfs2 # vi /etc/export
# /srv/nfs4/homes gss/krb5i(rw,sync,no_subtree_check)
#
/drbd/user1/ 10.0.0.40(rw,async,insecure,root_squash)
Majd indítsuk el az NFS szolgáltatást mindkét oldalon.
nfs1# /etc/init.d/nfs-kernel-server start
nfs2# /etc/init.d/nfs-kernel-server start
Haproxy konfiguráció
Természetesen a harpoxy-ban nem tudunk HTTP módot használni csak TCP-t. Nézzük milyen konfiguráció volt szükséges a HA NFS szolgáltatáshoz.
# vi /etc/haproxy/haproxy.cfg
global
log 127.0.0.1 local0
log 10.0.0.55 local0 info
stats socket /var/run/haproxy.sock mode 0600 level admin
maxconn 4096
user haproxy
group haproxy
daemon
#debug
#quiet
defaults
log global
option dontlognull
retries 3
option redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 60000
timeout http-request 5s
timeout connect 5s
timeout server 60s
timeout client 30s
frontend nfs-in
bind 10.0.0.40:2049
mode tcp
option tcplog
default_backend xorp-storage-nfs
backend xorp-storage-nfs
mode tcp
balance leastconn
server xorp-nfs1 10.0.0.58:2049 check
server xorp-nfs2 10.0.0.59:2049 check
Ahogy látszik TCP mode van a frontend és backend oldalon is beállítva. A 2049-es portot bind-olja ki a frontend, és értelemszerűen a backendeknél is erre csatlakozik. TCP módban csak Layer 4 ellenőrizést tesz lehetővé, de ebben az esetben ez is elég lehet.
Ezek után bármelyik alkalmas kliensen mountolhatjuk, a haproxy új NFS szolgáltatását.
client1# mount -t nfs4 -o proto=tcp,port=2049 10.0.0.58:/drbd/user1 /home/user1
client1# df -h
10.0.0.40:/drbd/user1 99G 58G 42G 59% /home/user1
Összegzés
Az ötlet már régóta megfogalmazódott bennem, viszont meglepetésemre egyetlen egy cikket sem találtam, ahol Haproxy-t tettek volna NFS elé. Pont ezért kicsit kételkedve kezdtem bele, mégis tökéletesen működik azóta nálam. Volt kieső backend, és a szolgáltatás tökéletesen elérhető maradt. Nincs adatkorrupció. Nem tudom más esetekben is mennyire működőképes, vagy épp veszélytelen ez a megoldás. Minden esetre nálam működőképes hetek óta.

Neked a sebességet is sikerült növelned ezzel a megoldással az NFS server és kliens között ?
Sajnos a DRBD-vel kuzdottem egy darabig, de kritikan aluli sebessegeket sikerult elernem :( Igy levaltottam. Az iras maga is csak azt kivanja bemutatni, hogy haproxy-val hogy tudnad megoldani. Sebessegben en nem tapasztaltam javulast a haproxynak koszonhetoen se, de a DRBD replikaio volt a szuk keresztmetszet.