Come connettersi a un container Docker dall'esterno dell'host (stessa rete) [Windows]


89

Ho creato il mio primo contenitore Docker, esegue un server utilizzando Go ma non riesco ad accedervi dall'esterno del computer host. Ho appena iniziato con docker quindi sono un po 'perso qui.

Quindi ho un codice Go molto semplice che avvia un server, ho costruito l'immagine docker che installa Go e costruisce il codice in un'immagine di base Linux. Sto eseguendo il server sulla porta 8080, quindi espongo quella porta all'host che esegue il contenitore in questo modo:

docker run -p 8080:8080 dockertest

Funziona e riesco ad accedere al server tramite l'IP della macchina di Docker (quello che appare sul Docker Quickstart Terminal quando avviato), il problema è che non riesco ad accedere al sito web che sto ospitando dall'esterno dell'host, quindi se provo per aprire lo stesso indirizzo IP sul mio telefono mi dà solo un errore: questa pagina web non è disponibile (ERR_CONNECTION_TIMED_OUT).

Ho anche provato a specificare l'IP in questo modo:

docker run -p 192.168.0.157:8080:8080 dockertest

Ma quando lo faccio, non posso accedere al sito Web né tramite l'IP della macchina docker né l'IP specificato nella riga di comando sopra. Inoltre non sono sicuro di quale IP dovrei scrivere in quel comando ho usato l'IP del mio computer, ho anche provato 127.0.0.1 (localhost) ma questo mi ha dato lo stesso risultato: non potevo accedere al sito web tramite nessuno IP qualunque.

Ho cercato su Google questo problema e ho trovato molte domande su StackOverflow ma nessuna delle due mi ha aiutato a risolvere il mio problema, la maggior parte di esse era orientata a Linux o Mac, quindi la soluzione non si applicava alla mia situazione.

Inoltre, posso eseguire il codice Go sul mio computer e accedere al sito Web da un altro dispositivo nella stessa rete tramite l'IP del computer. Non capisco perché non riesco ad accedervi quando lo eseguo nella macchina docker, mi è venuto in mente che potrebbe avere qualcosa a che fare con l'inoltro IP o qualcosa del genere, ma sono un noob completo nel networking, io Sono principalmente uno sviluppatore web e non ho quasi nessuna esperienza in nativo.


hai usato EXPOSE 8080 nel tuo Dockerfile insieme all'opzione -p? Inoltre, controlla che la porta 8080 sulla scatola in cui è in esecuzione il tuo contenitore non sia bloccata dalle tue regole di sicurezza.
keda

@keda Sì, il Dockerfile contiene EXPOSE 8080. Sto eseguendo il container localmente sul mio computer tramite il terminale Quickstart di Docker, ho anche provato a disabilitare il firewall di Windows ma non ha funzionato neanche, non so se ci sono delle impostazioni che ho
Mi

Risposte:


91

TL; DR Controlla la modalità di rete del tuo host VirtualBox: dovrebbe essere bridgedse vuoi che la macchina virtuale (e il contenitore Docker che ospita) sia accessibile sulla tua rete locale.


Sembra che la tua confusione risieda nell'host a cui connetterti per accedere alla tua applicazione tramite HTTP. Non hai davvero spiegato quale sia la tua configurazione - farò alcune ipotesi, in base al fatto che hai "Windows" e "VirtualBox" nei tuoi tag.

Immagino che tu abbia Docker in esecuzione su alcune versioni di Linux in esecuzione in VirtualBox su un host Windows. Etichetterò gli indirizzi IP come segue:

D = l'indirizzo IP del contenitore Docker

L = l'indirizzo IP dell'host Linux in esecuzione in VirtualBox

W = l'indirizzo IP dell'host Windows

Quando esegui l'applicazione Go sul tuo host Windows, puoi connetterti ad essa http://W:8080/da qualsiasi punto della rete locale. Questo funziona perché l'applicazione Go collega la porta 8080 sulla macchina Windows e chiunque tenti di accedere alla porta 8080 all'indirizzo IP Wsi connetterà.

Ed è qui che diventa più complicato:

VirtualBox, quando imposta una macchina virtuale (VM), può configurare la rete in una delle diverse modalità. Non ricordo quali siano tutte le diverse opzioni, ma quella che vuoi è bridged. In questa modalità, VirtualBox connette la macchina virtuale alla rete locale come se fosse una macchina autonoma sulla rete, proprio come qualsiasi altra macchina collegata alla rete. In bridgedmodalità, la macchina virtuale appare sulla rete come qualsiasi altra macchina. Altre modalità impostano le cose in modo diverso e la macchina non sarà visibile sulla rete.

Quindi, supponendo che tu abbia configurato correttamente la rete per l'host Linux ( bridged), l'host Linux avrà un indirizzo IP sulla tua rete locale (qualcosa come 192.168.0.x) e sarai in grado di accedere al tuo contenitore Docker su http://L:8080/.

Se l'host Linux è impostato su una modalità diversa da bridged, potresti essere in grado di accedere dall'host Windows, ma questo dipenderà esattamente dalla modalità in cui si trova.

MODIFICA - in base ai commenti qui sotto, sembra molto simile alla situazione che ho descritto sopra è corretta.

Facciamo un piccolo backup: ecco come funziona Docker sul mio computer (Ubuntu Linux).

Immaginate corro lo stesso comando si ha: docker run -p 8080:8080 dockertest. Ciò che fa è avviare un nuovo contenitore basato dockertestsull'immagine e inoltrare (connettere) la porta 8080 sull'host Linux (il mio PC) alla porta 8080 sul contenitore. Docker configura la propria rete interna (con il proprio set di indirizzi IP) per consentire al daemon Docker di comunicare e per consentire ai contenitori di comunicare tra loro. Quindi fondamentalmente quello che stai facendo con questo -p 8080:8080è connettere la rete interna di Docker con la rete "esterna", ad es. l'adattatore di rete dell'host - su una particolare porta.

Con me finora? OK, ora facciamo un passo indietro e guardiamo il tuo sistema. La tua macchina esegue Windows: Docker non funziona (attualmente) su Windows, quindi lo strumento che stai utilizzando ha configurato un host Linux in una macchina virtuale VirtualBox. Quando si esegue l'operazione docker runnel proprio ambiente, accade esattamente la stessa cosa: la porta 8080 sull'host Linux è collegata alla porta 8080 sul contenitore. La grande differenza qui è che il tuo host Windows non è l'host Linux su cui è in esecuzione il contenitore, quindi c'è un altro livello qui ed è la comunicazione attraverso questo livello in cui stai riscontrando problemi.

Quello che ti serve è una delle due cose:

  1. per connettere la porta 8080 sulla VM VirtualBox alla porta 8080 sull'host Windows, proprio come connetti il ​​contenitore Docker alla porta host.

  2. per connettere la VM VirtualBox direttamente alla tua rete locale con la bridgedmodalità di rete che ho descritto sopra.

Se scegli la prima opzione, sarai in grado di accedere al contenitore in http://W:8080cui si Wtrova l'indirizzo IP o il nome host dell'host Windows. Se si opta per il secondo, sarà possibile accedere al contenitore in http://L:8080cui si Ltrova l'indirizzo IP o il nome host della VM Linux.

Quindi questa è tutta la spiegazione di livello superiore: ora devi capire come modificare la configurazione della VM VirtualBox. Ed è qui che non posso davvero aiutarti: non so quale strumento stai usando per fare tutto questo sulla tua macchina Windows e non ho familiarità con l'utilizzo di Docker su Windows.

Se riesci ad accedere alla finestra di configurazione di VirtualBox, puoi apportare le modifiche descritte di seguito. C'è anche un client a riga di comando che modificherà le VM, ma non ne ho familiarità.

Per la bridgedmodalità (e questa è davvero la scelta più semplice), spegni la VM, fai clic sul pulsante "Impostazioni" in alto e cambia la modalità di rete in bridged, quindi riavvia la VM e sei a posto. La VM dovrebbe rilevare un indirizzo IP sulla rete locale tramite DHCP e dovrebbe essere visibile ad altri computer sulla rete a quell'indirizzo IP.


1
Riesco a trovare solo 2 IP, quello che mostra Docker quando apro il terminale Quickstart (192.168.99.100) e quello del mio computer (192.168.0.157), usando docker run -p 8080:8080 dockertestposso accedere al mio sito web usando http://192.168.99.100:8080ma solo dal mio computer Windows (il host) e non dal mio telefono. Se uso docker run -p 192.168.0.157:8080:8080 dockertestnon riesco ad accedere al sito web con nessun IP da nessuna parte. Non sono sicuro di come impostare la rete, ho provato a usare --net=bridgema non ha funzionato nemmeno. Suppongo di aprire VirtualBox? Non posso farlo utilizzando il terminale di Docker?
sale rosso

Il problema non è con Docker, quindi no, Docker non può aiutarti. Aggiungerò alcune modifiche per illustrare cosa penso stia succedendo.
Kryten

Ok grazie! Ora capisco, ero confuso dall'intera parte della macchina virtuale Linux. Avevo l'impressione che Docker stesse usando Virtual Box per cose interne che non avrei dovuto toccare. In realtà è stato molto semplice, dovevo solo passare a bridgedVirtual Box e ora funziona a meraviglia, grazie mille.
sale rosso

Non c'è un modo per avere finestre e container docker nella stessa rete, in modo da poter accedere direttamente ai container senza port forwarding?
Vituel

Ci siamo imbattuti in questo quando cercavo il server Jupyter in esecuzione nella finestra mobile e prova ad accedervi tramite LAN. C'è comunque che posso scoprire cos'è L dopo aver cambiato la modalità a ponte?
PaulDong

122
  1. Apri Oracle VM VirtualBox Manager
  2. Seleziona la VM utilizzata da Docker
  3. Fare clic su Impostazioni -> Rete
  4. L'adattatore 1 dovrebbe (predefinito?) Essere "Collegato a: NAT"
  5. Fare clic su Avanzate -> Port Forwarding
  6. Aggiungi regola: protocollo TCP, porta host 8080, porta guest 8080 (lascia vuoti l'IP host e l'IP ospite)
  7. Guest è il tuo container docker e Host è la tua macchina

Ora dovresti essere in grado di navigare nel tuo contenitore tramite localhost: 8080 e your-internal-ip: 8080.


10
Confermato, simpatico e facile.
Dirk

2
risposta migliore, nessuna descrizione
ampia

2
per gli utenti vagabondi aggiungere questo in vagrantfile: config.vm.network "forwarded_port", guest: 8080, host: 8080, protocollo: "tcp"
Vince Verhoeven

3
Yo! Ha funzionato a meraviglia! Grazie!!!! Passo ore a cercare di capire questo.
Joseph Freeman

2
Questa è una soluzione fantastica per chiunque esegua Docker tramite VBox!
Mirodinho

7

Dopo aver provato diverse cose, questo ha funzionato per me:

  • usa il flag docker --publish = 0.0.0.0: 8080: 8080
  • imposta la modalità di rete della virtualbox su NAT e non utilizzare alcun port forwarding

Con indirizzi diversi da quello non 0.0.0.0ho avuto successo.


4

TLDR: se Windows Firewall è abilitato, assicurati che sia presente un'eccezione per "vpnkit" sulle reti private.

Nel mio caso particolare, ho scoperto che Windows Firewall stava bloccando la mia connessione quando ho provato a visitare la porta pubblicata del mio contenitore da un'altra macchina sulla mia rete locale, perché disabilitarlo ha fatto funzionare tutto.

Tuttavia, non volevo disabilitare completamente il firewall solo per poter accedere al servizio del mio contenitore. Ciò ha sollevato la domanda su quale "app" fosse in ascolto per conto del servizio del mio contenitore. Dopo aver trovato un altro thread SO che mi ha insegnato a utilizzare netstat -a -bper scoprire le app dietro i socket di ascolto sulla mia macchina, ho scoperto che lo era vpnkit.exe, che aveva già una voce nelle mie impostazioni di Windows Firewall: ma "reti private" era disabilitato su di esso, e una volta abilitato, sono stato in grado di visitare il servizio del mio contenitore da un'altra macchina senza dover disabilitare completamente il firewall.


Signore, mi hai salvato da ore e ore di frustrazione. Grazie.
Behdad

2

Questo è il problema più comune affrontato dagli utenti Windows per l'esecuzione di Docker Containers. IMO questa è la "domanda da un milione di dollari su Docker"; @ "Rocco Smit" ha giustamente sottolineato "il traffico in entrata perché era disabilitato di default sul firewall della mia macchina host"; nel mio caso, il mio software McAfee Anti Virus. Ho aggiunto porte aggiuntive per consentire il traffico in entrata da altri computer sulla stessa LAN Wi-Fi nelle impostazioni del firewall di McAfee; poi è stata magia. Ho lottato per più di una settimana navigando su Internet, SO, documentazioni Docker, Tutorial dopo Tutorial relativi alla rete di Docker e le numerose illustrazioni di "non supportato su Windows" per "macvlan", "ipvlan", "utente definito bridge "e anche questo stesso thread SO un paio di volte. Ho persino iniziato a navigare su Google con "qualcuno utilizza Docker in produzione?", (Sì, so che Linux è più popolare per i carichi di lavoro Prod rispetto ai server Windows) poiché non ero in grado di accedere (dal mio cellulare nello stesso wifi domestico) a nginx app distribuita nel Docker Container su Windows. Dopo tutto, a che serve, se non puoi accedere all'applicazione (distribuita su un Docker Container) da altri computer / dispositivi nella stessa LAN almeno; In definitiva, nel mio caso, il problema riguardava solo un firewall che bloccava il traffico in entrata; se non è possibile accedere all'applicazione (distribuita su un Docker Container) almeno da altri computer / dispositivi nella stessa LAN; In definitiva, nel mio caso, il problema riguardava solo un firewall che bloccava il traffico in entrata; se non è possibile accedere all'applicazione (distribuita su un Docker Container) almeno da altri computer / dispositivi nella stessa LAN; In definitiva, nel mio caso, il problema riguardava solo un firewall che bloccava il traffico in entrata;


0

Ho scoperto che oltre all'impostazione dei valori della porta -p, Docker per Windows utilizza vpnkit e il traffico in entrata perché era disabilitato per impostazione predefinita sul firewall della mia macchina host. Dopo aver abilitato le regole TCP in entrata per vpnkit, sono stato in grado di accedere ai miei contenitori da altre macchine sulla rete locale.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.