[Nginx] Desde el interior de un contenedor Docker, ¿cómo me conecto al localhost de la máquina?


Answers

Para macOS y Windows

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

Use 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 docker.for.mac.host.internal lugar.

Docker para Mac v. 17.06 a v 17.11

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

Docker para Mac 17.05 y abajo

Para acceder a la máquina host desde el contenedor acoplable, debe adjuntar un alias IP a su interfaz de red. Puedes enlazar cualquier IP que quieras, solo asegúrate de no utilizarlo 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.

¡Entonces solo apunte su contenedor acoplable 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 reiniciará 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

Question

Así que tengo un Nginx ejecutándose dentro de un contenedor acoplable, tengo un mysql ejecutándose en localhost, quiero conectarme al MySql desde dentro de mi Nginx. MySql se está ejecutando en localhost y no está exponiendo un puerto al mundo exterior, por lo que está vinculado a localhost, no está vinculado a la dirección IP de la máquina.

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




Solución para Linux (kernel> = 3.6).

De acuerdo, su servidor localhost tiene una interfaz docker0 por defecto con la dirección IP 172.17.0.1 . Su contenedor comenzó con la configuración de red predeterminada --net = "bridge" .

  1. Habilite route_localnet para la interfaz docker0:
    $ sysctl -w net.ipv4.conf.docker0.route_localnet=1
  2. Agregue estas reglas a iptables:
    $ iptables -t nat -I PREROUTING -i docker0 -d 172.17.0.1 -p tcp --dport 3306 -j DNAT --to 127.0.0.1:3306
    $ iptables -t filter -I INPUT -i docker0 -d 127.0.0.1 -p tcp --dport 3306 -j ACCEPT
  3. Crear usuario de mysql con acceso desde '%' que significa, de cualquier persona, excluyendo localhost:
    CREATE USER 'user'@'%' IDENTIFIED BY 'password';
  4. Cambie en su script la dirección del servidor mysql a 172.17.0.1


De la documentación del kernel :

route_localnet - BOOLEAN: No considere las direcciones de bucle de retorno como fuente marciana o destino mientras enruta. Esto permite el uso de 127/8 para el enrutamiento local ( FALSE predeterminado ).




Editar: Terminé prototipando el concepto en GitHub. Consulte: https://github.com/sivabudh/system-in-a-box

Primero, mi respuesta está dirigida a 2 grupos de personas: los que usan una Mac y los que usan Linux.

El modo de red de host no funciona en una Mac. Debe usar un alias de IP, consulte: https://.com/a/43541681/2713729

¿Qué es un modo de red host? Ver: https://docs.docker.com/engine/reference/run/#/network-settings

En segundo lugar, para aquellos de ustedes que están usando Linux (mi experiencia directa fue con Ubuntu 14.04 LTS y estoy actualizando a 16.04 LTS en producción), , pueden hacer que el servicio que se ejecuta dentro de un contenedor Docker se conecte a los servicios localhost que se ejecutan en el host Docker (por ejemplo, su computadora portátil).

¿Cómo?

La clave es cuando ejecuta el contenedor Docker, tiene que ejecutarlo con el modo de host . El comando se ve así:

docker run --network="host" -id <Docker image ID>

Cuando haga un ifconfig (necesitará apt-get install net-tools el contenedor ifconfig ), dentro de su contenedor, verá que las interfaces de red son las mismas que en el host Docker (por ejemplo, su computadora portátil). )

Es importante tener en cuenta que soy un usuario de Mac, pero ejecuto Ubuntu bajo Parallels, por lo que usar una Mac no es una desventaja. ;-)

Y así es como se conecta el contenedor NGINX al MySQL ejecutándose en un servidor localhost .




Aquí está mi solución: funciona para mi caso

  • configure el servidor mysql local para el acceso público mediante el comentario #bind-address = 127.0.0.1 en /etc/mysql/mysql.conf.d

  • reinicie el servidor mysql sudo /etc/init.d/mysql restart

  • ejecute el siguiente comando para abrir el acceso de usuario root cualquier host mysql -uroot -proot GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION; FLUSH PRIVILEGES; mysql -uroot -proot GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION; FLUSH PRIVILEGES;

  • crear la secuencia de comandos sh: run_docker.sh

    #!bin/bash

    HOSTIP=`ip -4 addr show scope global dev eth0 | grep inet | awk '{print \$2}' | cut -d / -f 1`


      docker run -it -d --name web-app \
                  --add-host=local:${HOSTIP} \
                  -p 8080:8080 \
                  -e DATABASE_HOST=${HOSTIP} \
                  -e DATABASE_PORT=3306 \
                  -e DATABASE_NAME=demo \
                  -e DATABASE_USER=root \
                  -e DATABASE_PASSWORD=root \
                  sopheamak/springboot_docker_mysql

  
  • correr con docker-composer

    version: '2.1'
    
    

    services:
    tomcatwar: extra_hosts: - "local:10.1.2.232" image: sopheamak/springboot_docker_mysql
    ports: - 8080:8080 environment: - DATABASE_HOST=local - DATABASE_USER=root - DATABASE_PASSWORD=root - DATABASE_NAME=demo - DATABASE_PORT=3306




Esto funcionó para mí en una pila NGINX / PHP-FPM sin tocar ningún código o red donde la aplicación solo espera poder conectarse a localhost

Monte mysqld.sock desde el host hasta dentro del contenedor.

Encuentre la ubicación del archivo mysql.sock en el host que ejecuta mysql:
netstat -ln | awk '/mysql(.*)?\.sock/ { print $9 }'

Monta ese archivo donde se espera en la ventana acoplable:
docker run -v /hostpath/to/mysqld.sock:/containerpath/to/mysqld.sock

Posibles ubicaciones de mysqld.sock:
/tmp/mysqld.sock /var/run/mysqld/mysqld.sock /var/lib/mysql/mysql.sock




La solución más simple para Mac OSX

Solo usa la dirección IP de tu Mac. En Mac, ejecute esto para obtener la dirección IP y usarla desde el contenedor:

$ ifconfig | grep 'inet 192'| awk '{ print $2}'

Siempre que el servidor que se ejecute localmente en su Mac o en otro contenedor acoplable esté escuchando 0.0.0.0, el contenedor acoplable podrá comunicarse con esa dirección.

Si solo desea acceder a otro contenedor de acoplador que está escuchando en 0.0.0.0, puede usar 172.17.0.1