Herstellen einer Verbindung zu einem Docker-Container von außerhalb des Hosts (dasselbe Netzwerk) [Windows]

86

Ich habe meinen ersten Docker-Container erstellt. Er führt einen Server mit Go aus, kann jedoch nicht von außerhalb des Host-Computers darauf zugreifen. Ich habe gerade mit Docker angefangen, also bin ich hier ein wenig verloren.

Ich habe also einen sehr einfachen Go-Code, der einen Server startet. Ich habe das Docker-Image erstellt, das Go installiert, und den Code in einem Linux-Basis-Image erstellt. Ich führe den Server auf Port 8080 aus, also stelle ich diesen Port dem Host zur Verfügung, auf dem der Container wie folgt ausgeführt wird:

docker run -p 8080:8080 dockertest

Das funktioniert und ich kann über die IP-Adresse des Docker-Computers (die auf dem Docker-Schnellstart-Terminal angezeigt wird, wenn sie gestartet wird) auf den Server zugreifen. Das Problem ist, dass ich nicht von außerhalb des Hosts auf die von mir gehostete Website zugreifen kann. Wenn ich es also versuche Wenn Sie dieselbe IP-Adresse auf meinem Telefon öffnen, wird nur ein Fehler angezeigt: Diese Webseite ist nicht verfügbar (ERR_CONNECTION_TIMED_OUT).

Ich habe auch versucht, die IP wie folgt anzugeben:

docker run -p 192.168.0.157:8080:8080 dockertest

Wenn ich das tue, kann ich weder über die IP des Docker-Computers noch über die in der obigen Befehlszeile angegebene IP auf die Website zugreifen. Ich bin mir auch nicht sicher, welche IP ich in diesen Befehl schreiben soll. Ich habe die IP meines Computers verwendet. Ich habe auch 127.0.0.1 (localhost) ausprobiert, aber das hat mir das gleiche Ergebnis gebracht: Ich konnte über keine auf die Website zugreifen IP was auch immer.

Ich habe dieses Problem gegoogelt und viele StackOverflow-Fragen gefunden, aber keine hat mir geholfen, mein Problem zu lösen. Die meisten waren auf Linux oder Mac ausgerichtet, sodass die Lösung nicht auf meine Situation zutraf.

Außerdem kann ich den Go-Code auf meinem Computer ausführen und über die IP-Adresse meines Computers von einem anderen Gerät im selben Netzwerk auf die Website zugreifen. Ich verstehe nicht, warum ich nicht darauf zugreifen kann, wenn ich es auf dem Docker-Computer ausführe. Mir ist aufgefallen, dass es möglicherweise etwas mit IP-Weiterleitung zu tun hat oder so, aber ich bin ein absoluter Neuling im Netzwerk Ich bin meistens ein Webentwickler und habe fast keine Erfahrung in Native.

Rotsalz
quelle
Haben Sie EXPOSE 8080 in Ihrer Docker-Datei in Verbindung mit der Option -p verwendet? Überprüfen Sie außerdem, ob der Port 8080 auf der Box, auf der Ihr Container ausgeführt wird, nicht durch Ihre Sicherheitsregeln blockiert ist.
Keda
@keda Ja, die Docker-Datei enthält EXPOSE 8080. Ich führe den Container lokal auf meinem Computer über das Docker-Schnellstart-Terminal aus. Ich habe auch versucht, die Windows-Firewall zu deaktivieren, aber das hat auch nicht funktioniert. Ich weiß nicht, ob ich eine Einstellung habe
Ich

Antworten:

89

TL; DR Überprüfen Sie den Netzwerkmodus Ihres VirtualBox-Hosts. Dies sollte der Fall sein, bridgedwenn Sie möchten, dass auf die virtuelle Maschine (und den von ihr gehosteten Docker-Container) in Ihrem lokalen Netzwerk zugegriffen werden kann.


Es klingt so, als ob Ihre Verwirrung darin liegt, zu welchem ​​Host Sie eine Verbindung herstellen müssen, um über HTTP auf Ihre Anwendung zuzugreifen. Sie haben Ihre Konfiguration nicht wirklich dargelegt - ich werde einige Vermutungen anstellen, basierend auf der Tatsache, dass Ihre Tags "Windows" und "VirtualBox" enthalten.

Ich vermute, dass Docker unter Linux in VirtualBox auf einem Windows-Host ausgeführt wird. Ich werde die IP-Adressen wie folgt kennzeichnen:

D = die IP-Adresse des Docker-Containers

L = die IP-Adresse des Linux-Hosts, der in VirtualBox ausgeführt wird

W = die IP-Adresse des Windows-Hosts

Wenn Sie Ihre Go-Anwendung auf Ihrem Windows-Host ausführen, können Sie http://W:8080/von überall in Ihrem lokalen Netzwerk eine Verbindung herstellen. Dies funktioniert, weil die Go-Anwendung den Port 8080 auf dem Windows-Computer bindet und jeder, der versucht, unter der IP-Adresse auf Port 8080 zuzugreifen W, eine Verbindung herstellt.

Und hier wird es komplizierter:

VirtualBox kann beim Einrichten einer virtuellen Maschine (VM) das Netzwerk in einem von mehreren verschiedenen Modi konfigurieren. Ich erinnere mich nicht an die verschiedenen Optionen, aber die, die Sie wollen, ist bridged. In diesem Modus verbindet VirtualBox die virtuelle Maschine mit Ihrem lokalen Netzwerk, als wäre sie eine eigenständige Maschine im Netzwerk, genau wie jede andere Maschine, die an Ihr Netzwerk angeschlossen war. Im bridgedModus wird die virtuelle Maschine wie jede andere Maschine in Ihrem Netzwerk angezeigt. Andere Modi richten die Einstellungen anders ein und der Computer ist in Ihrem Netzwerk nicht sichtbar.

Vorausgesetzt, Sie haben das Netzwerk für den Linux-Host ( bridged) korrekt eingerichtet , hat der Linux-Host eine IP-Adresse in Ihrem lokalen Netzwerk (etwa 192.168.0.x) und Sie können auf Ihren Docker-Container unter zugreifen http://L:8080/.

Wenn der Linux-Host auf einen anderen Modus als eingestellt ist bridged, können Sie möglicherweise vom Windows-Host aus darauf zugreifen. Dies hängt jedoch davon ab, in welchem ​​Modus er sich befindet.

BEARBEITEN - basierend auf den Kommentaren unten klingt es sehr nach der Situation, die ich oben beschrieben habe, richtig ist.

Lassen Sie uns ein wenig zurücktreten: So funktioniert Docker auf meinem Computer (Ubuntu Linux).

Stellen Sie sich vor, ich führe denselben Befehl aus, den Sie haben : docker run -p 8080:8080 dockertest. Dadurch wird ein neuer Container basierend auf dem dockertestImage gestartet und Port 8080 auf dem Linux-Host (mein PC) an Port 8080 auf dem Container weitergeleitet (verbunden). Docker richtet ein eigenes internes Netzwerk (mit eigenen IP-Adressen) ein, damit der Docker-Dämon kommunizieren und Container miteinander kommunizieren können. Im Grunde genommen verbinden Sie damit -p 8080:8080das interne Netzwerk von Docker mit dem "externen" Netzwerk - dh. der Netzwerkadapter des Hosts - an einem bestimmten Port.

Bis jetzt bei mir? OK, jetzt machen wir einen Schritt zurück und schauen uns Ihr System an. Auf Ihrem Computer wird Windows ausgeführt. Docker wird (derzeit) nicht unter Windows ausgeführt. Daher hat das von Ihnen verwendete Tool einen Linux-Host in einer virtuellen VirtualBox-Maschine eingerichtet. Wenn Sie dies docker runin Ihrer Umgebung tun, geschieht genau das Gleiche: Port 8080 auf dem Linux-Host ist mit Port 8080 auf dem Container verbunden. Der große Unterschied besteht darin, dass Ihr Windows-Host nicht der Linux-Host ist, auf dem der Container ausgeführt wird. Daher gibt es hier eine weitere Ebene und die Kommunikation über diese Ebene, auf der Probleme auftreten.

Was Sie brauchen, ist eines von zwei Dingen:

  1. So verbinden Sie Port 8080 auf der VirtualBox-VM mit Port 8080 auf dem Windows-Host, genau wie Sie den Docker-Container mit dem Host-Port verbinden.

  2. um die VirtualBox-VM mit dem bridgedoben beschriebenen Netzwerkmodus direkt mit Ihrem lokalen Netzwerk zu verbinden .

Wenn Sie sich für die erste Option entscheiden, können Sie auf den Container zugreifen, in http://W:8080dem Wsich die IP-Adresse oder der Hostname des Windows-Hosts befindet. Wenn Sie sich für die zweite Option entscheiden, können Sie auf den Container zugreifen, in http://L:8080dem Lsich die IP-Adresse oder der Hostname der Linux-VM befindet.

Das ist also die übergeordnete Erklärung - jetzt müssen Sie herausfinden, wie Sie die Konfiguration der VirtualBox-VM ändern können. Und hier kann ich Ihnen nicht wirklich helfen - ich weiß nicht, mit welchem ​​Tool Sie all dies auf Ihrem Windows-Computer ausführen, und ich bin mit der Verwendung von Docker unter Windows überhaupt nicht vertraut.

Wenn Sie zum VirtualBox-Konfigurationsfenster gelangen, können Sie die unten beschriebenen Änderungen vornehmen. Es gibt auch einen Befehlszeilenclient, der VMs ändert, aber ich bin damit nicht vertraut.

bridgedFahren Sie für den Modus (und dies ist wirklich die einfachste Wahl) Ihre VM herunter, klicken Sie oben auf die Schaltfläche "Einstellungen" und ändern Sie den Netzwerkmodus in bridged, starten Sie die VM neu und los geht's. Die VM sollte eine IP-Adresse in Ihrem lokalen Netzwerk über DHCP abrufen und für andere Computer im Netzwerk unter dieser IP-Adresse sichtbar sein.

Kryten
quelle
1
Ich kann nur zwei IP-Adressen finden, die Docker beim Öffnen des Schnellstart-Terminals (192.168.99.100) und die meines Computers (192.168.0.157) anzeigt. Mit docker run -p 8080:8080 dockertestkann ich auf meine Website zugreifen, http://192.168.99.100:8080jedoch nur von meinem Windows-Computer aus Host) und nicht von meinem Telefon. Wenn ich benutze, docker run -p 192.168.0.157:8080:8080 dockertestkann ich von keiner Stelle aus mit einer IP auf die Website zugreifen. Ich bin mir nicht sicher, wie ich das Netzwerk einrichten soll. Ich habe es versucht, --net=bridgeaber das hat auch nicht funktioniert. Soll ich VirtualBox öffnen? Kann ich das nicht mit dem Docker-Terminal machen?
Redsalt
Das Problem liegt nicht bei Docker, also nein, Docker kann Ihnen nicht helfen. Ich werde einige Änderungen hinzufügen, um zu veranschaulichen, was meiner Meinung nach vor sich geht.
Kryten
OK danke! Jetzt verstehe ich, dass mich der gesamte Teil der virtuellen Linux-Maschine verwirrt hat. Ich hatte den Eindruck, dass Docker Virtual Box für interne Dinge verwendete, die ich nicht berühren sollte. Es war eigentlich sehr einfach, ich musste nur bridgedin Virtual Box wechseln und jetzt wirkt es Wunder, vielen Dank.
Redsalt
Gibt es keine Möglichkeit, Windows- und Docker-Container im selben Netzwerk zu haben, sodass wir ohne Portweiterleitung direkt auf Container zugreifen können?
Vituel
Ich bin darauf gestoßen, als ich nach einem laufenden Jupyter-Server im Docker gesucht habe und versucht habe, über LAN darauf zuzugreifen. Kann ich trotzdem herausfinden, was L ist, nachdem ich den Modus auf überbrückt umgeschaltet habe?
PaulDong
118
  1. Öffnen Sie den Oracle VM VirtualBox Manager
  2. Wählen Sie die von Docker verwendete VM aus
  3. Klicken Sie auf Einstellungen -> Netzwerk
  4. Adapter 1 sollte (Standard?) "Attached to: NAT" sein.
  5. Klicken Sie auf Erweitert -> Portweiterleitung
  6. Regel hinzufügen: Protokoll TCP, Host-Port 8080, Gast-Port 8080 (Host-IP und Gast-IP leer lassen)
  7. Gast ist Ihr Docker-Container und Host ist Ihre Maschine

Sie sollten nun in der Lage sein, über localhost: 8080 und your-internal-ip: 8080 zu Ihrem Container zu navigieren.

Davey Chu
quelle
9
Bestätigt, nett und einfach.
Dirk
2
beste Antwort, keine große Beschreibung wie die ausgewählte
Amir Qayyum Khan
2
für vagabundierende Benutzer fügen Sie dies in vagrantfile hinzu: config.vm.network "forwarded_port", Gast: 8080, Host: 8080, Protokoll: "tcp"
Vince Verhoeven
3
Yo! Das hat wie ein Zauber gewirkt! Vielen Dank!!!! Ich verbringe Stunden damit, dies herauszufinden.
Joseph Freeman
2
Dies ist eine fantastische Lösung für alle, die Docker über VBox ausführen!
Mirodinho
7

Nachdem ich einige Dinge ausprobiert hatte, funktionierte dies für mich:

  • Verwenden Sie das Docker-Flag --publish = 0.0.0.0: 8080: 8080
  • Stellen Sie den Virtualbox-Netzwerkmodus auf NAT ein und verwenden Sie keine Portweiterleitung

Mit anderen Adressen hatte 0.0.0.0ich keinen Erfolg.

mnieber
quelle
4

TLDR: Wenn Sie die Windows-Firewall aktiviert haben, stellen Sie sicher, dass in privaten Netzwerken eine Ausnahme für "vpnkit" vorliegt.

In meinem speziellen Fall stellte ich fest, dass die Windows-Firewall meine Verbindung blockierte, als ich versuchte, den veröffentlichten Port meines Containers von einem anderen Computer in meinem lokalen Netzwerk aus zu besuchen, da durch Deaktivieren alles funktionierte.

Ich wollte die Firewall jedoch nicht vollständig deaktivieren, nur um auf den Dienst meines Containers zugreifen zu können. Dies warf die Frage auf, welche "App" im Namen des Dienstes meines Containers zuhörte. Nachdem ich einen anderen SO-Thread gefunden hatte , mit dem ich netstat -a -bdie Apps hinter den Listening-Sockets auf meinem Computer erkennen konnte, stellte ich fest, dass dies der Fall war vpnkit.exe, der bereits einen Eintrag in meinen Windows-Firewall-Einstellungen hatte: "Private Netzwerke" war darauf deaktiviert, und Nachdem ich es aktiviert hatte, konnte ich den Dienst meines Containers von einem anderen Computer aus aufrufen, ohne die Firewall vollständig deaktivieren zu müssen.

Atul Varma
quelle
Sir, Sie haben mich vor Stunden und Stunden der Frustration gerettet. Vielen Dank.
Behdad
2

Dies ist das häufigste Problem, mit dem Windows-Benutzer beim Ausführen von Docker-Containern konfrontiert sind. IMO ist dies die "Millionen-Dollar-Frage zu Docker"; @ "Rocco Smit" hat zu Recht darauf hingewiesen, dass "eingehender Datenverkehr standardmäßig in der Firewall meines Host-Computers deaktiviert wurde". In meinem Fall meine McAfee Anti Virus-Software. Ich habe in den Firewall-Einstellungen von McAfee zusätzliche Ports hinzugefügt, die für eingehenden Datenverkehr von anderen Computern im selben Wifi-LAN zulässig sind. dann war es Magie. Ich hatte mehr als eine Woche lang Probleme mit dem Surfen im Internet, SO, Docker-Dokumentationen, Tutorials nach Tutorials im Zusammenhang mit dem Networking von Docker und den vielen Abbildungen von "unter Windows nicht unterstützt" für "macvlan", "ipvlan", "Benutzer" definierte Brücke "und sogar den gleichen SO-Thread ein paar Mal. Ich habe sogar angefangen, mit "jemand, der Docker in der Produktion verwendet?" Auf Google zu surfen (ja, ich weiß, dass Linux für Prod-Workloads im Vergleich zu Windows-Servern beliebter ist), da ich nicht (von meinem Handy im selben Home-WLAN) auf einen Nginx zugreifen konnte App in Docker Container unter Windows bereitgestellt. Was nützt es schließlich, wenn Sie zumindest nicht von anderen Computern / Geräten im selben LAN auf die Anwendung (die auf einem Docker-Container bereitgestellt wird) zugreifen können? Letztendlich war das Problem in meinem Fall nur eine Firewall, die eingehenden Datenverkehr blockierte. wenn Sie nicht von anderen Computern / Geräten im selben LAN aus auf die Anwendung zugreifen können (die auf einem Docker-Container bereitgestellt ist); Letztendlich war das Problem in meinem Fall nur eine Firewall, die eingehenden Datenverkehr blockierte. wenn Sie nicht von anderen Computern / Geräten im selben LAN aus auf die Anwendung zugreifen können (die auf einem Docker-Container bereitgestellt ist); Letztendlich war das Problem in meinem Fall nur eine Firewall, die eingehenden Datenverkehr blockierte.

Banarasi
quelle
0

Ich habe festgestellt, dass Docker für Windows neben dem Festlegen der -p-Portwerte vpnkit verwendet und eingehenden Datenverkehr standardmäßig in der Firewall meines Hostcomputers deaktiviert ist. Nachdem ich die eingehenden TCP-Regeln für vpnkit aktiviert hatte, konnte ich von anderen Computern im lokalen Netzwerk auf meine Container zugreifen.

Rocco Smit
quelle