Migracja kilkunastu aplikacji na własny klaster k3s — problemy i korzyści
Nasz trzeci klaster Kubernetes na bare metal — pierwszy produkcyjny u klienta. Działa od listopada 2023 roku i obsługuje około 20 aplikacji w czterech środowiskach. Opisujemy architekturę, siedem problemów, które nas zaskoczyły, i to, co realnie zyskaliśmy.
Kubernetes na własnym sprzęcie ma opinię projektu dla dużych zespołów. Zbudowaliśmy i utrzymujemy taki klaster dla platformy SaaS i jej narzędzi wewnętrznych. Poniżej uczciwe podsumowanie — łącznie z tym, co poszło źle.
Punkt wyjścia
Przed migracją aplikacje działały jako ręczne wdrożenia bezpośrednio na serwerach. Każde ponowne wdrożenie wymagało okna serwisowego albo ręcznego przełączania między środowiskami w trybie blue-green — pracochłonnego i zależnego od osoby, która pamiętała wszystkie kroki.
Klaster dla klienta był naszym trzecim klastrem Kubernetes na bare metal — dwa wcześniejsze zbudowaliśmy i przetestowaliśmy u siebie. Dzięki temu produkcyjne wdrożenie w listopadzie 2023 roku powstało od razu z automatyzacją od pierwszego węzła.
Architektura
- 3 węzły serwerowe i 6 roboczych jako maszyny wirtualne na kilku serwerach fizycznych z Proxmoxem, zarządzane przez Ansible.
- Baza stanu klastra w MariaDB Galera zamiast etcd — przy topologii rozproszonej między serwerami fizycznymi zachowywała się stabilniej.
- Dwa load balancery HAProxy z Keepalived przed API klastra, ze wspólnym adresem wirtualnym.
- MetalLB do wystawiania usług, z osobną tablicą routingu.
- Storage: lokalny na dyskach SSD dla baz danych i rozproszony (Longhorn) z replikacją dla reszty.
- Automatyzacja: cert-manager dla certyfikatów, external-dns dla rekordów DNS, Rancher jako panel, Prometheus, Loki i Grafana do metryk i logów.
Na klastrze działa około 20 aplikacji i około 170 podów: usługi platformy w środowiskach test, beta, canary i produkcja, bazy danych (MySQL, PostgreSQL w trybie wysokiej dostępności, Valkey), narzędzia analityczne, system mailingowy, GitLab z runnerami CI i usługi pomocnicze.
Siedem problemów, które nas zaskoczyły
- MTU w sieci overlay. Sieć między węzłami na różnych serwerach fizycznych działa przez tunel VXLAN. Domyślne MTU powodowało gubienie dużych pakietów — objaw: połączenia, które nawiązują się, ale zawieszają przy większych odpowiedziach. Rozwiązanie: MTU 1450 i dedykowana procedura w Ansible.
- Brakujący pakiet dla storage. Nowe węzły dodane po miesiącach nie miały komponentu iSCSI wymaganego przez Longhorna. Wolumeny nie montowały się tylko na nowych węzłach. Od tej pory każdy węzeł powstaje z tej samej roli Ansible.
- Ruch zwrotny z MetalLB. Odpowiedzi z usług wystawionych przez MetalLB wracały złą trasą. Pomogły osobna tablica routingu i ustawienia ARP w jądrze.
- Niepełny łańcuch certyfikatu. Gdy cert-manager i ingress rywalizowały o ten sam certyfikat, serwowany był certyfikat bez pośredniego CA. Przeglądarki to wybaczają, klienci Javy — nie. Skutek: nowo wdrożony silnik BPM nie mógł połączyć się z API i pierwszej nocy nie uruchomił żadnego procesu. Od tego czasu sprawdzamy łańcuch certyfikatu automatycznie.
- Wymuszony SSL po aktualizacji bazy. Po aktualizacji klastra PostgreSQL operator zaczął wymuszać szyfrowane połączenia. Jedna z aplikacji nie była na to gotowa i przestała działać.
- Rozjazd manifestów. Szybkie poprawki wprowadzane bezpośrednio na klastrze sprawiły, że repozytorium przestało opisywać rzeczywistość. Dziś zmiany idą wyłącznie przez repozytorium i pipeline.
- Limity pamięci a błędy 503. Aplikacja Java zwracała sporadycznie 503 — nie z powodu błędu, tylko dławienia pamięci przez mechanizm limitów kontenera. Diagnoza wymagała zajrzenia w statystyki cgroup, nie w logi aplikacji.
Co zyskaliśmy
- Wdrożenia bez przerw. Rolling update i health-checki zamiast okien serwisowych i ręcznego przełączania blue-green.
- Pełny łańcuch CI/CD. Commit → build → obraz → wdrożenie, w każdym repozytorium.
- Cztery środowiska, w tym canary. Nową wersję usługi można wypuścić dla części ruchu i porównać z poprzednią.
- Certyfikaty i DNS bez ręcznej pracy.
- Szybkość dla nowych usług. Nowy serwis — np. silnik procesów BPM — trafił na produkcję cztery dni po pierwszym commicie, bo cała infrastruktura już czekała.
Czy warto?
Przy stałym obciążeniu i kilkunastu aplikacjach — tak, pod warunkiem że ktoś w zespole rozumie każdą warstwę: od sieci fizycznej po limity pamięci w kontenerze. Klaster na bare metal nie jest trudny w zbudowaniu. Trudny jest w diagnozie, gdy coś idzie nie tak — i za tę wiedzę płaci się doświadczeniem, nie licencją.
Powiązane teksty
2026-10-18
Kubernetes to nie tylko nowy sposób wdrażania. To zmiana nawyków operacyjnych
Przeniesienie aplikacji z serwerów do kontenerów to mniejsza część pracy. Większa to porzucenie przyzwyczajeń — monitoringu hostów, logów w /var/log, założenia, że aplikacja działa w jednym egzemplarzu, i tego, że wiadomo, na której maszynie działa.
2026-10-10
AI nie psuje kodu. W rękach architekta podnosi jego jakość
Rynkowa opinia mówi, że modele językowe zalewają repozytoria kodem gorszej jakości. Nasze doświadczenie z modernizacji dużej platformy jest odwrotne — pod jednym warunkiem.