Die private API öffnet sich in Ihrem Desktop-Browser und scheitert im Entwicklungscontainer. Das ist kein Widerspruch, und selten ist die VPN selbst die Ursache. Die Browser-Anfrage und die fehlschlagende Anfrage stammen von verschiedenen Prozessen, mit unterschiedlichen Resolvern, Proxys und Routen, und oft aus völlig verschiedenen Netzwerk-Namespaces. „Auf meinem Laptop“ kann den Windows-Host, eine WSL-Distribution, die Docker-Desktop-VM und einen Container innerhalb dieser VM bedeuten – vier Kontexte, die dieselbe Hostadresse jeweils anders beantworten können. Finden Sie heraus, welchen der fehlschlagende Prozess verwendet, bevor Sie eine einzige Einstellung anfassen.

Den Prozess finden, bevor Sie eine Einstellung ändern

Beginnen Sie mit der Container-Engine statt mit dem VPN-Client. Fragen Sie, mit welchem Kontext die Kommandozeile spricht und auf welchem Betriebssystem diese Engine läuft, denn ein Linux-Container, der von einer Desktop-VM verwaltet wird, nimmt einen anderen Weg als einer, den ein lokaler Daemon verwaltet:

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

Unter Windows sagt Ihnen wsl -l -v, ob die Distribution unter WSL 2 läuft, was sie hinter einen eigenen virtuellen Switch stellt. Dieses Detail entscheidet, ob der Container die Routing-Tabelle des Hosts teilt oder hinter einem NAT sitzt, das einen weitergeleiteten Port oder einen Hostnamen braucht, um den Host zu erreichen.

Eine Anfrage konstant halten und vergleichen

Wählen Sie einen harmlosen Endpunkt auf dem privaten Host und nutzen Sie ihn für jeden Vergleich: aus dem Browser, aus einem Host-Terminal, aus der WSL-Distribution und aus dem Container heraus. Notieren Sie vier Dinge pro Versuch: die aufgelöste Adresse, ob ein Proxy verwendet wurde, die Fehlerklasse und die verstrichene Zeit. Namensauflösung, Verbindungsaufbau, TLS-Validierung und ein HTTP-Status sind vier verschiedene Probleme, und sie zu „es funktioniert nicht“ zu vermischen kostet einen Vormittag.

Führen Sie den Vergleich im fehlschlagenden Container aus, mit einem Timeout, damit eine stille Firewall das Terminal nicht minutenlang blockiert. Ein frischer Container reproduziert den Netzwerkkontext der Engine, aber nicht den Namespace, die Proxy-Variablen oder den Resolver des Anwendungscontainers, deshalb ist docker exec in den echten Container der maßgebliche Test, und ein Sidecar ist nur ein Weg, um zu isolieren, ob der Unterschied in der Engine oder im Container liegt:

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

Das alpine-Basisimage bringt busybox und kein curl mit, und genau solche Details lassen einen kopierten Diagnoseblock scheitern: Wählen Sie ein Image mit dem Client oder fügen Sie ihn im selben Lauf hinzu. Ein Vergleich mit unverwandten öffentlichen Seiten isoliert nichts. Wenn https://example.com aus dem Container funktioniert, haben Sie gelernt, dass der Container Internetzugang hat, und nichts darüber, ob er eine private Adresse durch den Tunnel erreicht. Ebenso beweist ein neues Terminal nur, dass das neue Terminal funktioniert, nicht dass es eine Laufzeitumgebung mit der fehlgeschlagenen Anwendung teilt.

Docker Desktop kann mit einer VPN funktionieren

Dockers eigene Dokumentation zu VPN und Host-Konnektivität beschreibt dies als unterstützte Einrichtung, und die ehrliche Zusammenfassung ist, dass es funktioniert, statt automatisch kaputt zu sein. Nehmen Sie nicht an, dass die Desktop-VM den Host-Tunnel konstruktionsbedingt umgeht; in vielen Setups folgt der Verkehr korrekt dem Host-Tunnel, und deshalb erzeugt das Märchen „Docker ignoriert die VPN“ selbstsichere und falsche Ratschläge.

Was weiterhin zählt, ist das verwendete Backend, die Split-Tunnel-Richtlinie des Clients und die Resolver-Konfiguration, die die VM erhalten hat. Ein VPN-Client, der Routen aber kein DNS installiert, oder der einen DNS-Server pusht, den die VM nicht erreicht, erzeugt einen Namensauflösungsfehler im Container, während der Host funktioniert, weil er einen zusätzlichen Resolver oder eine gecachte Antwort hat. Das ist ein Resolver-Problem im Container-Kostüm. Es übersteht jede VPN-Wiederverbindung, die Sie versuchen, weil der Tunnel bereits den Verkehr trägt, den Sie ihm aufgetragen haben.

Adressüberschneidungen und MTU sind verschiedene Fehler

Zwei Fehler verdienen eine eigene Diagnose, weil sie häufig mit Zugriffsrichtlinien verwechselt werden. Der erste ist eine Adressüberschneidung: Wenn die VPN einen Bereich pusht, der mit dem Standard-Bridge-Subnetz eines Container-Netzwerks kollidiert, zeigt die Route des Containers für diesen Bereich auf die lokale Bridge und erreicht den Tunnel nie. Untersuchen Sie die tatsächlichen Subnetze, statt zu raten:

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

Der zweite ist ein MTU-Problem. Wenn die Verbindung zustande kommt und TLS abgeschlossen wird, aber größere Antworten hängen bleiben, haben Sie ein Paketgrößenproblem, kein Autorisierungsproblem, und das Ersetzen von DNS-Einträgen wird es nie beheben. Testen Sie mit einer kleinen und einer großen Anfrage, bevor Sie etwas ändern, und notieren Sie beide Ergebnisse.

Die Lösung für eine Überschneidung ist ein anderes Container-Subnetz oder eine begrenzte Route, gewählt von dem, der den Adressplan besitzt. Die Lösung für einen MTU-Stillstand ist das Begrenzen oder Verringern der Tunnel- oder Interface-MTU auf einen Wert, der den Pfad übersteht, angewendet auf der Schicht, die Sie kontrollieren.

Proxy-Konfiguration gilt pro Prozess, nicht pro Maschine

Innerhalb eines Containers benennt localhost den eigenen Netzwerkkontext dieses Containers, also ist ein auf dem Host laufender Proxy dort unter diesem Namen nicht erreichbar. Docker Desktop stellt host.docker.internal für den Host-Zugriff bereit, und unter Linux fügen Sie ihn ausdrücklich mit --add-host=host.docker.internal:host-gateway hinzu. So oder so gibt Ihnen dieser Name eine Route zum Host; er erstellt keinen Proxy-Dienst und berechtigt Sie nicht, einen zu verwenden.

Verwenden Sie die Proxy-Adresse und den Port, die für die tatsächliche Umgebung bereitgestellt werden, und prüfen Sie, wer sie liest. Variablen, die in einer interaktiven Shell exportiert werden, konfigurieren nicht automatisch jede Editor-Erweiterung, jeden Language-Server, jedes Build-Tool und jeden Hintergrund-Daemon. Entscheidend ist der Prozess, der die fehlschlagende Anfrage gestellt hat, also untersuchen Sie dessen Umgebung und nicht die Ihres Terminals.

Lassen Sie schließlich die Korrektur sich selbst erklären. Eine nützliche Lösung benennt die Grenze, die falsch war, die Einstellung, die sie geändert hat, und die Menge der Prozesse, die sie jetzt betrifft. Ein Neustart von VPN, Editor und Engine nacheinander kann das Symptom ändern, lässt aber nichts zurück, das die nächste Person nutzen kann.

Ähnliche Artikel