Acceda a la base de datos del host desde un contenedor acoplable

131

Si tengo una base de datos mysql ejecutándose en alguna máquina host, y ese host también ejecuta un contenedor acoplable: ¿Cómo accedería a la base de datos mysql desde el contenedor acoplable que se ejecuta en el host?

Por ejemplo, ¿hay alguna manera de publicar un puerto de hosts en el contenedor (lo contrario de lo que hace Docker run -p)?

Ryan Anderson
fuente
1
Si el servidor MySQL está escuchando en un puerto, ¿no podría el contenedor simplemente conectarse al host en ese puerto como cualquier otra conexión a Internet?
jwodder

Respuestas:

87

Hay varias discusiones de larga data sobre cómo hacer esto de una manera consistente, bien entendida y portátil. No hay una resolución completa pero lo vincularé a las discusiones a continuación.

En cualquier caso, puede intentar usar la opción --add-host para ejecutar Docker para agregar la dirección IP del host en el archivo / etc / host del contenedor. Desde allí, es trivial conectarse al host en cualquier puerto requerido:

Agregar entradas a un archivo de hosts de contenedor

Puede agregar otros hosts al archivo / etc / hosts de un contenedor utilizando uno o más indicadores --add-host. Este ejemplo agrega una dirección estática para un host llamado docker:

 $ docker run --add-host=docker:10.180.0.1 --rm -it debian
    $$ ping docker
    PING docker (10.180.0.1): 48 data bytes
    56 bytes from 10.180.0.1: icmp_seq=0 ttl=254 time=7.600 ms
    56 bytes from 10.180.0.1: icmp_seq=1 ttl=254 time=30.705 ms
    ^C--- docker ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max/stddev = 7.600/19.152/30.705/11.553 ms

Nota: A veces necesita conectarse al host Docker, lo que significa obtener la dirección IP del host. Puede usar los siguientes comandos de shell para simplificar este proceso:

 $ alias hostip="ip route show 0.0.0.0/0 | grep -Eo 'via \S+' | awk '{ print $2 }'"
 $ docker run  --add-host=docker:$(hostip) --rm -it debian

Documentación:

https://docs.docker.com/engine/reference/commandline/run/

Debates sobre cómo acceder al host desde el contenedor:

https://github.com/docker/docker/issues/1143

https://github.com/docker/docker/issues/10023

John Petrone
fuente
¿Funcionará también detrás de un proxy inverso NGINX?
kta
89

De los 18.03 documentos:

Quiero conectarme desde un contenedor a un servicio en el host

El host tiene una dirección IP cambiante (o ninguna si no tiene acceso a la red). Desde el 18.03 en adelante, nuestra recomendación es conectarse al nombre DNS especial host.docker.internal, que se resuelve en la dirección IP interna utilizada por el host.

La puerta de enlace también es accesible como gateway.docker.internal.

EJEMPLO: Esto es lo que uso para mi cadena de conexión MySQL dentro de mi contenedor para acceder a la instancia de MySQL en mi host:

mysql://host.docker.internal:3306/my_awesome_database
Kevin Chen
fuente
31
Como una pista: hasta ahora solo funciona para Mac y Win
flp
me salvaste el día :)
amjad
44
Voto a favor. No solo por la respuesta, sino porque deberías CÓMO usarla con un ejemplo.
granadaCoder
Casi pasé 2 horas para lograr esto, muchas gracias.
Ashish Bainade
Todavía no hay soporte de Linux como escribió @flp, para aquellos curiosos. Aquí está el problema de github .
GAltelino
24

Use host.docker.internal desde Docker 18.03 en adelante.

Igor De Oliveira Sá
fuente
2
cómo ? ¿Puedes dar un ejemplo de cómo usarlo?
danfromisrael
¿Por qué no ejecutas un MySQL dockerizado?
Igor De Oliveira Sá
no funciona para mí enDocker version 18.03.0-ce, build 0520e24
scythargon
@ IgorDeOliveiraSá imagina el siguiente escenario, en el entorno de desarrollo tienes una base de datos que escucha 127.0.0.1:3306 en producción env tienes base de datos escuchando 127.0.0.1:3306, localmente es db local, la producción es proxy a la nube, tienes que dockerise mysql localmente y para la producción encuentre otra solución, o simplemente puede conectarse desde docker a puerto, funcionará para ambos casos
Drachenfels
1
docker.for.mac.localhost funciona para mí en18.03.1-ce-mac65
cdignam
21

Otras respuestas no funcionaron bien para mí. Mi contenedor no pudo resolver la ip del host usando host.docker.internal . Hay dos maneras

  1. Compartir red de host --net = host:

    docker run -it --net=host  myimage
    
  2. Usando la dirección IP de Docker , que generalmente es 172.17.0.1 . Puede verificarlo llamando al comando ifconfig y tomando inet addr de la interfaz docker

    user@ubuntu:~$ ifconfig
    docker0   Link encap:Ethernet  HWaddr 02:42:a4:a2:b2:f1  
      inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
      inet6 addr: fe80::42:a4ff:fea2:b2f1/64 Scope:Link
    

Una vez que tenga esta dirección IP, puede pasarla como un argumento para ejecutar Docker y luego a la aplicación o, como lo hago, mapear la ubicación de jdbc.properties por volumen al directorio en la máquina host, para que pueda administrar el archivo externamente .

  docker run -it -v /host_dir/docker_jdbc_config:${jetty_base}/var/config myimage

NOTA: es posible que su base de datos no permita conexiones externas. En el caso de postgresql, debe editar 2 archivos, como se describe aquí y aquí :

  1. Edite postgresql.conf para escuchar en todas las direcciones. Por defecto apuntará a localhost.

    listen_addresses = '*'
    
  2. Edite pg_hba.conf para permitir conexiones desde todas las direcciones. Agregue en la última línea:

    host     all             all             0.0.0.0/0               md5
    

IMPORTANTE: el último paso para actualizar el acceso a la base de datos no se recomienda para uso en producción a menos que esté realmente seguro de lo que está haciendo.

gmode
fuente
--net = host funcionó para mí en un entorno de CI, ¡muchas gracias!
Samy