Il Dev Container non raggiunge un host solo-VPN: dove guardare
Browser e container hanno contesti diversi di resolver, proxy e rotte. Scoprite quale usa il processo che fallisce prima di cambiare qualsiasi impostazione VPN.
L'API privata si apre nel browser del desktop e fallisce nel container di sviluppo. Non è una contraddizione, ed è raramente la VPN stessa. La richiesta del browser e la richiesta che fallisce sono state fatte da processi diversi, con resolver, proxy e rotte differenti, e spesso da spazi dei nomi di rete del tutto diversi. «Sul mio portatile» può significare l'host Windows, una distribuzione WSL, la macchina virtuale di Docker Desktop e un container dentro quella VM: quattro contesti che possono rispondere in modo diverso allo stesso nome host. Scoprite quale usa il processo che fallisce prima di toccare una sola impostazione.
Individuate il processo prima di cambiare un'impostazione
Iniziate dal motore dei container, non dal client VPN. Chiedete a quale contesto parla la riga di comando e su quale sistema operativo gira quel motore, perché un container Linux gestito da una VM desktop segue un percorso diverso da quello gestito da un demone locale:
docker context ls
docker info --format '{{.OperatingSystem}} / {{.Name}}'
docker run --rm alpine ip route
Su Windows, wsl -l -v vi dice se la distribuzione gira sotto WSL 2, il che la colloca dietro il proprio commutatore virtuale. Questo dettaglio decide se il container condivide la tabella di routing dell'host o sta dietro un NAT che richiede una porta inoltrata o un nome host per raggiungere l'host.
Tenete costante una richiesta e confrontate
Scegliete un endpoint innocuo sull'host privato e usatelo per ogni confronto: dal browser, da un terminale dell'host, dalla distribuzione WSL e dall'interno del container. Annotate quattro cose per ogni tentativo: l'indirizzo risolto, se è stato usato un proxy, la classe di errore e il tempo trascorso. Risoluzione del nome, instaurazione della connessione, validazione TLS e uno stato HTTP sono quattro problemi diversi, e mescolarli in «non funziona» spreca una mattinata.
Eseguite il confronto dentro il container che fallisce, con un timeout così un firewall silenzioso non blocca il terminale per minuti. Un container nuovo riproduce il contesto di rete del motore, ma non lo spazio dei nomi, le variabili proxy o il resolver del container dell'applicazione, quindi docker exec nel container reale è il test autorevole, e un container affiancato è solo un modo per isolare se la differenza è nel motore o nel container:
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
L'immagine base alpine contiene busybox e non curl, ed è esattamente il tipo di dettaglio che fa fallire un blocco diagnostico copiato: scegliete un'immagine con il client, oppure aggiungetelo nella stessa esecuzione. Un confronto con siti pubblici non correlati non isola nulla. Se https://example.com funziona dal container, avete imparato che il container ha accesso a Internet e nulla sul fatto che raggiunga un indirizzo privato attraverso il tunnel. Allo stesso modo, aprire un nuovo terminale dimostra solo che il nuovo terminale funziona, non che condivide un runtime con l'applicazione che ha fallito.
Docker Desktop può funzionare con una VPN
La documentazione di Docker su VPN e connettività all'host lo descrive come una configurazione supportata, e il riassunto onesto è che funziona invece di essere rotto per impostazione predefinita. Non date per scontato che la VM desktop aggiri il tunnel dell'host per progetto; in molte configurazioni il traffico segue correttamente il tunnel dell'host, ed è per questo che la leggenda «Docker ignora la VPN» produce consigli sicuri e sbagliati.
Ciò che conta ancora è il backend in uso, la politica di split tunnel del client e la configurazione del resolver che la VM ha ricevuto. Un client VPN che installa rotte ma non DNS, o che spinge un server DNS che la VM non riesce a raggiungere, produce un errore di risoluzione del nome dentro il container mentre l'host funziona perché ha un resolver aggiuntivo o una risposta in cache. È un problema di resolver travestito da container. Sopravvive a ogni riconnessione VPN che provate, perché il tunnel sta già trasportando il traffico che gli avete chiesto.
Le sovrapposizioni di indirizzi e l'MTU sono guasti diversi
Due guasti meritano una diagnosi propria perché vengono spesso scambiati per politica di accesso. Il primo è una sovrapposizione di indirizzi: se la VPN spinge un intervallo che collide con la sottorete del bridge predefinito di una rete di container, la rotta del container per quell'intervallo punta al bridge locale e non raggiunge mai il tunnel. Ispezionate le sottoreti reali invece di indovinare:
docker network inspect bridge --format '{{range .IPAM.Config}}{{.Subnet}}{{end}}'
ip route get 10.20.30.40
Il secondo è un problema di MTU. Se la connessione si stabilisce e TLS si completa ma le risposte più grandi si bloccano, avete un problema di dimensione dei pacchetti, non di autorizzazione, e sostituire record DNS non lo risolverà mai. Provate con una richiesta piccola e una grande prima di cambiare qualcosa, e annotate entrambi gli esiti.
La soluzione per una sovrapposizione è una sottorete di container diversa o una rotta limitata, scelta da chi possiede il piano degli indirizzi. La soluzione per un blocco MTU è fissare o ridurre l'MTU del tunnel o dell'interfaccia a un valore che sopravvive al percorso, applicato al livello che controllate.
La configurazione del proxy è per processo, non per macchina
Dentro un container, localhost indica il contesto di rete del container stesso, quindi un proxy in esecuzione sull'host non è raggiungibile lì con quel nome. Docker Desktop fornisce host.docker.internal per l'accesso all'host, e su Linux lo aggiungete esplicitamente con --add-host=host.docker.internal:host-gateway. In ogni caso, quel nome vi dà una rotta verso l'host; non crea un servizio proxy né vi autorizza a usarne uno.
Usate l'indirizzo e la porta del proxy forniti per l'ambiente reale, e controllate chi li legge. Le variabili esportate in una shell interattiva non configurano automaticamente ogni estensione dell'editor, language server, strumento di build e demone in background. Quello che conta è il processo che ha fatto la richiesta fallita, quindi ispezionate il suo ambiente e non quello del vostro terminale.
Infine, fate in modo che la correzione si spieghi da sola. Una soluzione utile nomina il confine che era sbagliato, l'impostazione che l'ha cambiato e l'insieme di processi che ora ne è influenzato. Riavviare la VPN, l'editor e il motore in sequenza può cambiare il sintomo, ma non lascia nulla che la persona successiva possa usare.