docker - hub - Cómo acceder al puerto host desde el contenedor acoplable
docker-compose (10)
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 resolverá 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 versiones inferiores
Para acceder a la máquina host desde el contenedor 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.
¡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 restablecerá en cada reinicio, así que cree un script de inicio si es necesario.
Solución y más documentación aquí: doc
Tengo un contenedor acoplable con jenkins. Como parte del proceso de compilación, necesito acceder a un servidor web que se ejecuta localmente en la máquina host. ¿Hay alguna manera de que el servidor web host (que se puede configurar para ejecutarse en un puerto) pueda exponerse al contenedor jenkins?
EDITAR: estoy ejecutando Docker de forma nativa en una máquina Linux.
ACTUALIZAR:
Además de la respuesta @larsks a continuación, para obtener la dirección IP de la IP del host de la máquina host, hago lo siguiente:
ip addr show docker0 | grep -Po ''inet /K[/d.]+''
Actualmente, la forma más fácil de hacer esto en Mac y Windows es usar el host doc , que resuelve la dirección IP de la máquina host. Desafortunadamente, https://github.com/docker/for-linux/issues/264 (a partir de abril de 2018).
Al ejecutar Docker de forma nativa en Linux, puede acceder a los servicios de host utilizando la dirección IP de la interfaz
docker0
.
Desde el interior del contenedor, esta será su ruta predeterminada.
Por ejemplo, en mi sistema:
$ ip addr show docker0
7: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
valid_lft forever preferred_lft forever
inet6 fe80::f4d2:49ff:fedd:28a0/64 scope link
valid_lft forever preferred_lft forever
Y dentro de un contenedor:
# ip route show
default via 172.17.0.1 dev eth0
172.17.0.0/16 dev eth0 src 172.17.0.4
Es bastante fácil extraer esta dirección IP usando un simple script de shell:
#!/bin/sh
hostip=$(ip route show | awk ''/default/ {print $3}'')
echo $hostip
Es posible que deba modificar las reglas de
iptables
en su host para permitir conexiones desde contenedores Docker.
Algo así hará el truco:
# iptables -A INPUT -i docker0 -j ACCEPT
Esto permitiría el acceso a cualquier puerto en el host desde los contenedores Docker. Tenga en cuenta que:
-
las reglas de iptables están ordenadas, y esta regla puede o no hacer lo correcto dependiendo de qué otras reglas vengan antes.
-
solo podrá acceder a los servicios de host que (a) escuchan en
INADDR_ANY
(también conocido como 0.0.0.0) o que escuchan explícitamente en la interfazdocker0
.
Creé un contenedor docker para hacer exactamente eso https://github.com/qoomon/docker-host
Luego puede simplemente usar el nombre del contenedor dns para acceder al sistema host, por ejemplo
curl http://dockerhost:9200
Cuando tiene dos imágenes acopladas "ya" creadas y desea colocar dos contenedores para comunicarse entre sí.
Para eso, puede ejecutar convenientemente cada contenedor con su propio nombre - y usar el indicador --link para permitir la comunicación entre ellos. Sin embargo, no obtienes esto durante la construcción de Docker.
Cuando estás en un escenario como yo, y es tu
curl http://172.17.0.1:localPort/fileIWouldLikeToDownload.tar.gz > dump.tar.gz
Eso se rompe cuando intentas
version: ''2.3''
services:
redis:
image: "redis"
extra_hosts:
- "dockerhost:172.20.0.1"
networks:
default:
ipam:
driver: default
config:
- subnet: 172.20.0.0/16
gateway: 172.20.0.1
y te quedas atascado en "curl / wget" y no devuelve ninguna "ruta al host".
La razón es la seguridad establecida por el acoplador que, de forma predeterminada, prohíbe la comunicación desde un contenedor hacia el host u otros contenedores que se ejecutan en su host. Esto fue bastante sorprendente para mí, debo decir, es de esperar que el ecosistema de las máquinas acoplables que se ejecutan en una máquina local pueda acceder sin problemas entre sí sin demasiados obstáculos.
La explicación de esto se describe en detalle en la siguiente documentación.
http://www.dedoimedo.com/computers/docker-networking.html
Se ofrecen dos soluciones rápidas que lo ayudan a moverse al reducir la seguridad de la red.
La alternativa más simple es simplemente apagar el firewall o permitirlo todo. Esto significa ejecutar el comando necesario, que podría ser systemctl stop firewalld, iptables -F o equivalente.
Espero que esta información le ayude.
Descubrimos que una solución más simple para toda esta basura de redes es usar el socket de dominio para el servicio. Si de todos modos está intentando conectarse al host, simplemente monte el zócalo como un volumen y estará en camino. Para postgresql, esto fue tan simple como:
NETWORK ID NAME DRIVER SCOPE
b3554ea51ca3 bridge bridge local
2f0d6d6fdd88 host host local
b9c2a4bc23b2 none null local
Luego, simplemente configuramos nuestra conexión de base de datos para usar el socket en lugar de la red. Literalmente así de fácil.
He explorado varias soluciones y encuentro que esta es la solución menos hacky:
- Defina una dirección IP estática para la puerta de enlace IP del puente.
-
Agregue la puerta de enlace IP como una entrada adicional en la directiva
extra_hosts
.
El único inconveniente es que si tiene varias redes o proyectos haciendo esto, debe asegurarse de que su rango de direcciones IP no entre en conflicto.
Aquí hay un ejemplo de Docker Compose:
docker build -t "centos7/someApp" someApp/
Luego puede acceder a los puertos en el host desde el interior del contenedor utilizando el nombre de host "dockerhost".
Puede acceder al servidor web local que se ejecuta en su máquina host de dos maneras.
-
Enfoque 1 con IP pública
Utilice la dirección IP pública de la máquina host para acceder al servidor web en el contenedor de acopladores Jenkins.
-
Enfoque 2 con la red host
Use "--net host" para agregar el contenedor acoplable Jenkins en la pila de red del host. Los contenedores que se implementan en la pila del host tienen acceso completo a la interfaz del host. Puede acceder al servidor web local en el contenedor acoplable con una dirección IP privada de la máquina host.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a604f7af5e36 ubuntu "/bin/bash" 22 seconds ago Up 20 seconds ubuntu_server
Inicie un contenedor con la red de host.
Eg: docker run --net host -it ubuntu
y ejecute
ifconfig
para enumerar todas las direcciones IP de red disponibles a las que se puede acceder desde el contenedor de docker.
Por ejemplo: inicié un servidor nginx en mi máquina host local y puedo acceder a las URL del sitio web nginx desde el contenedor acoplador de Ubuntu.
docker run --net host -it ubuntu
root@linuxkit-025000000001:/# curl 192.168.x.x -I
HTTP/1.1 200 OK
Server: nginx/1.15.10
Date: Tue, 09 Apr 2019 05:12:12 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 26 Mar 2019 14:04:38 GMT
Connection: keep-alive
ETag: "5c9a3176-264"
Accept-Ranges: bytes
Acceso al servidor web Nginx (que se ejecuta en la máquina host local) desde el contenedor acoplable de Ubuntu con la dirección IP de la red privada.
docker run -v /var/run/postgresql:/var/run/postgresql
Solución con docker-compose: para acceder al servicio basado en host puede usar el parámetro
network_mode
https://docs.docker.com/compose/compose-file/#network_mode
version: ''3''
services:
jenkins:
network_mode: host
Use
--net="host"
en su comando de
docker run
, luego
localhost
en su contenedor de docker apuntará a su host de docker.