Det privata API:et öppnas i din skrivbordswebbläsare och misslyckas i utvecklingscontainern. Det är ingen motsägelse, och det är sällan VPN:et självt. Webbläsarens begäran och den misslyckade begäran gjordes av olika processer, med olika resolvers, proxyservrar och rutter, och ofta från helt olika nätverksnamnrymder. Uttrycket "på min laptop" kan betyda Windows-värden, en WSL-distribution, Docker Desktops virtuella maskin och en container inuti den virtuella maskinen, fyra kontexter som var och en kan svara olika på samma värdnamn. Ta reda på vilken den misslyckade processen använder innan du rör en enda inställning.

Lokalisera processen innan du ändrar en inställning

Börja med containermotorn i stället för VPN-klienten. Fråga vilken kontext kommandoraden talar med, och vilket operativsystem den motorn kör på, eftersom en Linux-container som hanteras av en virtuell skrivbordsmaskin är en annan väg än en som hanteras av en lokal daemon:

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

På Windows berättar wsl -l -v om distributionen körs under WSL 2, vilket placerar den bakom sin egen virtuella switch. Den detaljen avgör om containern delar värdens routingtabell eller sitter bakom en NAT som behöver en vidarebefordrad port eller ett värdnamn för att nå värden.

Håll en begäran konstant och jämför

Välj en ofarlig slutpunkt på den privata värden och använd den för varje jämförelse, från webbläsaren, från en värdterminal, från WSL-distributionen och inifrån containern. Anteckna fyra saker för varje försök: den uppslagna adressen, om en proxy användes, felklassen och den förflutna tiden. Namnuppslagning, anslutningsuppbyggnad, TLS-validering och en HTTP-status är fyra olika problem, och att blanda dem till "det fungerar inte" slösar bort en förmiddag.

Kör jämförelsen inuti den container som misslyckas, med en tidsgräns så att en tyst brandvägg inte håller terminalen i minuter. En ny container återskapar motorns nätverkskontext men inte applikationscontainerns namnrymd, proxyvariabler eller resolver, så docker exec in i den riktiga är det avgörande testet och en sidovagn är bara ett sätt att isolera om skillnaden är motorn eller containern:

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

Alpine-basavbildningen innehåller busybox och ingen curl, vilket är precis den sortens detalj som får ett kopierat diagnostikblock att misslyckas: välj en avbildning med klienten, eller lägg till den inom samma körning. En jämförelse mot orelaterade publika webbplatser isolerar ingenting. Om https://example.com fungerar från containern har du lärt dig att containern har internetåtkomst och ingenting om huruvida den kan nå en privat adress genom tunneln. På samma sätt bevisar ett nytt terminalfönster bara att det nya terminalfönstret fungerar, inte att det delar en körtid med applikationen som misslyckades.

Docker Desktop kan fungera med ett VPN

Docker:s egen dokumentation om VPN och värdanslutning beskriver detta som en uppsättning som stöds, och den ärliga sammanfattningen är att det fungerar i stället för att vara automatiskt trasigt. Anta inte att den virtuella skrivbordsmaskinen kringgår värdens tunnel som en designfråga; i många uppsättningar följer trafiken värdens tunnel korrekt, vilket är varför folktron "Docker ignorerar VPN:et" ger självsäkra och felaktiga råd.

Det som fortfarande spelar roll är backend:en som används, klientens policy för delad tunnel och den resolverkonfiguration som den virtuella maskinen fick. En VPN-klient som installerar rutter men inte DNS, eller som skickar en DNS-server som den virtuella maskinen inte kan nå, ger ett namnuppslagningsfel inuti containern medan värden fungerar eftersom värden har en extra resolver eller ett cachat svar. Det är ett resolverproblem i containerkostym. Det överlever varje VPN-återanslutning du försöker, eftersom tunneln redan bär den trafik du bad den bära.

Adressöverlapp och MTU är olika fel

Två fel förtjänar sin egen diagnos eftersom de ofta förväxlas med åtkomstpolicy. Det första är ett adressöverlapp: om VPN:et skickar ett intervall som kolliderar med ett containernätverks standardbryggas subnät pekar containerns rutt för det intervallet på den lokala bryggan och når aldrig tunneln. Inspektera de faktiska subnäten i stället för att gissa:

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

Det andra är ett MTU-problem. Om anslutningen upprättas och TLS slutförs men större svar stannar upp har du ett paketstorleksproblem, inte ett auktoriseringsproblem, och att byta DNS-poster kommer aldrig att åtgärda det. Testa med en liten begäran och en stor innan du ändrar något, och anteckna båda resultaten.

Åtgärden för ett överlapp är ett annat containersubnät eller en avgränsad rutt, vald av den som äger adressplanen. Åtgärden för en MTU-stopp är att begränsa eller minska tunnelns eller gränssnittets MTU till ett värde som överlever vägen, tillämpat i det lager du kontrollerar.

Proxykonfiguration är per process, inte per maskin

Inuti en container namnger localhost containerns egen nätverkskontext, så en proxy som körs på värden går inte att nå där under det namnet. Docker Desktop tillhandahåller host.docker.internal för värdåtkomst, och på Linux lägger du till det explicit med --add-host=host.docker.internal:host-gateway. Hur som helst ger det namnet en rutt till värden; det skapar inte en proxytjänst och ger dig inte behörighet att använda en.

Använd proxyadressen och porten som tillhandahålls för den faktiska miljön, och kontrollera vem som läser den. Variabler som exporteras i ett interaktivt skal konfigurerar inte automatiskt varje redigeringstillägg, språkserver, byggverktyg och bakgrundsdaemon. Den som spelar roll är processen som gjorde den misslyckade begäran, så inspektera dess miljö i stället för terminalens.

Till sist, låt åtgärden förklara sig själv. En användbar lösning namnger den gräns som var fel, inställningen som ändrade den och den uppsättning processer den nu påverkar. Att starta om VPN:et, redigeraren och motorn i tur och ordning kan ändra symtomet, men det lämnar ingenting efter sig som nästa person kan använda.

Relaterade artiklar