Váš notebook ukazuje zelený tunel, klientský log hlásí, že trasy byly pushnuty, a jediná adresa, která odpovídá, je vlastní tunelová IP VPN serveru. Pingy za ni umírají bez ohledu na to, na co míříte, ať už je to ClusterIP, adresa jiného podu nebo veřejné jméno hostitele. Tahle kombinace je diagnostická, ne vágní: dekapsulace funguje a druhý skok ne.

Narazil jsem na to na Debian uzlu s OpenVPN image nainstalovaným přes chart a tunel byl ta snadná část. Klient dostal lease 10.8.0.x, 10.8.0.1 odpověděl a 10.96.0.10, clusterová DNS služba, vypršela. V logu serveru nevypadalo nic nezdravě, a právě proto lidé začínají přepisovat iptables pravidla, která nikdy nemuseli mít.

VPN pod je router a stojí za to to říct přímo. Zašifrované pakety přicházejí, rozbalí se ve vlastním síťovém namespace podu a pak musí odejít jiným rozhraním. Linux tento druhý krok odmítá, dokud není předávání zapnuté uvnitř právě toho namespace.

Co klient dosáhne a co ne

Adresa, která odpovídá, patří tunelovému koncovému bodu a VPN proces ji vlastní lokálně, takže se na předávání vůbec nepodílí. Všechno ostatní, včetně jiného podu, VIP služby nebo internetu, potřebuje, aby jádro přesunulo paket z tun0 na eth0. Když je tento přesun odmítnut, příznakem je stejnoměrné ticho, ne odmítnutí, protože nic negeneruje ICMP chybu zpět tunelem. Dostáváte timeouty, ne zprávy o nedostupnosti, a to je stopa, že nikdo vůbec neroutuje.

Dvě minuty klasifikace zúží vrstvu. Pokud DNS jména selhávají, zatímco surové pingy na IP služby procházejí, problém je v DNS instalatérství, ne v předávání. Pokud každý cíl za adresou peeru vyprší, včetně holé IP, začněte u namespace.

Přečtěte nastavení uvnitř namespace

Každý pod dostane vlastní síťový namespace a net.ipv4.ip_forward je sysctl pro každý namespace. Změna na uzlu vám o kontejneru neřekne nic a je to spolehlivý způsob, jak strávit odpoledne na špatném stroji.

kubectl exec -it deploy/openvpn -- sysctl net.ipv4.ip_forward
# net.ipv4.ip_forward = 0

Nula diagnózu potvrzuje. Hodnota se také nedědí z runtime konfigurace uzlu: začíná na výchozí hodnotě image při každém vytvoření kontejneru. Oprava provedená ručně pomocí kubectl exec ... sysctl -w proto zmizí při dalším restartu a vrátí se jako závada, která vypadá občasně.

Zapnout to tak, aby si to manifest udržel

Trvanlivou možností je init kontejner, který běží ve stejném pod sandboxu a zapíše hodnotu před startem VPN kontejneru. Kontejnery v podu sdílejí síťový namespace, takže se nastavení přenese do hlavního kontejneru.

initContainers:
- name: enable-forwarding
  image: busybox:1.36
  command: ["sysctl", "-w", "net.ipv4.ip_forward=1"]
  securityContext:
    privileged: true

Právě privileged: true je řádek, proti kterému recenzenti protestují, a mají pravdu. Zápis sysctl potřebuje buď privilegium, nebo úzce vymezenou schopnost, a cluster s restriktivním Pod Security Standard může privilegovaný init kontejner rovnou odmítnout. Pokud admission pod odmítne, dozvíte se to při vytváření, což je alespoň poctivé a snadno čitelné.

Čistší alternativou je seznam securityContext.sysctls na úrovni podu, který umožňuje kubeletu aplikovat namespaced sysctls bez udělení privilegia kterémukoli kontejneru. Pokrývá jen jména na allowlistu clusteru. Zda je net.ipv4.ip_forward na tomto seznamu, závisí na konfiguraci kubeletu, a pod, který žádá sysctl mimo něj, je odmítnut při admission nebo uvízne v CreateContainerConfigError, zatímco se sandbox opakuje. Zkontrolujte allowlist, než budete předpokládat, že pole je rozbité.

Než oba přístupy začnete stavět ručně, podívejte se, zda chart už přepínač neexponuje, často jako něco jako ipForwardInitContainer: true. Použití hodnoty z chartu udrží váš override soubor malý a přežije další upgrade, což ručně záplatované úpravy Deploymentu nedělají.

Druhá polovina: zpáteční cesta a politika

Zapnuté předávání je nutné, ne dostačující. Pokud klienti používají privátní pool, pro který clusterová síť nemá trasu, odpovědi si nenajdou cestu zpět do tunelu a pod musí ten provoz maskovat směrem ke svému cíli.

Politika sedí navrch. Objekty NetworkPolicy a pravidla cloudového firewallu se vyhodnocují proti zdrojové adrese, kterou paket nese po překladu, takže pravidlo napsané pro klientský pool může tiše přestat odpovídat, jakmile je maskování zapnuté.

Když klienti potřebují dosáhnout jen služeb uvnitř clusteru, ukončení VPN na VIP služby je menší návrh než routování do sítě podů. Také drží klientský pool úplně mimo routovací tabulku CNI.

Izolace selhávajícího skoku od klienta

Pracujte směrem ven a zastavte se u prvního tichého kroku. Začněte u VPN peeru, pak zkuste adresu nějakého podu, pak VIP služby a teprve potom veřejný cíl. Každý úspěch posune hranici o jeden skok a každé selhání pojmenuje vrstvu, kterou stojí za to prozkoumat. Po každém rollout se přihlaste a přečtěte sysctl znovu, protože nahrazený pod začíná na výchozí hodnotě image a oprava, která nikdy nebyla v manifestu, je už pryč.

Dokumentace Kubernetes o používání sysctls v clusteru uvádí, která jména lze nastavit přes bezpečnostní kontext podu, a je to první místo, kam se podívat, když admission změnu odmítne.

Související články