Soukromé API se otevře ve vašem desktopovém prohlížeči a v development kontejneru selže. To není rozpor a málokdy je příčinou samotná VPN. Požadavek z prohlížeče a selhávající požadavek vytvořily různé procesy, s různými resolvery, proxy a trasami, a často z úplně odlišných síťových jmenných prostorů. „Na svém notebooku“ může znamenat hostitele Windows, distribuci WSL, virtuální stroj Docker Desktop a kontejner uvnitř tohoto VM – čtyři kontexty, z nichž každý může na stejné jméno hostitele odpovědět jinak. Zjistěte, který z nich selhávající proces používá, než se dotknete jediného nastavení.

Najděte proces dřív, než změníte nastavení

Začněte kontejnerovým enginem, ne VPN klientem. Zeptejte se, s jakým kontextem mluví příkazová řádka a na kterém operačním systému tento engine běží, protože Linux kontejner spravovaný desktopovým VM jde jinou cestou než ten spravovaný lokálním démonem:

docker context ls
docker info --format '{{.OperatingSystem}} / {{.Name}}'
docker run --rm alpine ip route

Ve Windows wsl -l -v řekne, zda distribuce běží pod WSL 2, což ji staví za vlastní virtuální switch. Tento detail rozhoduje, zda kontejner sdílí hostitelovu směrovací tabulku, nebo sedí za NAT, který potřebuje přesměrovaný port nebo jméno hostitele, aby se k hostiteli dostal.

Držte jeden požadavek konstantní a porovnávejte

Vyberte jeden neškodný koncový bod na soukromém hostiteli a používejte ho pro každé srovnání: z prohlížeče, z terminálu hostitele, z distribuce WSL a zevnitř kontejneru. U každého pokusu zaznamenejte čtyři věci: přeloženou adresu, zda byla použita proxy, třídu selhání a uplynulý čas. Překlad jména, navázání spojení, validace TLS a HTTP stav jsou čtyři různé problémy a jejich slití do „nefunguje to“ promrhá celé dopoledne.

Srovnání spusťte uvnitř selhávajícího kontejneru, s timeoutem, aby tichý firewall nedržel terminál minuty. Nový kontejner reprodukuje síťový kontext enginu, ale ne jmenný prostor aplikačního kontejneru, jeho proxy proměnné ani resolver, takže docker exec do skutečného kontejneru je autoritativní test a sidecar je jen způsob, jak izolovat, zda je rozdíl v enginu, nebo v kontejneru:

docker exec -it app /bin/sh -c "getent hosts api.internal; curl -v --max-time 8 https://api.internal/ 2>&1 | tail -20"
docker run --rm --network container:app curlimages/curl:latest -sv --max-time 8 https://api.internal/ 2>&1 | tail -20

Základní image alpine nese busybox a žádný curl, a to je přesně ten druh detailu, který zkopírovaný diagnostický blok shodí: vyberte image s klientem, nebo ho přidejte v témže běhu. Srovnání s nesouvisejícími veřejnými weby nic neizoluje. Pokud https://example.com funguje z kontejneru, zjistili jste, že kontejner má přístup k internetu, a nic o tom, zda se tunelem dostane na soukromou adresu. Stejně tak otevření nového terminálu dokazuje jen to, že nový terminál funguje, ne že sdílí runtime s aplikací, která selhala.

Docker Desktop může s VPN fungovat

Vlastní dokumentace Dockeru o VPN a konektivitě k hostiteli to popisuje jako podporované nastavení a upřímné shrnutí je, že to funguje, místo aby to bylo automaticky rozbité. Nepředpokládejte, že desktopový VM obchází tunel hostitele už z principu; v mnoha nastaveních provoz správně sleduje tunel hostitele, a právě proto folklór „Docker ignoruje VPN“ produkuje sebevědomé a špatné rady.

Co stále záleží, je použitý backend, politika rozděleného tunelu klienta a konfigurace resolveru, kterou VM dostal. VPN klient, který instaluje trasy, ale ne DNS, nebo protlačí DNS server, na který se VM nedostane, vytváří selhání překladu jména uvnitř kontejneru, zatímco hostitel funguje, protože má navíc resolver nebo kešovanou odpověď. To je problém resolveru v kostýmu kontejneru. Přežije každé opětovné připojení VPN, které zkusíte, protože tunel už veze provoz, o který jste ho požádali.

Překryvy adres a MTU jsou různé poruchy

Dvě poruchy si zaslouží vlastní diagnostiku, protože se často pletou s přístupovou politikou. První je překryv adres: pokud VPN protlačí rozsah, který koliduje s výchozí podsítí bridge kontejnerové sítě, trasa kontejneru pro tento rozsah ukazuje na lokální bridge a nikdy se nedostane do tunelu. Prohlédněte skutečné podsítě, místo abyste hádali:

docker network inspect bridge --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}'
ip route get 10.20.30.40

Druhá je problém MTU. Pokud se spojení naváže a TLS dokončí, ale větší odpovědi se zaseknou, máte problém velikosti paketu, ne autorizace, a výměna DNS záznamů to nikdy nespraví. Otestujte malý požadavek a velký, než cokoli změníte, a zaznamenejte oba výsledky.

Řešením překryvu je jiná kontejnerová podsíť nebo omezená trasa, kterou vybere ten, kdo vlastní plán adres. Řešením zaseknutí MTU je sevření nebo snížení MTU tunelu či rozhraní na hodnotu, která cestu přežije, aplikované na vrstvě, kterou ovládáte.

Konfigurace proxy je pro proces, ne pro stroj

Uvnitř kontejneru localhost pojmenovává vlastní síťový kontext tohoto kontejneru, takže proxy běžící na hostiteli tam pod tímto jménem dostupná není. Docker Desktop poskytuje host.docker.internal pro přístup k hostiteli a v Linuxu ho přidáte výslovně pomocí --add-host=host.docker.internal:host-gateway. V obou případech vám to jméno dává trasu k hostiteli; nezakládá proxy službu ani vás neopravňuje ji používat.

Použijte proxy adresu a port, které jsou určené pro skutečné prostředí, a zkontrolujte, kdo je čte. Proměnné exportované v interaktivním shellu automaticky nenastaví každé rozšíření editoru, jazykový server, nástroj pro build a background daemon. Důležitý je proces, který selhávající požadavek vytvořil, takže prohlédněte jeho prostředí, ne prostředí svého terminálu.

Nakonec ať se oprava vysvětlí sama. Užitečné řešení pojmenuje hranici, která byla špatně, nastavení, které ji změnilo, a množinu procesů, na které teď působí. Restartování VPN, editoru a enginu v tomto pořadí může změnit symptom, ale nezanechá nic, co by další člověk mohl použít.

Související články