VPN per Pod w Kubernetes a brama wyjściowa: do kogo należy tunel?
Pod to własna przestrzeń nazw sieci, więc prawdziwym wyborem jest to, która warstwa posiada tunel: tożsamość dla każdego obciążenia czy wyjście sterowane przez CNI z jednym wspólnym źródłem.
Wdrażasz Pod o nazwie vpn-gateway, kierujesz klienta testowego na jego adres i widzisz, jak pakiety znikają. W manifeście nie ma nic złego, a kubelet nie ma zastrzeżeń. Przyczyna jest strukturalna, a nie konfiguracyjna: Kubernetes daje każdemu Podowi własną przestrzeń nazw sieci, więc nazwa, etykieta czy wspólna przestrzeń nazw API nic nie zmieniają w tym, dokąd trafiają pakiety. Dlatego decyzja o tym, jak ruch VPN opuszcza klaster, zaczyna się od pytania o własność, a nie o obrazy kontenerów.
Dwa mechanizmy pokrywają większość rzeczywistych wdrożeń i nie są wymienne. Jeden umieszcza tunel we własnej przestrzeni nazw sieci obciążenia. Drugi prosi CNI o skierowanie wybranego ruchu przez wskazany węzeł bramy. Zawodzą inaczej, skalują się inaczej i podlegają różnym zespołom, dlatego pytanie o kontenery zwykle rodzi spory, które nigdy się nie kończą.
Granica Podu to przestrzeń nazw, nie host skoku
Przestrzeń nazw sieci Linuksa posiada swoje interfejsy, adresy, trasy i reguły zapory, a każdy Pod dostaje jedną. Kontenery w tym Podzie do niej dołączają i właśnie dlatego kontener pomocniczy może przepisać trasy, których potem przestrzega aplikacja. Sąsiedni Pod ma identycznie wyglądający, ale całkowicie osobny stos. Nie ma wspólnej tabeli, którą mógłby odziedziczyć Pod bramy, ani niejawnego przekazania ruchu z jednej przestrzeni nazw do drugiej.
Dlatego wzorzec Podu bramy działa tylko wtedy, gdy coś powyżej naprawdę wysyła do niego pakiety: Service, trasa statyczna w węźle albo polityka kierowania w CNI. Sam adres niczego nie przyciąga.
Co daje tunel na Pod i ile kosztuje
Tunel działający w przestrzeni nazw obciążenia daje temu obciążeniu własną tożsamość klienta, której wiele usług dostępu zdalnego wymaga, zanim autoryzują lub rozliczą sesję. Promień rażenia też pozostaje lokalny: zepsuty tunel wyłącza jeden Deployment zamiast wspólnej ścieżki używanej przez wszystko. Sposób działania zależy od implementacji i właśnie tutaj ludzie mylą się.
Konfiguracja, która potrzebuje tylko stanu jądra, może zakończyć się w kontenerze init i wyjść. Demon przestrzeni użytkownika, który musi żyć przez cały czas życia Podu, wymaga restartowalnej formy kontenera init wprowadzonej jako natywny sidecar w Kubernetes 1.29, a ta różnica wynika z implementacji tunelu, nie z gustu. Kosztem tego modelu jest duplikacja: każda replika uwierzytelnia się, otrzymuje własny adres tunelu i zajmuje miejsce sesji zdalnej, więc zdarzenie autoskalowania staje się zdarzeniem pojemności po drugiej stronie łącza. Kopiowanie jednego poświadczenia do wszystkich replik nie usuwa tego kosztu, usuwa ślad audytowy. Uprawnienia zasługują na tę samą kontrolę, bo tunel, który chce NET_ADMIN we własnej przestrzeni nazw, nie ma powodu dziedziczyć władzy nad całym hostem z przykładu z privileged: true.
Kiedy CNI posiada wyjście
Jeśli CNI to obsługuje, brama wyjściowa wybiera ruch według obciążenia i zakresu docelowego, a następnie wysyła go przez wybrane węzły pod jednym przewidywalnym adresem źródłowym. Wersja Cilium jest zwykłym odniesieniem, a jej dokumentacja jasno mówi, że funkcja wymaga konkretnej konfiguracji Cilium oraz węzłów bramy wyposażonych w właściwe interfejsy i adresy. Wspomina też początkowy okres po utworzeniu Podu, gdy kierowanie nie jest jeszcze egzekwowane, co jest daną projektową, a nie przypisem.
Przeczytaj to opóźnienie wobec własnej obietnicy. Jeśli regułą jest, że żaden ruch nie może wyjść inną drogą, nowy Pod, który nadaje w tej luce, już ją złamał, więc sekwencja startowa potrzebuje własnej odpowiedzi: wstrzymać aplikację, aż polityka zacznie obowiązywać, albo zaakceptować okno i je udokumentować.
Trzymaj twierdzenie wąsko. Brama wyjściowa wybiera i tłumaczy ścieżkę. Nie kończy VPN i nie czyni klastra klientem twojej sieci zdalnej bez obsługiwanego połączenia za nią.
| Question | Per-Pod tunnel | CNI egress gateway |
|---|---|---|
| Who holds the client identity | Each workload | The gateway, shared |
| What scaling changes | Enrollment and sessions per replica | Throughput and capacity per node |
| What the remote side sees | Distinct addresses | One translated source |
| Failure scope | One Deployment | Every workload behind the gateway |
Tłumaczenie po cichu zmienia to, co widzi strona zdalna
Gdy brama przepisze źródło, adresy poszczególnych Podów znikają, więc lista dozwolonych oparta na tożsamości staje się listą opartą na jednym współdzielonym adresie. To wymiana, a nie defekt: mniej reguł do utrzymania, grubsze przypisanie, gdy coś zachowuje się źle.
Uwierzytelnianie na poziomie aplikacji i logowanie żądań muszą nieść to, czego sieć już nie raportuje. Traktuj pojemność i wymianę bramy jako wspólną infrastrukturę, bo restart jednego węzła przerywa teraz każde obciążenie za nim, i sprawdź wcześnie drogę powrotną: strona zdalna musi wiedzieć, jak dotrzeć do przetłumaczonego adresu, zwykle przez trasę lub NAT, którym musi zarządzać człowiek, a nie manifest. Planowanie adresów też tu należy, bo nakładające się zakresy klastra i sieci zdalnej psują oba modele, a przyjęcie IPv6 nie usprawiedliwia sprzecznego planu.
Zdecyduj według własności, a potem przetestuj obiecaną awarię
Wybierz tunel na Pod, gdy usługa zdalna uwierzytelnia pojedyncze obciążenia, gdy tylko kilka Deploymentów potrzebuje łącza i gdy awaria ma pozostać lokalna. Wybierz bramę, gdy zespół sieciowy już posiada ścieżkę, gdy wiele obciążeń dzieli jeden cel i gdy stabilny adres źródłowy jest całym sensem ćwiczenia.
Tak czy inaczej, zweryfikuj sprzedaną właściwość, a nie stan ustalony. Utwórz Pod, pozwól mu natychmiast nadawać i obserwuj pierwsze sekundy, jeśli obietnicą było, że nic nie ucieka z tunelu. Skaluj do pięciu replik i policz sesje, które zgłasza strona zdalna, jeśli obietnicą była tożsamość na obciążenie. Te dwie kontrole ujawniają granice mechanizmu znacznie szybciej niż przegląd manifestu i mówią, do którego zespołu należy następny incydent.