Saltar al contenido

Desde el interior de un contenedor Docker, ¿cómo me conecto al host local de la máquina?

Solución:

Editar: Si está utilizando Docker-para-mac o Docker-para-Windows 18.03+, simplemente conéctese a su servicio mysql usando el host host.docker.internal (en vez de 127.0.0.1 en su cadena de conexión).

A partir de Docker 18.09.3, esto no funciona en Docker para Linux. Se envió una solución el 8 de marzo de 2019 y, con suerte, se fusionará con la base del código. Hasta entonces, una solución es usar un contenedor como se describe en la respuesta de qoomon.

2020-01: Se han hecho algunos avances. Si todo va bien, esto debería aterrizar en Docker 20.04

Docker 20.10-beta1 se ha informado de implementar host.docker.internal :

$ docker run --rm --add-host host.docker.internal:host-gateway alpine ping host.docker.internal
PING host.docker.internal (172.17.0.1): 56 data bytes
64 bytes from 172.17.0.1: seq=0 ttl=64 time=0.534 ms
64 bytes from 172.17.0.1: seq=1 ttl=64 time=0.176 ms
...

TLDR

Usar --network="host" en tus docker run comando, entonces 127.0.0.1 en su contenedor de la ventana acoplable apuntará a su host de la ventana acoplable.

Nota: Este modo solo funciona en Docker para Linux, según la documentación.


Nota sobre los modos de red del contenedor de la ventana acoplable

Docker ofrece diferentes modos de red cuando se ejecutan contenedores. Dependiendo del modo que elija, se conectará a su base de datos MySQL que se ejecuta en el host de la ventana acoplable de manera diferente.

docker run –network = “puente” (predeterminado)

Docker crea un puente llamado docker0 por defecto. Tanto el host de la ventana acoplable como los contenedores de la ventana acoplable tienen una dirección IP en ese puente.

en el host de Docker, escriba sudo ip addr show docker0 tendrá una salida que se parece a:

[[email protected]:~] $ sudo ip addr show docker0
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
    inet 172.17.42.1/16 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::5484:7aff:fefe:9799/64 scope link
       valid_lft forever preferred_lft forever

Entonces aquí mi host de la ventana acoplable tiene la dirección IP 172.17.42.1 sobre el docker0 interfaz de red.

Ahora inicie un nuevo contenedor y obtenga un caparazón: docker run --rm -it ubuntu:trusty bash y dentro del tipo de contenedor ip addr show eth0 para descubrir cómo está configurada su interfaz de red principal:

[email protected]:/# ip addr show eth0
863: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 66:32:13:f0:f1:e3 brd ff:ff:ff:ff:ff:ff
    inet 172.17.1.192/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::6432:13ff:fef0:f1e3/64 scope link
       valid_lft forever preferred_lft forever

Aquí mi contenedor tiene la dirección IP 172.17.1.192. Ahora mire la tabla de enrutamiento:

[email protected]:/# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         172.17.42.1     0.0.0.0         UG    0      0        0 eth0
172.17.0.0      *               255.255.0.0     U     0      0        0 eth0

Entonces, la dirección IP del host de la ventana acoplable 172.17.42.1 se establece como la ruta predeterminada y es accesible desde su contenedor.

[email protected]:/# ping 172.17.42.1
PING 172.17.42.1 (172.17.42.1) 56(84) bytes of data.
64 bytes from 172.17.42.1: icmp_seq=1 ttl=64 time=0.070 ms
64 bytes from 172.17.42.1: icmp_seq=2 ttl=64 time=0.201 ms
64 bytes from 172.17.42.1: icmp_seq=3 ttl=64 time=0.116 ms

docker run –network = “host”

Alternativamente, puede ejecutar un contenedor de la ventana acoplable con la configuración de red establecida en host. Dicho contenedor compartirá la pila de red con el host de la ventana acoplable y, desde el punto de vista del contenedor, localhost (o 127.0.0.1) se referirá al host de la ventana acoplable.

Tenga en cuenta que cualquier puerto abierto en su contenedor de la ventana acoplable se abriría en el host de la ventana acoplable. Y esto sin requerir el -p o -P docker run opción.

Configuración de IP en mi host de Docker:

[[email protected]:~] $ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe98:dcaa/64 scope link
       valid_lft forever preferred_lft forever

y desde un contenedor docker en anfitrión modo:

[[email protected]:~] $ docker run --rm -it --network=host ubuntu:trusty ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe98:dcaa/64 scope link
       valid_lft forever preferred_lft forever

Como puede ver, tanto el host de la ventana acoplable como el contenedor de la ventana acoplable comparten exactamente la misma interfaz de red y, como tal, tienen la misma dirección IP.


Conectarse a MySQL desde contenedores

Modo Puente

Para acceder a MySQL que se ejecuta en el host de Docker desde contenedores en Modo Puente, debe asegurarse de que el servicio MySQL esté escuchando conexiones en el 172.17.42.1 Dirección IP.

Para hacerlo, asegúrese de tener bind-address = 172.17.42.1 o bind-address = 0.0.0.0 en su archivo de configuración de MySQL (my.cnf).

Si necesita establecer una variable de entorno con la dirección IP de la puerta de enlace, puede ejecutar el siguiente código en un contenedor:

export DOCKER_HOST_IP=$(route -n | awk '/UG[ t]/{print $2}')

luego en su aplicación, use el DOCKER_HOST_IP variable de entorno para abrir la conexión a MySQL.

Nota: si utiliza bind-address = 0.0.0.0 su servidor MySQL escuchará las conexiones en todas las interfaces de red. Eso significa que se puede acceder a su servidor MySQL desde Internet; asegúrese de configurar las reglas del firewall en consecuencia.

Nota 2: si utiliza bind-address = 172.17.42.1 su servidor MySQL no escuchará las conexiones realizadas a 127.0.0.1. Los procesos que se ejecutan en el host de la ventana acoplable que querrían conectarse a MySQL tendrían que usar el 172.17.42.1 Dirección IP.

modo anfitrión

Para acceder a MySQL que se ejecuta en el host de la ventana acoplable desde contenedores en modo anfitrión, puedes quedarte bind-address = 127.0.0.1 en su configuración de MySQL y todo lo que necesita hacer es conectarse a 127.0.0.1 de sus contenedores:

[[email protected]:~] $ docker run --rm -it --network=host mysql mysql -h 127.0.0.1 -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 36
Server version: 5.5.41-0ubuntu0.14.04.1 (Ubuntu)

Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.

Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.

mysql>

Nota: Utilizar mysql -h 127.0.0.1 y no mysql -h localhost; de lo contrario, el cliente MySQL intentaría conectarse usando un socket Unix.

Para macOS y Windows

Docker v 18.03 y superior (desde el 21 de marzo de 2018)

Utilice su dirección IP interna o conéctese al nombre DNS especial host.docker.internal que se resolverá en la dirección IP interna utilizada por el host.

Soporte de Linux pendiente https://github.com/docker/for-linux/issues/264

MacOS con versiones anteriores de Docker

Docker para Mac v 17.12 a v 18.02

Igual que el anterior pero use docker.for.mac.host.internal en lugar de.

Docker para Mac v 17.06 a v 17.11

Igual que el anterior pero use docker.for.mac.localhost en lugar de.

Docker para Mac 17.05 y versiones anteriores

Para acceder a la máquina host desde el contenedor de la ventana acoplable, debe adjuntar un alias de IP a su interfaz de red. Puede vincular la IP que desee, solo asegúrese de no usarla para nada más.

sudo ifconfig lo0 alias 123.123.123.123/24

Luego, asegúrese de que su servidor esté escuchando la IP mencionada anteriormente o 0.0.0.0. Si está escuchando en localhost 127.0.0.1 no aceptará la conexión.

Luego, simplemente apunte su contenedor docker a esta IP y podrá acceder a la máquina host.

Para probar, puede ejecutar algo como curl -X GET 123.123.123.123:3000 dentro del contenedor.

El alias se restablecerá en cada reinicio, así que cree un script de inicio si es necesario.

Solución y más documentación aquí: https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds

Estoy haciendo un truco similar a las publicaciones anteriores para que la IP local se asigne a un nombre de alias (DNS) en el contenedor. El principal problema es conseguir dinámicamente con un script simple que funcione tanto en Linux y OSX la dirección IP del host. Hice este script que funciona en ambos entornos (incluso en la distribución de Linux con "$LANG" != "en_*" configurado):

ifconfig | grep -E "([0-9]{1,3}.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1

Entonces, usando Docker Compose, la configuración completa será:

Script de inicio (docker-run.sh):

export DOCKERHOST=$(ifconfig | grep -E "([0-9]{1,3}.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1)
docker-compose -f docker-compose.yml up

docker-compose.yml:

myapp:
  build: .
  ports:
    - "80:80"
  extra_hosts:
    - "dockerhost:$DOCKERHOST"

Entonces cambia http://localhost para http://dockerhost en su código.

Para obtener una guía más avanzada sobre cómo personalizar el DOCKERHOST script, eche un vistazo a esta publicación con una explicación de cómo funciona.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *