Cómo conectarse a un contenedor Docker desde fuera del host (misma red) [Windows]

88

Creé mi primer contenedor de ventana acoplable, está ejecutando un servidor usando Go pero no puedo acceder a él desde fuera de la computadora host. Acabo de comenzar con Docker, así que estoy un poco perdido aquí.

Así que tengo un código Go muy simple que inicia un servidor, he creado la imagen de la ventana acoplable que instala Go y crea el código en una imagen base de Linux. Estoy ejecutando el servidor en el puerto 8080, así que expongo ese puerto al host que ejecuta el contenedor de esta manera:

docker run -p 8080:8080 dockertest

Eso funciona y puedo acceder al servidor a través de la IP de la máquina de Docker (la que aparece en la Terminal de inicio rápido de Docker cuando se inicia), el problema es que no puedo acceder al sitio web que estoy alojando desde fuera del host, así que si intento para abrir la misma dirección IP en mi teléfono, solo me da un error: Esta página web no está disponible (ERR_CONNECTION_TIMED_OUT).

También intenté especificar la IP de esta manera:

docker run -p 192.168.0.157:8080:8080 dockertest

Pero cuando hago eso, no puedo acceder al sitio web a través de la IP de la máquina acoplable ni la IP especificada en la línea de comando anterior. Tampoco estoy seguro de qué IP se supone que debo escribir en ese comando. Usé la IP de mi computadora, también probé 127.0.0.1 (localhost) pero eso me dio el mismo resultado: no pude acceder al sitio web a través de ningún IP cualquiera.

Busqué en Google este problema y encontré muchas preguntas de StackOverflow, pero ninguna me ayudó a resolver mi problema, la mayoría de ellas estaban orientadas a Linux o Mac, por lo que la solución no se aplicó a mi situación.

Además, puedo ejecutar el código Go en mi computadora y acceder al sitio web desde otro dispositivo en la misma red a través de la IP de mi computadora. No entiendo por qué no puedo acceder a él cuando lo estoy ejecutando en la máquina docker, se me ocurrió que puede tener algo que ver con el reenvío de IP o algo así, pero soy un novato completo en redes, yo Soy principalmente un desarrollador web y casi no tengo experiencia en nativos.

sal roja
fuente
¿Usó EXPOSE 8080 en su Dockerfile junto con la opción -p? Además, verifique que el puerto 8080 en la casilla donde se ejecuta su contenedor no esté bloqueado por sus reglas de seguridad.
keda
@keda Sí, el Dockerfile contiene EXPOSE 8080. Estoy ejecutando el contenedor localmente en mi computadora a través de la Terminal de inicio rápido de Docker, también intenté deshabilitar el firewall de Windows pero tampoco funcionó, no sé si hay alguna configuración que
estoy

Respuestas:

90

TL; DR Verifique el modo de red de su host VirtualBox; debería serlo bridgedsi desea que la máquina virtual (y el contenedor Docker que está alojando) sea accesible en su red local.


Parece que su confusión radica en a qué host conectarse para acceder a su aplicación a través de HTTP. Realmente no ha explicado en detalle cuál es su configuración; voy a hacer algunas conjeturas, basándome en el hecho de que tiene "Windows" y "VirtualBox" en sus etiquetas.

Supongo que tiene Docker ejecutándose en algún tipo de Linux ejecutándose en VirtualBox en un host de Windows. Voy a etiquetar las direcciones IP de la siguiente manera:

D = la dirección IP del contenedor Docker

L = la dirección IP del host Linux que se ejecuta en VirtualBox

W = la dirección IP del host de Windows

Cuando ejecuta su aplicación Go en su host de Windows, puede conectarse http://W:8080/desde cualquier lugar de su red local. Esto funciona porque la aplicación Go vincula el puerto 8080 en la máquina con Windows y cualquiera que intente acceder al puerto 8080 en la dirección IP Wse conectará.

Y aquí es donde se vuelve más complicado:

VirtualBox, cuando configura una máquina virtual (VM), puede configurar la red en uno de varios modos diferentes. No recuerdo cuáles son todas las diferentes opciones, pero la que quieres es bridged. En este modo, VirtualBox conecta la máquina virtual a su red local como si fuera una máquina independiente en la red, como cualquier otra máquina que estuviera conectada a su red. En el bridgedmodo, la máquina virtual aparece en su red como cualquier otra máquina. Otros modos configuran las cosas de manera diferente y la máquina no será visible en su red.

Por lo tanto, suponiendo que configuró la red correctamente para el host de Linux ( bridged), el host de Linux tendrá una dirección IP en su red local (algo así como 192.168.0.x) y podrá acceder a su contenedor Docker en http://L:8080/.

Si el host de Linux está configurado en un modo distinto a bridged, es posible que pueda acceder desde el host de Windows, pero esto dependerá exactamente del modo en el que se encuentre.

EDITAR : según los comentarios a continuación, parece que la situación que describí anteriormente es correcta.

Retrocedamos un poco: así es como funciona Docker en mi computadora (Ubuntu Linux).

Imagino corro el mismo comando que tenga: docker run -p 8080:8080 dockertest. Lo que hace esto es iniciar un nuevo contenedor basado en la dockertestimagen y reenviar (conectar) el puerto 8080 en el host Linux (mi PC) al puerto 8080 en el contenedor. Docker configura su propia red interna (con su propio conjunto de direcciones IP) para permitir que el demonio de Docker se comunique y permitir que los contenedores se comuniquen entre sí. Entonces, básicamente, lo que está haciendo -p 8080:8080es conectar la red interna de Docker con la red "externa", es decir. el adaptador de red del host, en un puerto en particular.

Conmigo hasta ahora? Bien, ahora demos un paso atrás y observemos su sistema. Su máquina está ejecutando Windows: Docker no se ejecuta (actualmente) en Windows, por lo que la herramienta que está utilizando ha configurado un host Linux en una máquina virtual VirtualBox. Cuando lo hace docker runen su entorno, ocurre exactamente lo mismo: el puerto 8080 del host Linux está conectado al puerto 8080 del contenedor. La gran diferencia aquí es que su host de Windows no es el host de Linux en el que se ejecuta el contenedor, por lo que hay otra capa aquí y es la comunicación a través de esta capa en la que tiene problemas.

Lo que necesita es una de dos cosas:

  1. para conectar el puerto 8080 en VirtualBox VM al puerto 8080 en el host de Windows, al igual que conecta el contenedor Docker al puerto del host.

  2. para conectar la VM VirtualBox directamente a su red local con el bridgedmodo de red que describí anteriormente.

Si elige la primera opción, podrá acceder al contenedor http://W:8080donde Westá la dirección IP o el nombre de host del host de Windows. Si opta por el segundo, podrá acceder al contenedor http://L:8080donde Lestá la dirección IP o el nombre de host de la VM Linux.

Así que esa es toda la explicación de nivel superior: ahora necesita descubrir cómo cambiar la configuración de VirtualBox VM. Y aquí es donde realmente no puedo ayudarlo: no sé qué herramienta está usando para hacer todo esto en su máquina con Windows y no estoy familiarizado con el uso de Docker en Windows.

Si puede acceder a la ventana de configuración de VirtualBox, puede realizar los cambios que se describen a continuación. También hay un cliente de línea de comandos que modificará las máquinas virtuales, pero no estoy familiarizado con eso.

Para el bridgedmodo (y esta es realmente la opción más simple), apague su máquina virtual, haga clic en el botón "Configuración" en la parte superior y cambie el modo de red a bridged, luego reinicie la máquina virtual y listo. La VM debería recoger una dirección IP en su red local a través de DHCP y debería ser visible para otras computadoras en la red en esa dirección IP.

Kryten
fuente
1
Solo puedo encontrar 2 direcciones IP, la que muestra Docker cuando abro la Terminal de inicio rápido (192.168.99.100) y la que tiene mi computadora (192.168.0.157), usando docker run -p 8080:8080 dockertestPuedo acceder a mi sitio web usando http://192.168.99.100:8080pero solo desde mi computadora Windows (la host) y no desde mi teléfono. Si utilizo docker run -p 192.168.0.157:8080:8080 dockertestno puedo acceder al sitio web con ninguna IP desde cualquier lugar. No estoy seguro de cómo configurar la red, intenté usarlo --net=bridgepero tampoco funcionó. ¿Se supone que debo abrir VirtualBox? ¿No puedo hacerlo usando la terminal de Docker?
sal roja
El problema no es con Docker, así que no, Docker no puede ayudarte. Voy a agregar algunas ediciones para ilustrar lo que creo que está sucediendo.
Kryten
¡Ok, gracias! Ahora entiendo, me estaba confundiendo toda la parte de la máquina virtual Linux. Tenía la impresión de que Docker estaba usando Virtual Box para cosas internas que se suponía que no debía tocar. En realidad fue muy fácil, solo tuve que cambiarme a bridgedVirtual Box y ahora funciona de maravilla, muchas gracias.
sal roja
¿No hay alguna forma de tener contenedores de Windows y Docker en la misma red, para que podamos acceder a los contenedores directamente sin reenvío de puertos?
Vituel
Me encontré con esto cuando buscaba ejecutar el servidor Jupyter en la ventana acoplable e intentaba acceder a él a través de LAN. ¿De todos modos puedo averiguar qué es L después de cambiar el modo a puenteado?
PaulDong
121
  1. Abra Oracle VM VirtualBox Manager
  2. Seleccione la máquina virtual utilizada por Docker
  3. Haga clic en Configuración -> Red
  4. El adaptador 1 debería (¿predeterminado?) "Conectado a: NAT"
  5. Haga clic en Avanzado -> Reenvío de puertos
  6. Agregar regla: Protocolo TCP, Puerto de host 8080, Puerto de invitado 8080 (deje vacíos la IP del host y la IP del invitado)
  7. Guest es su contenedor de Docker y Host es su máquina

Ahora debería poder navegar a su contenedor a través de localhost: 8080 y your-internal-ip: 8080.

Davey Chu
fuente
10
Confirmado, agradable y fácil.
Dirk
2
mejor respuesta, sin una gran descripción como la seleccionada
Amir Qayyum Khan
2
para usuarios vagabundos agregue esto en vagrantfile: config.vm.network "fordered_port", invitado: 8080, host: 8080, protocolo: "tcp"
Vince Verhoeven
3
¡Yo! ¡Esto funcionó a las mil maravillas! ¡¡¡¡Gracias!!!! Paso horas tratando de resolver esto.
Joseph Freeman
2
¡Esta es una solución fantástica para cualquiera que ejecute Docker a través de VBox!
Mirodinho
7

Después de probar varias cosas, esto funcionó para mí:

  • use el indicador de ventana acoplable --publish = 0.0.0.0: 8080: 8080
  • establezca el modo de red virtualbox en NAT y no use ningún reenvío de puerto

Con direcciones que 0.0.0.0no sean yo no tuve éxito.

mnieber
fuente
4

TLDR: si tiene el Firewall de Windows habilitado, asegúrese de que haya una excepción para "vpnkit" en redes privadas.

Para mi caso particular, descubrí que Windows Firewall estaba bloqueando mi conexión cuando intenté visitar el puerto publicado de mi contenedor desde otra máquina en mi red local, porque deshabilitarlo hizo que todo funcionara.

Sin embargo, no quería deshabilitar el firewall por completo solo para poder acceder al servicio de mi contenedor. Esto planteó la pregunta de qué "aplicación" estaba escuchando en nombre del servicio de mi contenedor. Después de encontrar otro hilo SO que me enseñó a usar netstat -a -bpara descubrir las aplicaciones detrás de los enchufes de escucha en mi máquina, supe que lo era vpnkit.exe, que ya tenía una entrada en la configuración de mi Firewall de Windows: pero las "redes privadas" estaban deshabilitadas en él, y una vez que lo habilité, pude visitar el servicio de mi contenedor desde otra máquina sin tener que deshabilitar completamente el firewall.

Atul Varma
fuente
Señor, me salvó de horas y horas de frustración. Gracias.
Behdad
2

Este es el problema más común que enfrentan los usuarios de Windows al ejecutar contenedores Docker. En mi opinión, esta es la "pregunta del millón de dólares sobre Docker"; @ "Rocco Smit" ha señalado correctamente "el tráfico entrante ya que estaba deshabilitado de forma predeterminada en el firewall de mi máquina host"; en mi caso, mi software McAfee Anti Virus. Agregué puertos adicionales para permitir el tráfico entrante de otras computadoras en la misma LAN Wifi en la Configuración del firewall de McAfee; entonces fue mágico. Había luchado durante más de una semana navegando por todo Internet, SO, documentación de Docker, tutoriales tras tutoriales relacionados con las redes de Docker y las numerosas ilustraciones de "no compatible con Windows" para "macvlan", "ipvlan", "usuario puente definido "e incluso este mismo hilo SO un par de veces. Incluso comencé a navegar en Google con "¿alguien usa Docker en producción?", (Sí, sé que Linux es más popular para cargas de trabajo de Prod en comparación con los servidores de Windows) ya que no pude acceder (desde mi móvil en el mismo wifi doméstico) a un nginx aplicación implementada en Docker Container en Windows. Después de todo, de qué sirve si no puede acceder a la aplicación (implementada en un contenedor Docker) desde otras computadoras / dispositivos en la misma LAN al menos; En última instancia, en mi caso, el problema fue solo con un firewall que bloquea el tráfico entrante; si no puede acceder a la aplicación (implementada en un contenedor Docker) desde otras computadoras / dispositivos en la misma LAN al menos; En última instancia, en mi caso, el problema fue solo con un firewall que bloquea el tráfico entrante; si no puede acceder a la aplicación (implementada en un contenedor Docker) desde otras computadoras / dispositivos en la misma LAN al menos; En última instancia, en mi caso, el problema fue solo con un firewall que bloquea el tráfico entrante;

Banarasi
fuente
0

Descubrí que junto con la configuración de los valores del puerto -p, Docker para Windows usa vpnkit y el tráfico entrante estaba deshabilitado de manera predeterminada en el firewall de mi máquina host. Después de habilitar las reglas de TCP de entrada para vpnkit, pude acceder a mis contenedores desde otras máquinas en la red local.

Rocco Smit
fuente