GlusterFS frissítési kalandok

GlusterFS logó
„Avagy én már megint jól megszívtam, hogy neked ne kelljen”. Ez lehetne az alcím. Röviden összegezve szeretném visszakapni az életemből az elmúlt kb. 16 órát, bár kétségtelen, hogy rengeteg tapasztalattal gyarapodtam GlusterFS témakörben. De ne ugorjunk ennyire előre.

Hogy vázlatosan el lehessen képzelni a helyzetet, röviden felskiccelem az alapfelállást: Van egy kisebb, általam felügyelt/üzemeltetett Gluster klaszter. A Gluster szerverek Ubuntu 16.04-ek, míg a Gluster kliensek vegyesen Gentoo-k és Ubuntu 16.04-ek. A Gentoo klienseken futó virtuális gépek (KVM) GFAPI-val csatlakoznak a klaszterhez, az Ubuntu sima FUSE-t használ.

Felmerülhet a kérdés, hogy miért nem teljesen homogén a környezet, akkor jóval kevesebbet is szívnék (papíron). A válasz erre az, hogy bár nagyon jól tudok tákolni, nem szeretek. Nincs megfelelő GFAPI-val fordított Qemu/Libvirt bináris Ubuntura. Ami PPA-ból telepíthető az indításkor összeomlik. Fordítgathatnám, foltozgathatnám magam a Qemu+Libvirt+GFAPI szentháromságot, de ez is beláthatatlan mennyiségű potenciális buktatót és szívást jelentene. Ki tudja, hogy a következő nagyobb frissítéskor melyik függőség miatt nem fordulna, nem menne be valamelyik patch. Ahogy az sem garantált, hogy a GFAPI mindig sikeresen integrálódik, de ha mégis, alaposan tesztelni kellene, mielőtt kimegy PROD-ba... Ennél sokkal barátságosabb a Gentoo, és jóval kevesebb időm van. Ésszel használva alapvetően nem szokott a Gentoo-alapú telepítéseimmel gond lenni, és még systemd sincs. Tiszta haszon. :)

Visszatérve a klaszterhez, ezen futnak olyan kisebb-nagyobb szolgáltatások, melyek úgy vannak elosztva, hogy amiknek állandóan futniuk kell, azokból van tartalék. Amiből meg nincs, annak nem kritikus, ha rövidebb időre kiesik. Durván negyedévente szánok 3-4 órát arra, hogy a nagyobb frissítéseket (elsősorban Gluster) elintézzem, és ez általában elég is.

Ahogy közeledik az év vége, úgy szeretek minden dolgot elintézni, hogy tiszta lappal lépjek át az új évbe. A Gluster klaszter esetében lényegében ez egy nagyobb Gentoo frissítést és néhány kisebb Ubuntu frissítést jelent. A Gentoo tényleg elég nagyot lépett előre, új alapprofil jött, ami hozta magával többek közt a GCC 6.4.0-át, új Mesa-t, glibc-t és még elég sok mindent. Természetesen a Libvirt és a Gluster frissítés sem maradhatott ki. Ahogy azt a rendszer az alapprofil váltáskor erősen javasolta, újrafordítottam cakompakk az egész rendszert. Nem több 400 csomagnál, ez tényleg csak egy célgép.

Frissítés után szépen elindult a rendszer, kivéve a libvirtet. Itt jött az első hoppá:

[10301640.895761] traps: glusterepoll1[4877] general protection ip:7efddf5a6ad0 sp:7efdce567590 error:0 in libc-2.25.so[7efddf478000+1a6000]
[10301655.777394] traps: glusterepoll1[4941] general protection ip:7fe1ae46dad0 sp:7fe19d3df590 error:0 in libc-2.25.so[7fe1ae33f000+1a6000]

Ezt műveli a Libvirt indításkor. Ez elég rossz. Ahogy az tisztán látszik, valami gáz van a Gluster integrációval. Valami szívást emlegettem fentebb :). Bizonyításképp glusterfs flag nélkül fordítottam egy libvirtet és tádá, jó lett. Ez így nekem most annyira nem volt jó, mert szükségem van a GFAPI-ra. Itt szerencsém volt (először és utoljára a történetben), mert kisvártatva jött egy -r1-es update a libvirthez, ami a fenti segfault problémát megoldotta.

Ugyanakkor mikor megpróbáltam újracsatlakozni a klaszterhez, Transport endpoint is not connected hibával el lettem zavarva. Máskor is voltak már kapcsolódási problémáim, amik abból adódtak, hogy túl nagy volt a verziókülönbség a Gluster szerver és kliens közt. Itt 3.11 vs. 3.13, ami épp elég lehet egy ilyen hibához. Amúgy is frissíteni terveztem, szóval uzsgyi neki. Bár a 3.13-as Gluster a hónap elején jött ki, a szoftver kiadása pedig kvázi rolling jellegű, nem számítottam nagyobb bukfencre.

Az első gép frissítése után az egyik brick nem éledt fel. A fene se tudja miért, összeomlott a hozzátartozó glusterfsd, ilyen hibaüzeneteket dobálva:

[2017-12-11] I [socket.c:2474:socket_event_handler] 0-transport: EPOLLERR - disconnecting now
[2017-12-11] I [MSGID: 106005] [glusterd-handler.c:6071:__glusterd_brick_rpc_notify] 0-management: Brick <ip>:/mnt/GlusterFS-Primary has disconnected from glusterd.

Úgy egy órányi sikertelen tekergetés és keresgélés után úgy gondoltam, hogy nekem erre pont nincs most időm, próbáljuk meg a több bugfix verziót megélt 3.12-es verziót. Ez szépen fel is ment, ahogy számítottam. Némi szinkronizáció után minden kötet boldognak érezte magát az összes gépen. Szuper.

Itt az idő rápróbálni a Gentoo-ra. Ugyanaz a Transport endpoint is not connected hiba Libvirt oldalon. Itt már sejtettem, hogy nem úszom meg pár órával ezt a dolgot. Kézzel való csatoláskor, debug módban ezt dobta a logokba a Gluster:

[2017-12-11 18:37:35.930070] I [MSGID: 100030] [glusterfsd.c:2556:main] 0-/usr/sbin/glusterfs: Started running /usr/sbin/glusterfs version 3.13.0 (args: /usr/sbin/glusterfs --process-name fuse --volfile-server=10.252.0.5 --volfile-id=primary /mnt/GlusterFS-Client-Primary)
[2017-12-11 18:37:35.931059] W [MSGID: 101002] [options.c:995:xl_opt_validate] 0-glusterfs: option 'address-family' is deprecated, preferred is 'transport.address-family', continuing with correction
[2017-12-11 18:37:35.932048] E [MSGID: 101075] [common-utils.c:319:gf_resolve_ip6] 0-resolver: getaddrinfo failed (Address family for hostname not supported)
[2017-12-11 18:37:35.932057] E [name.c:267:af_inet_client_get_remote_sockaddr] 0-glusterfs: DNS resolution failed on host 10.252.0.5
[2017-12-11 18:37:35.932097] I [glusterfsd-mgmt.c:2209:mgmt_rpc_notify] 0-glusterfsd-mgmt: disconnected from remote-host: 10.252.0.5
[2017-12-11 18:37:35.932112] I [glusterfsd-mgmt.c:2230:mgmt_rpc_notify] 0-glusterfsd-mgmt: Exhausted all volfile servers
[2017-12-11 18:37:35.932124] I [MSGID: 101190] [event-epoll.c:613:event_dispatch_epoll_worker] 0-epoll: Started thread with index 1
[2017-12-11 18:37:35.932340] W [glusterfsd.c:1393:cleanup_and_exit] (-->/usr/lib64/libgfrpc.so.0(rpc_clnt_notify+0xab) [0x7ff484930d3b] -->/usr/sbin/glusterfs(+0x1141e) [0xb14192441e] -->/usr/sbin/glusterfs(cleanup_and_exit+0x54) [0xb14191d3e4] ) 0-: received signum (1), shutting down
[2017-12-11 18:37:35.932362] I [fuse-bridge.c:5855:fini] 0-fuse: Unmounting '/mnt/GlusterFS-Client-Primary'.
[2017-12-11 18:37:36.026409] I [fuse-bridge.c:5860:fini] 0-fuse: Closing fuse connection to '/mnt/GlusterFS-Client-Primary'.
[2017-12-11 18:37:36.026497] W [glusterfsd.c:1393:cleanup_and_exit] (-->/lib64/libpthread.so.0(+0x78f7) [0x7ff4840bd8f7] -->/usr/sbin/glusterfs(glusterfs_sigwaiter+0xf5) [0xb14191d5d5] -->/usr/sbin/glusterfs(cleanup_and_exit+0x54) [0xb14191d3e4] ) 0-: received signum (15), shutting down

A két legizgalmasabb sor pont egymás alatt van:

[2017-12-11 18:37:35.932048] E [MSGID: 101075] [common-utils.c:319:gf_resolve_ip6] 0-resolver: getaddrinfo failed (Address family for hostname not supported)
[2017-12-11 18:37:35.932057] E [name.c:267:af_inet_client_get_remote_sockaddr] 0-glusterfs: DNS resolution failed on host 10.252.0.5

[common-utils.c:319:gf_resolve_ip6] 0-resolver: getaddrinfo failed (Address family for hostname not supported). Ezen a gépen nincs támogatva az IPv6 (még a kernelből is ki van takarítva), de ő mégis ezt akarta használni. Nyilván nem megy, ha nem támogatott.

A következő izgalmas rész a DNS resolution failed on host 10.252.0.5. Valóban, az IP címről ő azt hiszi, hogy az egy hosztnév és fel akarja oldani. Hö’? Bizonyára én értettem félre valamit, ezért próbáltam több megoldással, de mindig az jött ki, hogy valóban feloldást akar. Pedig megpróbáltam nem létező IP címmel is, hátha én nem értem a hibaüzenetet. De nem, azt is hosztnévnek képzelte és fel akarta oldani. Hát jó. Annyi baj legyen, született egy hostnév bejegyzés a hosts fájlba, a --volfile-server= paramétere pedig egy gépnév lett, majd megpróbáltam újra csatlakozni. Nos, ugyanez. Végül újabb tesztnek bekerült az egyik szerver ipv6-os címe is a hostsba, hiszen az előző hibaüzenetnél a gf_resolve_ip6 volt a hibás. Hátha. Nyilván nem lesz jó, de az kiderülhet, hogy tényleg valami a Gluster+IPv6 környékén gázos-e vagy sem.

Erre kicsit változott a hibaüzenet:

[2017-12-11 18:51:05.057751] E [socket.c:3175:socket_connect] 0-glusterfs: socket creation failed (Address family not supported by protocol)

Nyilván nincs támogatva az IPv6 címzés, így nem tud socketet létrehozni, hiszen a teljes gépen ki van gyomlálva a támogatása. Innentől sehogy sem sikerült a Glustert rávennem arra, hogy ne foglalkozzon az IPv6-tal, mindenképp erőltette. Némi keresgélés után találtam is rá egy hibajegyet. Szóval tudják, hogy nem jó, de még nem csinálták meg.

Ha én most IPv6 támogatást akarok, akkor az kvázi megint a rendszer teljes újrafordításával jár, sőt új kernelt is kell hozzá konfigurálni és még ez és még az... Ez a gép eddig tökéletesen jól megvolt IPv6 nélkül, ezután is legyen már meg, arról nem is beszélve, hogy ez csak egy megérzés, semmi sem garantálja a sikert.

A következő lépés volt a GlusterFS kliensben is átállni 3.12.3-as verzióra. A várva várt sikerélményt ez sem hozta meg. Gluster kötet csatolásakor csodálatos segfault lett a jutalmam:

[2017-12-11 19:06:11.797937] I [MSGID: 100030] [glusterfsd.c:2524:main] 0-/usr/sbin/glusterfs: Started running /usr/sbin/glusterfs version 3.12.3 (args: /usr/sbin/glusterfs --volfile-server=Gluster-1 --volfile-id=primary /mnt/GlusterFS-Client-Primary -N)
[2017-12-11 19:06:11.800301] W [MSGID: 101002] [options.c:995:xl_opt_validate] 0-glusterfs: option 'address-family' is deprecated, preferred is 'transport.address-family', continuing with correction
[2017-12-11 19:06:11.802619] I [MSGID: 101190] [event-epoll.c:613:event_dispatch_epoll_worker] 0-epoll: Started thread with index 1
[2017-12-11 19:06:11.805554] I [MSGID: 101190] [event-epoll.c:613:event_dispatch_epoll_worker] 0-epoll: Started thread with index 2
[2017-12-11 19:06:11.805863] W [MSGID: 101174] [graph.c:363:_log_if_unknown_option] 0-primary-readdir-ahead: option 'parallel-readdir' is not recognized
[2017-12-11 19:06:11.806032] I [MSGID: 114020] [client.c:2360:notify] 0-primary-client-0: parent translators are ready, attempting connect on transport
[2017-12-11 19:06:11.806217] I [MSGID: 114020] [client.c:2360:notify] 0-primary-client-1: parent translators are ready, attempting connect on transport
[2017-12-11 19:06:11.806368] I [MSGID: 114020] [client.c:2360:notify] 0-primary-client-2: parent translators are ready, attempting connect on transport
pending frames:
frame : type(0) op(0)
frame : type(0) op(0)
patchset: git://git.gluster.org/glusterfs.git
signal received: 11
time of crash: 
2017-12-11 19:06:11
configuration details:
argp 1
backtrace 1
dlfcn 1
libpthread 1
llistxattr 1
setfsid 1
spinlock 1
epoll.h 1
xattr.h 1
st_atim.tv_nsec 1
package-string: glusterfs 3.12.3
/usr/lib64/libglusterfs.so.0(_gf_msg_backtrace_nomem+0xaa)[0x7fc4273a68fa]
/usr/lib64/libglusterfs.so.0(gf_print_trace+0x2f7)[0x7fc4273b0537]
/lib64/libc.so.6(+0x35040)[0x7fc42657b040]
/lib64/libc.so.6(xdr_uint64_t+0x80)[0x7fc426674ad0]
/usr/lib64/libgfxdr.so.0(xdr_gf_dump_req+0x9)[0x7fc426d2ada9]
/lib64/libtirpc.so.3(xdr_sizeof+0xa3)[0x7fc426f51d73]
/usr/lib64/glusterfs/3.12.3/xlator/protocol/client.so(+0xfae0)[0x7fc421134ae0]
/usr/lib64/glusterfs/3.12.3/xlator/protocol/client.so(+0x33c2c)[0x7fc421158c2c]
/usr/lib64/glusterfs/3.12.3/xlator/protocol/client.so(+0x1059c)[0x7fc42113559c]
/usr/lib64/libgfrpc.so.0(rpc_clnt_notify+0x22c)[0x7fc42716facc]
/usr/lib64/libgfrpc.so.0(rpc_transport_notify+0x23)[0x7fc42716be23]
/usr/lib64/glusterfs/3.12.3/rpc-transport/socket.so(+0x4fc5)[0x7fc422206fc5]
/usr/lib64/glusterfs/3.12.3/rpc-transport/socket.so(+0x9641)[0x7fc42220b641]
/usr/lib64/libglusterfs.so.0(+0x80bee)[0x7fc4273fcbee]
/lib64/libpthread.so.0(+0x78f7)[0x7fc4268fc8f7]
/lib64/libc.so.6(clone+0x3f)[0x7fc42663ec7f

Egészen elképesztően csodálatos.

A Google nem igazán akart most a barátom lenni, az strace sem volt túl segítőkész, a gdb előtt elkezdtem random Gluster jegyekbe is beleolvasni, hátha lesz releváns. A megoldáshoz vezető utat a Gentoo bugtrackerében a Bug 635172 (CVE-2017-15096) - sys-cluster/glusterfs-3.12.3: Null pointer dereference in send_brick_req function in glusterfsd/src/gf_attach.c című jegy alatt találtam. A jegy amúgy eredetileg a CVE-2017-15096 javításáról szólt, de átcsapott a beszélgetés a segfaultok irányába és a végén megszületett a Bug 639838 - sys-cluster/glusterfs-3.12.3[libtirpc]: glusterd crashes with segmentation fault jegy. Innen már gyerekjáték volt a megoldás.

Röviden összefoglalva így működik: vedd ki a glusterfs 3.12.3 use flagjei közül az ibtirpc-t.

A működő konfiguráció:
(Ubuntu) szerver GlusterFS verzió: 3.12.3
Gentoo:

Package: sys-cluster/glusterfs-3.12.3
Flags: fuse georeplication qemu-block syslog tiering vim-syntax xml -bd-xlator -crypt-xlator -debug -emacs -glupy -infiniband -libtirpc -rsyslog -static-libs -systemtap -test PYTHON_TARGETS="python2_7")

Libvirt verzió: 3.10.0-r1
Qemu verzió: 2.10.1