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

Resuelto Phil asked hace 10 años • 43 respuestas

Tengo un Nginx ejecutándose dentro de un contenedor acoplable. Tengo un MySql ejecutándose en el sistema host. Quiero conectarme a MySql desde mi contenedor. MySql solo se vincula al dispositivo localhost.

¿Hay alguna forma de conectarse a este MySql o cualquier otro programa en localhost desde este contenedor acoplable?

Esta pregunta es diferente de "Cómo obtener la dirección IP del host de la ventana acoplable desde dentro de un contenedor de la ventana acoplable" debido al hecho de que la dirección IP del host de la ventana acoplable podría ser la IP pública o la IP privada en la red, lo que puede o puede no será accesible desde el contenedor acoplable (me refiero a IP pública si está alojada en AWS o algo así). Incluso si tiene la dirección IP del host de Docker, no significa que pueda conectarse al host de Docker desde dentro del contenedor, dado que la dirección IP de su red Docker puede ser superpuesta, host, puente, macvlan, ninguna, etc., lo que restringe la accesibilidad de esa dirección IP.

Phil avatar Jun 20 '14 10:06 Phil
Aceptado

Editar:

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

Si está utilizando Docker-for-Linux 20.10.0+, también puede usar el host host.docker.internal si inició su contenedor Docker con la --add-host host.docker.internal:host-gatewayopción o agregó el siguiente fragmento en su archivo docker-compose.yml:

extra_hosts:
    - "host.docker.internal:host-gateway"

De lo contrario, lea a continuación


TLDR

Úselo --network="host"en su docker runcomando, luego 127.0.0.1en su contenedor acoplable apuntará a su host acoplable.

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


Nota sobre los modos de red del contenedor Docker

Docker ofrece diferentes modos de red cuando ejecuta 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.

ventana acoplable ejecutar --network="puente" (predeterminado)

Docker crea un puente docker0con el nombre predeterminado. 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 Docker, escriba y sudo ip addr show docker0obtendrá un resultado parecido a:

[vagrant@docker:~] $ 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 Docker tiene la dirección IP 172.17.42.1en la docker0interfaz de red.

Ahora inicie un nuevo contenedor y obtenga un shell en él: docker run --rm -it ubuntu:trusty bashy dentro del tipo de contenedor ip addr show eth0, descubra cómo está configurada su interfaz de red principal:

root@e77f6a1b3740:/# 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:

root@e77f6a1b3740:/# 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

Por lo tanto, la dirección IP del host de la ventana acoplable 172.17.42.1se establece como la ruta predeterminada y se puede acceder a ella desde su contenedor.

root@e77f6a1b3740:/# 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

ejecución de la ventana acoplable --network="host"

Alternativamente, puede ejecutar un contenedor acoplable con la configuración de red configurada enhost . 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 acoplable se abrirá en el host de la ventana acoplable. Y esto sin requerir la opción -po-P docker run .

Configuración de IP en mi host Docker:

[vagrant@docker:~] $ 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 acoplable en modo host :

[vagrant@docker:~] $ 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.


Conexión a MySQL desde contenedores

Modo Puente

Para acceder a MySQL que se ejecuta en el host de la ventana acoplable desde contenedores en modo puente , debe asegurarse de que el servicio MySQL esté escuchando las conexiones en la 172.17.42.1dirección IP.

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

Si necesita configurar 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 la DOCKER_HOST_IPvariable de entorno para abrir la conexión a MySQL.

Nota: si utiliza bind-address = 0.0.0.0su 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 de firewall en consecuencia.

Nota 2: si usa bind-address = 172.17.42.1su servidor MySQL no escuchará las conexiones realizadas a 127.0.0.1. Los procesos que se ejecutan en el host de la ventana acoplable y que quieran conectarse a MySQL deberán usar la 172.17.42.1dirección IP.

modo anfitrión

Para acceder a MySQL que se ejecuta en el host de Docker desde contenedores en modo host , puede mantener bind-address = 127.0.0.1su configuración de MySQL y conectarse 127.0.0.1desde sus contenedores:

[vagrant@docker:~] $ 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: use mysql -h 127.0.0.1y no mysql -h localhost; de lo contrario, el cliente MySQL intentaría conectarse utilizando un socket Unix.

Thomasleveil avatar Jun 20 '2014 11:06 Thomasleveil

Para todas las plataformas

Docker v 20.10 y superior (desde el 14 de diciembre de 2020)

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

Esto es para fines de desarrollo y no funciona en un entorno de producción fuera de Docker Desktop.

Advertencias de Linux

Para habilitar esto en Docker en Linux, agregue --add-host=host.docker.internal:host-gatewaya su dockercomando para habilitar la función.

Para habilitar esto en Docker Compose en Linux, agregue las siguientes líneas a la definición del contenedor:

extra_hosts:
    - "host.docker.internal:host-gateway"

Según algunos usuarios, el nombre DNS especial sólo funciona dentro de la bridgered predeterminada de Docker, no dentro de redes personalizadas.

Para versiones anteriores de Docker 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.internalque se resolverá en la dirección IP interna utilizada por el host.

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

Para versiones anteriores de macOS de Docker

Docker para Mac v 17.12 a v 18.02

Igual que el anterior pero utilícelo docker.for.mac.host.internalen su lugar.

Docker para Mac v 17.06 a v 17.11

Igual que el anterior pero utilícelo docker.for.mac.localhosten su lugar.

Docker para Mac 17.05 y versiones anteriores

Para acceder a la máquina host desde el contenedor acoplable, debe adjuntar un alias de IP a su interfaz de red. Puedes vincular cualquier IP que desees, solo asegúrate 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.1no aceptará la conexión.

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

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

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

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

Janne Annala avatar Apr 21 '2017 11:04 Janne Annala

Usar

host.docker.internal

en lugar de

localhost
DeyaEldeen avatar Jul 27 '2020 09:07 DeyaEldeen