wtorek, 23 lutego 2016

Kernel Same-page Merging - drobiazg, który cieszy

Wziąłem się trochę za OpenStacka. Konkretnie za Swifta, a konkretnie za Swifta jako cloud storage do TSMa.^H^H^H^H Spectrum Protect :-P. No i mam lekki problem. W sumie mam dwa komputery z w sumie 24GiB RAM. A żeby postawić to w miarę koszernie to potrzebuję: 16GiB RAM na samego TSMa (to akurat zabobon, daje radę na 12  zwłaszcza, że to testówka, 2x4GB na storage nody Swiftwa + 2 GiB na keystone. Swifty spróbuję zmieścić w 2x2GiB (testówka). To daje razem, w wersji minimum, jakieś 18GiB RAM na same wirtualki. Co zostawia jednemu hostowi 4 GiB na system i aplikacje a drugiemu... raptem 2GiB. Trochę mało zwłaszcza, że oba muszą działać w grafice, a jeden z nich (ten 16gigowy z TSMem) musi ciągnąc jeszcze napisane w javie+eclipse korpo Lotusy-Gniotusy. Na drugim w tych pozostałych 2GB muszę upchnąć LibreOffice i Chrome + X okien xterminala.
Wirtualizator to oczywiście KVM + qemu. Hosty to Fedory 23. Jądro Linuxa zawiera mechanizm KSM: Kernel Same-page Merge, który pozwala deduplikować pamięć. Całość została pomyślana jako metoda na oszczędzanie pamięci w wirtualizatorach, ale w zasadzie każdy może użyć funkcji madvice :-)
Żeby to włączyć wystarczy zainstalować pakiet:
  • ksm - u mnie w takiej wersji: ksm-2.4.1-6.fc23.x86_64
A następnie włączyć usługę ksm.service.
Ale to za chwilę. Przyjrzyjmy się mojej pamięci RAM przed uruchomieniem maszyn wirtualnych:


Jak widać szału nie ma - standardowy zestaw aplikacji: Chrome, LibreOffice, Evolution wszystko w Gnome3. Istotne są dwie kolumny: VIRT - mówiąca ile pamięci aplikacja "myśli, że ma" i RES która pokazuje faktycznie, ile zajmuje dany proces w RAM.
Po odpaleniu dwóch maszyn wirtualnych (obie mają formalnie 2GB RAM, ale zaraz po uruchomieniu nie będą z tego korzystać) sytuacja wygląda następująco:

W sumie oba procesy qemu-system-x86 pożarły nieco ponad 1GB ramu.
Zobaczmy co się stanie po włączeniu KSM:

[marcinek@ajax:~]$ sudo systemctl start ksm

Pozwoliłem maszynom wirtualnym popracować około 10 minut. W tym czasie ksmd też nie próżnował i oto efekty:

Jak widać procesy qemu w sumie zjadły już 1341MiB (suma kolumn RES /1024). Zajętość pamięci hosta jest na poziomie 53%. Przy wyłączonym KSM, maszyny, które w sumie zajęły 1061MiB dawały utylizację RAMu hosta na poziomie 54%. Czary - zajętość ramu wzrosla, a utulizacja w % zmalała. 
Oczywiście pomiar nie jest super dokładny - musiałbym utłuc wszystkie procesy chodzące w tle, ale starałem się w nie nie zbytnio nie ignorować :-)
Jak sprawdzić ile zyskaliśmy na KSM? Trzeba zajrzeć do:

[marcinek@ajax:~]$ ls /sys/kernel/mm/ksm/
full_scans          pages_shared   pages_to_scan   pages_volatile  sleep_millisecs
merge_across_nodes  pages_sharing  pages_unshared  run

A konkretnie wyświetlić zawartość pliku pages_shared i pages_sharing:

[marcinek@ajax:~]$ cat /sys/kernel/mm/ksm/pages_shar*
47912
104698
Pierwsza wartość to liczba współdzielonych stron. Druga to oszczędność jaką mamy z zastosowania KSM. Obie wartości są w 4KB stronach, więc po przełożeniu na MB wychodzi odpowiednio: shared 187MiB, sharing 408MiB. To daje około 3% oszczędności pamięci hosta. Przy dwóch maszynach.
Za to przy trzech maszynach, każda po 2GiB RAM i pracy cały dzień, statystyki wyglądają już dużo ciekawiej:


Maszynki w sumie zajmują prawie 3GiB RAMu. Ale wskażnik pages_shared wynosi: 104898 co daje 409MB współdzielonych, przekładających się na 273768 stron (1069MB) zmapowanych. Zysk netto 660MB :-)

KSM i pliki z /sys/kernel/mm/ksm so opisane tutaj:

środa, 10 lutego 2016

IPSEC VPN i problemy z ssh

Wbijałem się ostatnio do testowych maszyn, które zostały mi wystawione przy pomocy Shrew Software VPN. To cudo bazuje na IPSEC i IKE. W Fedorę jest wbudowany klient tego VPNu i jego postanowiłem użyć:

ike.x86_64 : Shrew Soft VPN Client For Linux

Od dostawcy VPNu dostałem profil PCF, który się prawie zaimportował. Nie wciągnął sobie adresu bramki, wartości klucza PSK i identyfikatora klucza. O ile bramka i identyfikator są tekstowe, o tyle PSK jest zaszyfrowany i musiałem go wyciągnąć oddzielnie od dostawcy. (cisco-decrypt tu nie pomaga :-\ )

Po zapięciu połączenia dostajemy interfejs tap0:

12: tap0: <BROADCAST,UP,LOWER_UP> mtu 1200 qdisc noqueue state UNKNOWN group default qlen 500
    link/ether 56:55:f3:de:c3:32 brd ff:ff:ff:ff:ff:ff
    inet 192.168.254.69/32 brd 192.168.254.69 scope global tap0
       valid_lft forever preferred_lft forever


Okazało się, że trafiam na ciekawy objaw: 
SSH do hosta zawisa na 

debug1: SSH2_MSG_KEXINIT sent.

Żeby było zabawniej jak robię telnet na port 22 tegoż hosta to SSH odpowiada.

Po googlaniu okazało się, że istotne jest MTU, które VPN domyślnie ustawia na 1380, co według różnych forów jest zbyt dużą wartością, dlatego zmniejszyłem ją do 1200. 
To problemu nie rozwiązało. Dalsze przeszukiwanie sieci pokazało jeszcze jedną sugestię. Linux wydaje się ignorować informacje o fragmentowaniu pakietów przez routery po drodze. Ale znalazłem zaklęcie, które to naprawia. miałem trochę szczęścia, bo wkleiłem je bez zrozumienia i działa :-)

firewall-cmd --direct --add-passthrough ipv4 -I OUTPUT -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu

Teraz muszę rozkminić jak to ubrać w regułkę, którą firewalld będzie łykał i monitorował, bo dodanie "passthrough" jest mało zgrabne.