Rys. 1. Każdy klient API korzysta z adresu wirtualnego. Jedno połączenie skonfigurowane na adres węzła zamienia awarię węzła w awarię klastra.

Dokumentacja każdej dystrybucji Kubernetes obiecuje wysoką dostępność po uruchomieniu trzech węzłów control plane. To prawda w bardzo wąskim sensie: baza etcd przeżyje utratę jednego węzła. Wszystko powyżej etcd trzeba zaprojektować osobno, a w małych klastrach, gdzie każdy węzeł pełni kilka ról jednocześnie, punktów awarii jest więcej, niż sugeruje schemat.

Adres serwera API

Klienci klastra, w tym kubelet na każdym węźle i sam CNI, muszą łączyć się z serwerem API pod jakimś adresem. Jeśli jest to adres pierwszego węzła, awaria tego węzła zatrzymuje cały klaster, mimo że etcd nadal działa. Rozwiązaniem jest wirtualny adres IP przenoszony między węzłami control plane lub zewnętrzny load balancer.

Częsty błąd: wirtualny adres istnieje, ale nie wszystkie komponenty z niego korzystają. Wtyczka sieciowa skonfigurowana podczas instalacji na adres konkretnego węzła będzie działała miesiącami, aż ten konkretny węzeł padnie. Wtedy wtyczka traci połączenie z API, przestaje programować sieć, DNS w klastrze przestaje odpowiadać, a każda aplikacja, która rozwiązuje nazwy, zaczyna zgłaszać błędy. Awaria jednego węzła zamienia się w awarię całego klastra, a przyczyna źródłowa jest odległa od objawów.

Zasada: każdy komponent, który łączy się z API, korzysta wyłącznie z adresu wirtualnego. Warto to zweryfikować po instalacji, a nie zakładać.

Stabilność samego adresu wirtualnego

Komponent utrzymujący wirtualny adres, niezależnie od tego, czym jest, sam może być niestabilny. Jeśli często restartuje, adres na chwilę znika i pojawia się na innym węźle. Pojedyncze przełączenie jest niegroźne; seria przełączeń w krótkim czasie potrafi wywołać kaskadę ponownych połączeń, których niektóre komponenty nie obsługują dobrze.

Restarty tego komponentu należy monitorować tak samo uważnie jak stan etcd. Liczba restartów rosnąca z tygodnia na tydzień to sygnał, że coś jest źle skonfigurowane, nawet jeśli klaster „działa”.

Przechowywanie danych

Baza danych w kontenerze z operatorem obiecuje automatyczny failover. Zwykle tak jest: nowy węzeł główny zostaje wybrany w ciągu kilkudziesięciu sekund. Pytanie brzmi, co dzieje się z replikami. Replika, która straciła połączenie ze starym węzłem głównym, nie zawsze automatycznie podłącza się do nowego. Może działać, odpowiadać na zapytania i jednocześnie nie replikować niczego, dopóki padnięty węzeł nie wróci.

Wnioski:

  • monitorować opóźnienie replikacji, a nie tylko liczbę działających instancji,
  • testować scenariusz, w którym padnięty węzeł nie wraca przez kilka godzin,
  • wiedzieć, jak ręcznie wymusić ponowne podłączenie repliki, zanim będzie to potrzebne.

Rejestr obrazów

Po awarii węzła Kubernetes przenosi pody na pozostałe węzły. Jeśli polityka pobierania obrazów wymusza sprawdzenie rejestru przy każdym uruchomieniu, w ciągu kilku minut klaster wykonuje dziesiątki zapytań do rejestru. Publiczne rejestry mają limity i klaster w środku awarii zaczyna dostawać odmowy.

Dwa środki zaradcze: polityka pobierania ustawiona tak, aby korzystać z lokalnie obecnego obrazu, jeśli jest dostępny, oraz własny rejestr lub proxy z pamięcią podręczną w sieci lokalnej.

Zależność od DNS poza klastrem

Węzły muszą rozwiązywać nazwy: rejestru, repozytoriów, źródeł aktualizacji. Jeśli jedynym serwerem DNS jest usługa działająca wewnątrz tego samego klastra albo na jednym z jego węzłów, każda awaria sieci klastra odbiera węzłom możliwość naprawy. Węzły powinny mieć co najmniej jeden serwer DNS niezależny od klastra.

Test, który mówi prawdę

Jedyną wiarygodną weryfikacją jest wyłączenie węzła. Nie wyłączenie usługi, nie odłączenie kabla na dziesięć sekund, tylko twarde zatrzymanie maszyny na czas dłuższy niż wszystkie limity czasu w systemie, czyli w praktyce co najmniej dwadzieścia minut. Po teście należy sprawdzić nie tylko to, czy aplikacje odpowiadają, ale też stan replikacji, liczbę restartów komponentów systemowych i logi wtyczki sieciowej.

Klaster, który przeszedł ten test dla każdego węzła z osobna, można nazwać wysokodostępnym. Klaster, którego nikt nie odważył się przetestować w ten sposób, jest wysokodostępny wyłącznie w dokumentacji.