Pod-VPN i Kubernetes kontra utgångsgateway: vem äger tunneln?
En Pod är sitt eget nätverksnamnrum, så det egentliga valet är vilket lager som äger tunneln: identitet per arbetsbelastning eller CNI-styrd utgång med en enda delad källa.
Du driftsätter en Pod som heter vpn-gateway, pekar en testklient mot dess adress och ser paketen försvinna. Inget i manifestet är fel och kubelet har inget att klaga på. Orsaken är strukturell och inte konfigurationsmässig: Kubernetes ger varje Pod sitt eget nätverksnamnrum, så ett namn, en etikett eller ett delat API-namnrum ändrar inget i vart paketen tar vägen. Att avgöra hur VPN-trafik lämnar klustret börjar därför med en fråga om ägande, inte om containeravbildningar.
Två mekanismer täcker de flesta verkliga driftsättningar, och de är inte utbytbara. Den ena placerar tunneln i arbetsbelastningens eget nätverksnamnrum. Den andra ber CNI:t att styra vald trafik genom en utsedd gateway-nod. De misslyckas olika, skalar olika och lyder under olika team, vilket är varför containerfrågan brukar skapa diskussioner som aldrig avgörs.
En Pod-gräns är ett namnrum, inte en språnghost
Ett Linux-nätverksnamnrum äger sina gränssnitt, adresser, rutter och brandväggsregler, och varje Pod får ett. Containrar i den Poden ansluter till det, och det är precis därför en hjälpcontainer kan skriva om rutter som applikationen sedan följer. En närliggande Pod har en identiskt utseende men helt separat stack. Det finns ingen delad tabell som en gateway-Pod kan ärva, och ingen implicit överlämning av trafik från ett namnrum till ett annat.
Därför fungerar gateway-Pod-mönstret bara när något uppströms faktiskt skickar paket till det: en Service, en statisk rutt på noden eller styrningspolicy i CNI:t. En adress ensam lockar ingenting.
Vad en tunnel per Pod köper, och vad den kostar
En tunnel som körs i arbetsbelastningens namnrum ger den arbetsbelastningen sin egen klientidentitet, som många fjärråtkomsttjänster kräver innan de auktoriserar eller redovisar en session. Skadans radie förblir också lokal: en trasig tunnel slår ut en Deployment i stället för den delade väg som allt använder. Hur den körs beror på implementeringen, och det är här folk gissar fel.
En uppsättning som bara behöver kärntillstånd kan avslutas i en init-container och avsluta. En användarrymdsdemon som måste leva under Podens hela livstid behöver den omstartbara init-containerformen som infördes som inbyggd sidecar i Kubernetes 1.29, och den skillnaden kommer från tunnelimplementeringen och inte från smak. Kostnaden för denna modell är duplicering: varje replik autentiserar, får sin egen tunneladress och tar en fjärrsessionsplats, så en autoskalningshändelse blir en kapacitetshändelse på andra sidan länken. Att kopiera en enda autentiseringsuppgift till alla repliker tar inte bort den kostnaden, det tar bort revisionsspåret. Behörigheter förtjänar samma granskning, för en tunnel som vill ha NET_ADMIN i sitt eget namnrum har ingen anledning att ärva hela värdens auktoritet från ett exempel med privileged: true.
När CNI:t äger utgången
Om CNI:t stöder det väljer en utgångsgateway trafik efter arbetsbelastning och målområde och skickar den sedan genom valda noder under en förutsägbar källadress. Ciliums version är den vanliga referensen, och dess dokumentation säger uttryckligen att funktionen kräver en specifik Cilium-konfiguration plus gateway-noder försedda med rätt gränssnitt och adresser. Den nämner också en inledande period efter att Poden skapats då styrningen ännu inte tillämpas, vilket är en designindata och inte en fotnot.
Läs den fördröjningen mot ditt eget löfte. Om regeln är att ingen trafik får lämna på en annan väg har en ny Pod som sänder under gapet redan brutit den, så startsekvensen behöver sitt eget svar: håll tillbaka applikationen tills policyn gäller, eller acceptera fönstret och dokumentera det.
Håll påståendet smalt. En utgångsgateway väljer och översätter en väg. Den avslutar inte en VPN, och den gör inte klustret till klient i ditt fjärrnätverk utan en stödd anslutning bakom.
| 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 |
Översättning ändrar tyst vad fjärrsidan ser
När gatewayen skriver om källan är adresserna per Pod borta, så en tillåtelselista grundad på identitet blir en lista grundad på en delad adress. Det är en byteshandel och inte en defekt: färre regler att underhålla, grövre tillskrivning när något beter sig illa.
Autentisering på applikationsnivå och förfrågningsloggning måste bära det nätverket inte längre rapporterar. Behandla gateway-kapacitet och -utbyte som delad infrastruktur, eftersom en enda nodomstart nu avbryter varje arbetsbelastning bakom den, och kontrollera returvägen tidigt: fjärränden måste veta hur den når den översatta adressen, vanligtvis via en rutt eller NAT som en människa, inte ett manifest, måste äga. Adressplanering hör också hit, för överlappande kluster- och fjärrområden bryter båda modellerna och IPv6 gör inte en motstridig plan acceptabel.
Bestäm efter ägande och testa sedan felet du lovade
Välj tunneln per Pod när fjärrtjänsten autentiserar enskilda arbetsbelastningar, när bara några få Deployment behöver länken och när ett fel ska förbli lokalt. Välj gatewayen när ett nätverksteam redan äger vägen, när många arbetsbelastningar delar en destination och när en stabil källadress är hela poängen med övningen.
Hur som helst, verifiera egenskapen du sålde och inte det stabila tillståndet. Skapa en Pod, låt den sända direkt och titta på de första sekunderna om löftet var att inget undkommer tunneln. Skala till fem repliker och räkna sessionerna som fjärränden rapporterar om löftet var identitet per arbetsbelastning. Dessa två kontroller avslöjar mekanismens gränser mycket snabbare än en granskning av manifestet, och de berättar vilket team som äger nästa incident.