Vážení kolegové a nadšenci.
Postavil jsem dvou nodový Pacemaker cluster na OS CentOS 7.9, na kterém testuji vysokou dostupnost služby NFS 4.2. Služba NFS4 již plně pracuje na TCP. Do nižší verze než je verze 4.0 nemůžeme jít, protože nepodporuje námi požadované ACL. Při této příležitosti jsem narazil na zajímavý problém s rychlostí obnovení navázané komunikace mezi serverem a klientem, při přepnutí virtuální IP adresy z jedno nodu na druhý.
Nody mají připojený iSCSI disk s LVM, tento disk se exportuje pro NFS sdílení. Celé to zastřešuje virtuální IP adresa. Je také použit parametr pro sdílení stavových informací pro NFS, je umístěn na iSCSI svazku, který je připojen na obou nodech.
Konfigurace clusteru je následující (jedná se o skupinu):
Resource: lvm (class=ocf provider=heartbeat type=LVM)
Attributes: exclusive=true volgrpname=data
Resource: iscsidrive (class=ocf provider=heartbeat type=Filesystem)
Attributes: device=/dev/mapper/data directory=/mnt/data fstype=xfs
Resource: nfs-daemon (class=ocf provider=heartbeat type=nfsserver)
Attributes: nfs_no_notify=true nfs_shared_infodir=/mnt/data/nfsconf nfsd_args="-N2 -N3 -V4 --grace-time 10"
Resource: nfs-share (class=ocf provider=heartbeat type=exportfs)
Attributes: clientspec=10.0.0.0/255.0.0.0 directory=/mnt/data/data/ fsid=1 options=rw,sync,no_root_squash
Resource: nfs_ip (class=ocf provider=heartbeat type=IPaddr2)
Attributes: cidr_netmask=24 ip=10.0.0.100
/etc/nfs.conf
[nfsd]
vers4=y
vers4.2=y
konfigurace v /etc/sysconfig/nfs je dynamicky upravovaná pomocí resource ocf:heartbeat:nfsserver pacemakerem (viz. parametr nfsd_args a nfs_no_notify)
použité balíčky na nodech:
libnfsidmap-0.25-19.el7.x86_64
corosync-2.4.5-7.el7_9.1.x86_64
nfs-utils-1.3.0-0.68.el7.x86_64
corosync-qdevice-2.4.5-7.el7_9.1.x86_64
corosynclib-2.4.5-7.el7_9.1.x86_64
resource-agents-4.1.1-61.el7_9.8.x86_64
kernel: Linux node 3.10.0-1160.21.1.el7.x86_64 #1 SMP Tue Mar 16 18:28:22 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
použité balíčky na nfs klientovi:
libnfsidmap-0.25-19.el7.x86_64
nfs-utils-1.3.0-0.68.el7.x86_64
Linux nfs-client 3.10.0-1160.21.1.el7.x86_64 #1 SMP Tue Mar 16 18:28:22 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
Nebudu se rozepisovat o stonith, protože ten funguje v rámci možností našeho virtuálního prostředí poskytovatele.
Nyní k problému. Dobu výpadku jsem testoval tak, že jsem si napsal skript, který na NFS klientovi otevřel soubor pro zápis a každou sekundu zapisoval do tohoto souboru datum s časem, aniž by se soubor uzavřel. Zároveň jsem z tohoto souboru četl pomocí tail -f. Při odstavení jednoho nodu clusteru pomocí pcs standby node1 se prvně zastaví služby na stroji node1 a následně se nastartují služby na stroji node2. Celá tato akce časově zabere max. 15s. Při prvním výpadku od připojení sdíleného svazku, trvá na klientovi přerušení zápisu cca. 20s. Při dalším obnovení node1 pcs unstandby node1 a následném shozením služeb na stroji node2 již tento výpadek není 20s, ale zhruba 3,5min. Tato doba se dalšími shozeními již nemění. Až do doby, kdy provedu umount sdílené složky a nový mount. Vždy po prvním shození aktivního nodu se reset spojení a obnovení komunikace mezi klientem a serverem provede do 20s.
Protože potřebuji tuto službu pokud možná s co nejkratším výpadkem a 3,5min je opravdu dost dlouho, začal jsem zjištovat co se děje po dobu výpadku.
Z tcpdumpu jsem zjistil, že virtuální switch správně identifikuje, že se změnila MAC adresa virtuální ipadresy 10.0.0.100 a packety se začnou směřovat na správný stroj. Je zřejmé, že nový stroj neví co má s TCP stackem, který byl určen pro původní stroj dělat a tak na něj nereaguje. A tak čeká na reset spojení. Ten ovšem přijde vždy až po 8. retransmissi packetu což odpovídá cca 3,5min. RTO, které je dané normou RFC793, není dost možné změnit, protože je dynamicky ovlivněné stavem linky a doba do retransmisse se každou další retransmissí dvojnásobí. Počet retransmissí, které je možné do jisté míry ovlivnit, se mi nijak nepodařilo u NFS změnit. I přes nastavené parametry mountu klienta timeo=3 a retrans=1 a sysctl nastavení net.ipv4.tcp_retries2=3 se změna počtu retransmissí nijak nezměnila. Testoval jsem zda změna hodnoty net.ipv4.tcp_retries2 opravdu funguje a např. u SSH se opravdu spojení zresetovalo po 3. retransmissi packetu, ale NFS tuto volbu ignoruje. Toto ovšem neplatí při první odstávce jednoho z aktivních nodů, po novém mountu sdílené složky. Zde je pouze 5 retransmissí, po kterých se spojení resetuje. Stejně tak se to chová i po delší přestávce testování (když se např. 1 den nody nevypínají a nezapínají).
Také jsem zkoušel sychronizaci tcp stavů pomocí resource ocf:heartbeat:conntrackd. Pomocí služby conntrackd a jejích informací je vidět, že se stavy korektně předávají na druhý server, ale aplikace stejně čeká na reset tcp spojení.
Proto prosím o radu co jsem v konfiguraci přehlédl a nebo spatně nastavil, že se mi cluster takto podivně chová.
Předem děkuji za názory a nápady.