To jest prawdziwa historia, wiesz – taka oparta o faktach. Nikt nie zginął, no chyba, że liczymy te zaginione dni z mojego życia. Ale do rzeczy.
Jak wiesz jestem w trakcie przygotowywania kursu “Kubernetes po polsku” i jednym z jego elementów są moduły PRO. Poruszają one zaawansowane funkcje Kubernetes, których chyba nikt nigdy w kursie nie umieszczał. Są czasem dość odjechane, ale bardzo ciekawe i przydatne w średnich i dużych środowiskach.
Jedną z takich funkcji umieściłem w programie i w ramach moich prac postanowiłem to przetestować. Nawet nie wiedziałem jak bardzo intensywne te testy się okażą.
Moje środowisko
Do testów mam swój lab, a raczej kilka jego konfiguracji. Oto z czego się one składają:
- Kubeadm z własną konfiguracją do stawiania Kubernetes
- Czasem używam też k3s ze względu na szybsze stawianie węzłów (ale jako Control Plane odpada)
- Mam konfiguracje maszyn wirtualnych Vagrant na Macu z Virtualbox i na stacji z Windows 11 z Hyper-V
- Używam też Packera do budowania własnych obrazów dla Vagrant – to zdecydowanie przyspiesza mi stawianie środowisk
- Okazjonalnie też stawiam instancje w chmurze GCP i mam do tego kod Terraform – przydaje się do większych testów
Czyli jak widzisz mam wszystko czego potrzebuję. A do czego tego użyłem?
A miało być tak pięknie – dzień 1
W ramach kursu chcę wytłumaczyć jak użyć zaawansowanych reguł kierowania ruchem do instancji, aby aplikacje komunikowały się szybciej.
I jedną z takich funkcji jest Topology Aware Hints. Dokumentacja jest, przykładów brak. Ale co to dla mnie!
Przystąpiłem do testów i… klops. Nie działa. Tylko dziwne komunikaty w logach. Nie ukrywam – strasznie się zirytowałem! Przeszukałem Internet i nic – najwidoczniej niewiele osób tego jeszcze używa. Podwójna szkoda – nie wiedzą co tracą, a ja wciąż nie mam rozwiązania.
Brak przykładów zmusił mnie do zajrzenia do kodu źródłowego kontrolera odpowiadającego za obsługę tej funkcji. Jedyne czego się dowiedziałem to to, że część informacji nie jest logowana. To na koniec dnia zwiększyłem gadatliwość komponentu kube-controller-manager o jeden (-v2) w ramach ustawień kubeadm. Nie pomogło za wiele.
Bliżej, a jednak wciąż tak daleko – dzień 2
Logi tylko nakierowały mnie bliżej, ale wciąż nie miałem tego co chciałem. Teraz wiedziałem, że szukałem nie tam gdzie powinienem. I powiem szczerze, że nie znając zasad działania Kubernetes pewnie bym tak utknął.
I tak spędziłem cały dzień eksperymentując na różnych konfiguracjach i czytając kod źródłowy (szczególnie ten fragment). Aż w końcu doznałem pierwszego olśnienia – ta funkcja nie działa na węzłach control plane! Usunąłem labelki z moich trzech węzłów i… dalej nic.
Ale po dodaniu kolejnego węzła (ta funkcja nie działa jeśli nie ma wystarczającej ilości węzłów w strefach) już witałem się z gąską – w logachv pojawiła się wyczekiwana informacja, że funkcja “Topology Aware Hints has been enabled”. No w końcu! Przystąpiłem do testów, uruchomiłem przykładowe aplikacje w podach, puściłem ruch, a tu niespodzianka – dalej nie działa.
Znowu zawiedziony kończyłem dzień i coś co miało zająć tylko chwilę przedłuża się na kolejny dzień. W tym momencie miałem odpuścić i następnego dnia przejść do kolejnego tematu.
Albo ja albo on – dzień 3
“Nie tym razem – nie mogę tak tego odpuścić” – pomyślałem kiedy zaczynałem kolejny dzień. Ze świeżym umysłem zasiadłem i odpaliłem po raz chyba 50-ty moją konfigurację maszyn i sprawdziłem reguły ruchu wystawiane przez kube-proxy na iptables (nagrałem o tym wideo).
I co? Wszystko tam wyglądało dobrze – ruch powinien trafiać tylko do części aplikacji, a moje testy nadal pokazywały, że ruch idzie do wszystkich. Dodatkowo licznik tych reguł wskazywał na 0, czyli w ogóle ruch nie trafiał do tych łańcuchów. Ale dlaczego?
I kolejne olśnienie – w mojej konfiguracji użyłem Cilium do obsługi sieci. A Cilium jest bardzo fajne, ale działa w oparciu o eBPF i również manipuluje regułami iptables. Podmieniłem Cilium na Calico i.. Ruszyło! W końcu po trzech dniach z ulgą przyjąłem fakt, że to nie ja, nie sam Kubernetes, a Cilium coś namieszał.
I tak spędziłem 3 dni na diagnozowaniu tego błędu. Sporo przy okazji jeszcze się dowiedziałem o innych komponentach, ale to już może historia na kolejny raz.
Czego się nauczyłem
Wszystko może być lekcją, nawet (a może szczególnie) jak kosztuje Cię 3 dni i kupę irytacji. Oto co wyciągnąłem z tego dla siebie:
- Nawet jak myślisz, że już dużo wiesz to mogą czekać Cię niespodzianki – po prostu bądź gotowy do ciągłej nauki, nawet jak Cię to wkurza
- Dokumentacja ma sens, szczególnie dobra, ale przykłady mają jeszcze większy sens – łatwiej jest wklejać, nawet na początku bezmyślnie, niż samodzielnie rozkminiać
- Nawet jak nie jesteś developerem to umiejętność czytania kodu ma wymierne korzyści – w tym przykładzie ewidentnie bym poległ, gdybym nie potrafił zrozumieć co jest pod spodem
- Pomagaj społeczności – ja w wyniku tych eksperymentów zgłosiłem bug na GitHubie i liczę, że oszczędzi to innym cennych dni i niepotrzebnych nerwów
- Cilium jest wspaniałe, ale ten nowy sposób działania (ePBF) może wymagać czasu na dostosowanie do wszystkich zaawansowanych funkcji Kubernetes
- I oczywiście – nigdy się nie poddawaj, ale też daj sobie czasu. Mogłem się poddać po pierwszym lub drugim dniu, ale odpoczynek pozwolił mojemu umysłowi na kolejną rundę i ze świeżym spojrzeniem udało mi się dotrzeć do celu.