Sprawę miałem opisać już jakiś czas temu i zapomniałem, a jest szansa, że komuś się przyda. Był sobie serwer, na którym działało trochę VPSów. Wszystkie KVM, wszystkie z systemem plików ext4 i obrazem dysku qcow2. Czyli standard. Sprzęt nie pierwszej młodości, ale działały względnie stabilnie. Poza jedną, w sumie najbardziej obciążoną, bo działał w niej jeden z serwerów Zabbixa. Niespecjalnie obciążony w porównaniu z innymi, w których jednak żaden nie działał w KVM.
Tej jednej zdarzał się zaliczyć zwis, z komunikatami dotyczącymi KVM i task blocked for more than 120 seconds:
kernel: INFO: task XXX blocked for more than 120 seconds.kernel: "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
Wymagany był reboot wirtualki. Dotyczyło to różnych tasków, a całość działa się losowo. Potrafiło działać przez kilka tygodni, a potrafiło wywalić się co parę dni, co nie ułatwiało diagnostyki. Początkowo działo się to na tyle rzadko, że sprawa została zignorowana. Jedkal w miarę wzrostu obciążenia maszyny fizycznej, problem się nasilał. Objaw był taki, że operacje wymagające zapisu na dysk nie wykonywały się (czyli monitoring zdychał). Zacząłem szukać przyczyn. Pierwotnie podejrzenie padło na coś, co wykonuje się z crona, bo sporo procesów crona wisiało. Jedak przejrzenie skryptów pokazało, że niespecjalnie mogą one być przyczyną
Wyglądało, jakby momentami coś nie wyrabiało się dostępem do dysków w momentach większego obciążenia. Z tym, że znowu – widać było, że nie jest to deterministyczne. Ponieważ maszyny jak wspomniałem starawe, to podejrzenie padło na sprzęt – problemy z dostępem do dysków potrafią robić cuda. SMART pokazywał, że wszystko OK, ale sprawdzić nie zawadzi… Przeniesienie wirtualki na inną, mniej obciążoną maszynę fizyczną nie przyniosło rezultatów – wieszało się nadal, chociaż rzadziej.
Oczywiście wyłączenie komunikatu, które jest w nim wspomniane, nie rozwiązuje problemu. W międzyczasie trafiłem na opis rozwiązania problemu KVM task blocked, czyli zmniejszenie vm.dirty_ratio oraz vm.dirty_backgroud_ratio. Tylko że… to nie pomogło. Nie pomogło także zwiększenie kernel.hung_task_timeout_secs początkowo do 180, potem do 300 sekund. Było trochę lepiej, ale problem nadal występował. Pół żartem, pół serio zacząłem się zastanawiać nad automatycznym rebootem po wystąpieniu problemu (zawsze to krótsza przerwa), ale to brzydkie obejście, nie rozwiązanie. Tym bardziej, że w miarę wzrostu obciążenia i VPSa, i maszyny fizycznej na której on działał, problem zaczął występować częściej. Góra co parę dni. Paradoksalnie, dobrze się stało, bo i motywacja większa, i sprawdzanie efektu wprowadzonych zmian łatwiejsze.
Z braku opisów w sieci, pomocy znajomych adminów i innych pomysłów zacząłem sprawdzać po kolei wszystko. Od fsck systemu plików, przez nowsze wersje kernela, zarówno na maszynie fizycznej, jak i na wirtualce – a nuż coś poprawili. Bez rezultatu. Ostatecznie postanowiłem zmienić format dysku wirtualki z qcow2 na raw i… trafiony, zatopiony – wirtualka zaczęła działać stabilnie.
Dla pewności wróciłem jeszcze z raw z powrotem na qcow2, na wypadek, gdyby chodziło o jakieś błędy, których nie wykrywało narzędzie do sprawdzania qcow2, ale… problem natychmiast wrócił. Gwoli ścisłości: ww. tuning dotyczący parametrów kernela z serii vm.dirty został zachowany.
Swego czasu byłem zszokowany gdy okazało się, że jedna z wirtualek z jakimś Debianem dostawała czkawki z powodu braku dostatecznej liczby losowych bodźców do generatora liczb pseudolosowych. Okresowe uruchomienie standardowych bibliotek (proste aplikacje oparte o Javę i driver Oracle) alokowało ich za każdym razem tak dużo, że wirtualka bez klawiatury, myszki, i innych takich nie dawała rady z zapełnieniem braków. Wystarczyło przełączyć domyślny parametr i poszło. 😉