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.