Desde el interior de un contenedor Docker, ¿cómo me conecto al host local de la máquina?
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.
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.1
su 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-gateway
opció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 run
comando, luego 127.0.0.1
en 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 docker0
con 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 docker0
obtendrá 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.1
en la docker0
interfaz de red.
Ahora inicie un nuevo contenedor y obtenga un shell en él: docker run --rm -it ubuntu:trusty bash
y 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.1
se 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 -p
o-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.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 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_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 de firewall en consecuencia.
Nota 2: si usa 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 y que quieran conectarse a MySQL deberán usar la 172.17.42.1
direcció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.1
su configuración de MySQL y conectarse 127.0.0.1
desde 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.1
y no mysql -h localhost
; de lo contrario, el cliente MySQL intentaría conectarse utilizando un socket Unix.
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.internal
que 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-gateway
a su docker
comando 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 bridge
red 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.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
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.internal
en su lugar.
Docker para Mac v 17.06 a v 17.11
Igual que el anterior pero utilícelo docker.for.mac.localhost
en 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.1
no 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:3000
dentro 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
Usar
host.docker.internal
en lugar de
localhost