Comment se connecter à un conteneur Docker depuis l'extérieur de l'hôte (même réseau) [Windows]

87

J'ai créé mon premier conteneur docker, il exécute un serveur utilisant Go mais je ne peux pas y accéder depuis l'extérieur de l'ordinateur hôte. Je viens de commencer avec docker donc je suis un peu perdu ici.

J'ai donc un code Go très simple qui démarre un serveur, j'ai construit l'image docker qui installe Go et construit le code dans une image de base Linux. J'exécute le serveur sur le port 8080 donc j'expose ce port à l'hôte exécutant le conteneur comme ceci:

docker run -p 8080:8080 dockertest

Cela fonctionne et je peux accéder au serveur via l'adresse IP de la machine de docker (celle qui apparaît sur le terminal de démarrage rapide Docker une fois lancé), le problème est que je ne peux pas accéder au site Web que j'héberge depuis l'extérieur de l'hôte, donc si j'essaye pour ouvrir la même adresse IP sur mon téléphone, cela me donne juste une erreur: Cette page Web n'est pas disponible (ERR_CONNECTION_TIMED_OUT).

J'ai également essayé de spécifier l'adresse IP comme ceci:

docker run -p 192.168.0.157:8080:8080 dockertest

Mais lorsque je fais cela, je ne peux accéder au site Web via ni l'IP de la machine docker ni l'adresse IP spécifiée sur la ligne de commande ci-dessus. Je ne sais pas non plus quelle IP je suis censé écrire dans cette commande.J'ai utilisé l'adresse IP de mon ordinateur, j'ai également essayé 127.0.0.1 (localhost) mais cela m'a donné le même résultat: je n'ai pas pu accéder au site Web via aucun IP que ce soit.

J'ai recherché ce problème sur Google et trouvé de nombreuses questions StackOverflow, mais aucune ne m'a aidé à résoudre mon problème, la plupart d'entre elles étaient orientées vers Linux ou Mac, donc la solution ne s'appliquait pas à ma situation.

En outre, je peux exécuter le code Go sur mon ordinateur et accéder au site Web à partir d'un autre appareil du même réseau via l'adresse IP de mon ordinateur. Je ne comprends pas pourquoi je ne peux pas y accéder lorsque je l'exécute dans la machine docker, il m'est venu à l'esprit que cela pouvait avoir quelque chose à voir avec le transfert IP ou quelque chose, mais je Je suis principalement un développeur Web et je n'ai presque aucune expérience en natif.

sel rouge
la source
avez-vous utilisé EXPOSE 8080 dans votre Dockerfile en conjonction avec l'option -p? Vérifiez également que le port 8080 sur la boîte où votre conteneur est en cours d'exécution n'est pas bloqué par vos règles de sécurité.
keda
@keda Oui, le Dockerfile contient EXPOSE 8080. J'exécute le conteneur localement sur mon ordinateur via le terminal de démarrage rapide de Docker, j'ai également essayé de désactiver le pare-feu Windows mais cela ne fonctionnait pas non plus, je ne sais pas s'il y a un paramètre que je 'm missing
redsalt

Réponses:

90

TL; DR Vérifiez le mode réseau de votre hôte VirtualBox - il devrait l'être bridgedsi vous voulez que la machine virtuelle (et le conteneur Docker qu'elle héberge) soit accessible sur votre réseau local.


Il semble que votre confusion réside dans l'hôte auquel se connecter pour accéder à votre application via HTTP. Vous n'avez pas vraiment précisé quelle est votre configuration - je vais faire des suppositions, basées sur le fait que vous avez "Windows" et "VirtualBox" dans vos balises.

Je suppose que Docker fonctionne sur une certaine saveur de Linux fonctionnant dans VirtualBox sur un hôte Windows. Je vais étiqueter les adresses IP comme suit:

D = l'adresse IP du conteneur Docker

L = l'adresse IP de l'hôte Linux s'exécutant dans VirtualBox

W = l'adresse IP de l'hôte Windows

Lorsque vous exécutez votre application Go sur votre hôte Windows, vous pouvez vous y connecter http://W:8080/depuis n'importe où sur votre réseau local. Cela fonctionne car l'application Go lie le port 8080 sur la machine Windows et toute personne qui tente d'accéder au port 8080 à l'adresse IP Wse connecte.

Et voici où cela devient plus compliqué:

VirtualBox, lorsqu'il configure une machine virtuelle (VM), peut configurer le réseau dans l'un des différents modes. Je ne me souviens pas de toutes les différentes options, mais celle que vous voulez est bridged. Dans ce mode, VirtualBox connecte la machine virtuelle à votre réseau local comme s'il s'agissait d'une machine autonome sur le réseau, comme toute autre machine connectée à votre réseau. En bridgedmode, la machine virtuelle apparaît sur votre réseau comme toute autre machine. D'autres modes configurent les choses différemment et la machine ne sera pas visible sur votre réseau.

Donc, en supposant que vous configuriez correctement le réseau pour l'hôte Linux ( bridged), l'hôte Linux aura une adresse IP sur votre réseau local (quelque chose comme 192.168.0.x) et vous pourrez accéder à votre conteneur Docker à http://L:8080/.

Si l'hôte Linux est défini sur un mode autre que bridged, vous pourrez peut- être accéder à partir de l'hôte Windows, mais cela dépendra exactement du mode dans lequel il se trouve.

EDIT - sur la base des commentaires ci-dessous, cela ressemble beaucoup à la situation que j'ai décrite ci-dessus est correcte.

Reculons un peu: voici comment Docker fonctionne sur mon ordinateur (Ubuntu Linux).

Imaginez que je lance la même commande que vous avez: docker run -p 8080:8080 dockertest. Cela permet de démarrer un nouveau conteneur basé sur l' dockertestimage et de transférer (connecter) le port 8080 sur l'hôte Linux (mon PC) vers le port 8080 sur le conteneur. Docker configure son propre réseau interne (avec son propre ensemble d'adresses IP) pour permettre au démon Docker de communiquer et pour permettre aux conteneurs de communiquer entre eux. Donc, fondamentalement, ce que vous faites avec cela, -p 8080:8080c'est de connecter le réseau interne de Docker au réseau "externe" - c'est-à-dire. l'adaptateur réseau de l'hôte - sur un port particulier.

Avec moi si loin? OK, prenons maintenant du recul et regardons votre système. Votre machine exécute Windows - Docker ne fonctionne pas (actuellement) sous Windows, donc l'outil que vous utilisez a configuré un hôte Linux dans une machine virtuelle VirtualBox. Lorsque vous faites le docker rundans votre environnement, exactement la même chose se produit: le port 8080 sur l'hôte Linux est connecté au port 8080 sur le conteneur. La grande différence ici est que votre hôte Windows n'est pas l'hôte Linux sur lequel le conteneur s'exécute, il y a donc une autre couche ici et c'est la communication à travers cette couche où vous rencontrez des problèmes.

Ce dont vous avez besoin est l'une des deux choses suivantes:

  1. pour connecter le port 8080 sur la VM VirtualBox au port 8080 sur l'hôte Windows, tout comme vous connectez le conteneur Docker au port hôte.

  2. pour connecter la VM VirtualBox directement à votre réseau local avec le bridgedmode réseau décrit ci-dessus.

Si vous optez pour la première option, vous pourrez accéder au conteneur http://W:8080où se Wtrouve l'adresse IP ou le nom d'hôte de l'hôte Windows. Si vous optez pour le second, vous pourrez accéder au conteneur http://L:8080où se Ltrouve l'adresse IP ou le nom d'hôte de la VM Linux.

C'est donc toute l'explication de niveau supérieur - vous devez maintenant comprendre comment modifier la configuration de la VM VirtualBox. Et voici où je ne peux pas vraiment vous aider - je ne sais pas quel outil vous utilisez pour faire tout cela sur votre machine Windows et je ne suis pas du tout familiarisé avec l'utilisation de Docker sur Windows.

Si vous pouvez accéder à la fenêtre de configuration de VirtualBox, vous pouvez effectuer les modifications décrites ci-dessous. Il existe également un client de ligne de commande qui modifiera les machines virtuelles, mais je ne suis pas familier avec cela.

Pour le bridgedmode (et c'est vraiment le choix le plus simple), arrêtez votre VM, cliquez sur le bouton "Paramètres" en haut et changez le mode réseau en bridged, puis redémarrez la VM et vous êtes prêt à partir. La machine virtuelle doit récupérer une adresse IP sur votre réseau local via DHCP et doit être visible par les autres ordinateurs du réseau à cette adresse IP.

Kryten
la source
1
Je ne trouve que 2 adresses IP, celle que Docker affiche lorsque j'ouvre le terminal de démarrage rapide (192.168.99.100) et celle de mon ordinateur (192.168.0.157), en utilisant docker run -p 8080:8080 dockertestje peux accéder à mon site Web en utilisant http://192.168.99.100:8080mais uniquement à partir de mon ordinateur Windows (le hôte) et non depuis mon téléphone. Si j'utilise, docker run -p 192.168.0.157:8080:8080 dockertestje ne peux pas accéder au site Web avec une adresse IP de n'importe où. Je ne sais pas comment configurer le réseau, j'ai essayé de l'utiliser --net=bridgemais cela n'a pas fonctionné non plus. Suis-je supposé ouvrir VirtualBox? Est-ce que je ne peux pas le faire en utilisant le terminal Docker?
redsalt
Le problème n'est pas avec Docker, donc non, Docker ne peut pas vous aider. Je vais ajouter quelques modifications pour illustrer ce que je pense qu'il se passe.
Kryten
D'accord, merci! Maintenant que je comprends, je devenais confus par toute la partie machine virtuelle Linux. J'avais l'impression que Docker utilisait Virtual Box pour des éléments internes que je n'étais pas censé toucher. C'était en fait très facile, je devais juste passer à bridgedVirtual Box et maintenant cela fonctionne à merveille, merci beaucoup.
redsalt
N'existe-t-il pas un moyen d'avoir des fenêtres et des conteneurs Docker dans le même réseau, afin que nous puissions accéder directement aux conteneurs sans redirection de port?
Vituel
Je suis tombé sur cela lors de la recherche du serveur Jupyter en cours d'exécution dans le docker et essayez d'y accéder via LAN. Y a-t-il de toute façon que je puisse savoir ce qu'est L après avoir basculé le mode en ponté?
PaulDong
121
  1. Ouvrez Oracle VM VirtualBox Manager
  2. Sélectionnez la VM utilisée par Docker
  3. Cliquez sur Paramètres -> Réseau
  4. L'adaptateur 1 doit (par défaut?) Être «Attaché à: NAT»
  5. Cliquez sur Avancé -> Redirection de port
  6. Ajouter une règle: protocole TCP, port hôte 8080, port invité 8080 (laissez l'IP hôte et l'IP invité vides)
  7. L'invité est votre conteneur docker et l'hôte est votre machine

Vous devriez maintenant pouvoir accéder à votre conteneur via localhost: 8080 et your-internal-ip: 8080.

Davey Chu
la source
10
Confirmé, agréable et facile.
Dirk
2
meilleure réponse, pas de description énorme comme celle sélectionnée
Amir Qayyum Khan
2
pour les utilisateurs vagabonds, ajoutez ceci dans vagrantfile: config.vm.network "forwarded_port", guest: 8080, host: 8080, protocol: "tcp"
Vince Verhoeven
3
Yo! Cela a fonctionné comme un charme! Merci!!!! Je passe des heures à essayer de comprendre celui-ci.
Joseph Freeman
2
C'est une solution fantastique pour quiconque exécute Docker via VBox!
Mirodinho
7

Après avoir essayé plusieurs choses, cela a fonctionné pour moi:

  • utilisez l'indicateur de menu fixe --publish = 0.0.0.0: 8080: 8080
  • définissez le mode réseau de virtualbox sur NAT et n'utilisez aucune redirection de port

Avec des adresses autres que 0.0.0.0moi, je n'ai eu aucun succès.

mnieber
la source
4

TLDR: Si le pare-feu Windows est activé, assurez-vous qu'il existe une exception pour «vpnkit» sur les réseaux privés.

Pour mon cas particulier, j'ai découvert que le pare-feu Windows bloquait ma connexion lorsque j'ai essayé de visiter le port publié de mon conteneur à partir d'une autre machine sur mon réseau local, car sa désactivation faisait tout fonctionner.

Cependant, je ne voulais pas désactiver complètement le pare-feu juste pour pouvoir accéder au service de mon conteneur. Cela a soulevé la question de savoir quelle "application" écoutait au nom du service de mon conteneur. Après avoir trouvé un autre fil SO qui m'a appris à utiliser netstat -a -bpour découvrir les applications derrière les sockets d'écoute sur ma machine, j'ai appris que c'était le cas vpnkit.exe, qui avait déjà une entrée dans mes paramètres de pare-feu Windows: mais les "réseaux privés" y étaient désactivés, et une fois que je l'ai activé, j'ai pu visiter le service de mon conteneur à partir d'une autre machine sans avoir à désactiver complètement le pare-feu.

Atul Varma
la source
Monsieur, vous m'avez sauvé d'heures et d'heures de frustration. Merci.
Behdad
2

Il s'agit du problème le plus courant rencontré par les utilisateurs de Windows pour exécuter des conteneurs Docker. OMI c'est la "question à un million de dollars sur Docker"; @ "Rocco Smit" a souligné à juste titre "le trafic entrant car il était désactivé par défaut sur le pare-feu de ma machine hôte"; dans mon cas, mon logiciel McAfee Anti Virus. J'ai ajouté des ports supplémentaires pour autoriser le trafic entrant d'autres ordinateurs sur le même LAN Wifi dans les paramètres du pare-feu de McAfee; alors c'était magique. J'avais eu du mal pendant plus d'une semaine à naviguer sur Internet, SO, documentations Docker, Tutoriels après Tutoriels liés à la mise en réseau de Docker, et les nombreuses illustrations de "non pris en charge sur Windows" pour "macvlan", "ipvlan", "utilisateur pont défini "et même ce même couple de threads SO. J'ai même commencé à naviguer sur Google avec "quelqu'un utilisant Docker en production?", (Oui, je sais que Linux est plus populaire pour les charges de travail Prod que les serveurs Windows) car je n'ai pas pu accéder (depuis mon mobile dans le même wifi domestique) à un nginx application déployée dans Docker Container sous Windows. Après tout, à quoi ça sert, si vous ne pouvez pas accéder à l'application (déployée sur un Docker Container) à partir d'autres ordinateurs / appareils dans le même LAN au moins; En fin de compte, dans mon cas, le problème était simplement avec un pare-feu bloquant le trafic entrant; si vous ne pouvez pas accéder à l'application (déployée sur un conteneur Docker) à partir d'autres ordinateurs / périphériques au moins dans le même LAN; En fin de compte, dans mon cas, le problème était simplement avec un pare-feu bloquant le trafic entrant; si vous ne pouvez pas accéder à l'application (déployée sur un conteneur Docker) à partir d'autres ordinateurs / périphériques au moins dans le même LAN; En fin de compte, dans mon cas, le problème était simplement avec un pare-feu bloquant le trafic entrant;

banarasi
la source
0

J'ai trouvé qu'en plus de définir les valeurs du port -p, Docker pour Windows utilise vpnkit et le trafic entrant car il était désactivé par défaut sur le pare-feu de ma machine hôte. Après avoir activé les règles TCP entrantes pour vpnkit, j'ai pu accéder à mes conteneurs à partir d'autres machines sur le réseau local.

Rocco Smit
la source