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.]+'
docker
docker-container
Tri Nguyen
fuente
fuente
curl: (7) Failed to connect to 172.17.1.78 port 7000: No route to host
Respuestas:
Al ejecutar Docker de forma nativa en Linux, puede acceder a los servicios de host utilizando la dirección IP de la
docker0
interfaz. Desde el interior del contenedor, esta será su ruta predeterminada.Por ejemplo, en mi sistema:
Y dentro de un contenedor:
Es bastante fácil extraer esta dirección IP usando un simple script de shell:
Es posible que deba modificar las
iptables
reglas en su host para permitir conexiones desde contenedores Docker. Algo así hará el truco: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
INADDR_ANY
(también conocido como 0.0.0.0) o que escuchan explícitamente en ladocker0
interfaz.fuente
docker.for.mac.localhost
lugar delocalhost
o127.0.0.1
. Aquí está el doc .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
MacOS con versiones anteriores de Docker
Docker para Mac v 17.12 a v 18.02
Igual que el anterior, pero úsalo
docker.for.mac.host.internal
en su lugar.Docker para Mac v 17.06 a v 17.11
Igual que el anterior, pero úsalo
docker.for.mac.localhost
en su 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 localhost127.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, por lo tanto, 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
fuente
docker.for.mac.localhost
que se resolverá en la dirección IP interna utilizada por el host! ... Lo he probado y en realidad está funcionando! :)ip route show | awk '/default/ {print $3}'
una IP ydocker.for.mac.localhost
otra.host.docker.internal
docs.docker.com/docker-for-mac/networking/…host.docker.internal
en el contenedor docker y la configuración127.0.0.1 host.docker.internal
en el archivo hosts .Use
--net="host"
en sudocker run
comando, luegolocalhost
en su contenedor docker apuntará a su host docker.fuente
network_mode: "host"
Solución con docker-compose: para acceder al servicio basado en host puede usar el
network_mode
parámetro https://docs.docker.com/compose/compose-file/#network_modeEDITAR 2020-04-27: recomendado para usar solo en el entorno de desarrollo local.
fuente
Actualmente, la forma más fácil de hacer esto en Mac y Windows es usar el host
host.docker.internal
, que resuelve la dirección IP de la máquina host. Desafortunadamente, todavía no funciona en Linux (a partir de abril de 2018).fuente
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
fuente
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:
Luego, simplemente configuramos nuestra conexión de base de datos para usar el socket en lugar de la red. Literalmente así de fácil.
fuente
He explorado las diversas soluciones y encuentro que esta es la solución menos hacky:
extra_hosts
directiva.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:
A continuación, puede acceder a los puertos en el host desde el interior del contenedor utilizando el nombre de host "dockerhost".
fuente
Para los sistemas Linux, puede, a partir de la versión principal
20.04
, ahora también comunicarse con el host a través dehost.docker.internal
. Esto no funcionará automáticamente , pero debe proporcionar el siguiente indicador de ejecución:Ver
fuente
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 acoplable Jenkins.
Enfoque 2 con la red host
Utilice "--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.
Inicie un contenedor con la red host
Eg: docker run --net host -it ubuntu
y ejecúteloifconfig
para enumerar todas las direcciones IP de red disponibles a las que se puede acceder desde el contenedor acoplable.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
Acceder al servidor web Nginx (que se ejecuta en la máquina host local) desde el contenedor acoplable de Ubuntu con una dirección IP de red privada.
fuente
Para
docker-compose
usar la red de puente para crear una red privada entre contenedores, la solución aceptadadocker0
no funciona porque la interfaz de salida de los contenedores no lo es,docker0
sino que es una identificación de interfaz generada aleatoriamente, como:Desafortunadamente, esa identificación aleatoria no es predecible y cambiará cada vez que componer tenga que recrear la red (por ejemplo, en un reinicio del host). Mi solución a esto es crear la red privada en una subred conocida y configurarla
iptables
para aceptar ese rango:Redactar fragmento de archivo:
Puede cambiar la subred si su entorno lo requiere. Seleccioné arbitrariamente
192.168.32.0/20
usandodocker network inspect
para ver lo que se estaba creando por defecto.Configure
iptables
en el host para permitir la subred privada como fuente:Esta es la
iptables
regla más simple posible . Es posible que desee agregar otras restricciones, por ejemplo, por puerto de destino. No olvides mantener tus reglas de iptables cuando estés contento de que estén funcionando.Este enfoque tiene la ventaja de ser repetible y, por lo tanto, automatizable. Uso el
template
módulo de ansible para implementar mi archivo de redacción con sustitución de variables y luego uso los módulosiptables
yshell
para configurar y mantener las reglas del firewall, respectivamente.fuente
iptables -A INPUT -i docker0 -j ACCEPT
, pero eso no me ayudó, mientras que loiptables -I INPUT 1 -s 192.168.32.0/20 -j ACCEPT
sugerido aquí resolvió mi problema.Esta es una pregunta antigua y tenía muchas respuestas, pero ninguna de ellas se ajustaba lo suficientemente bien a mi contexto. En mi caso, los contenedores son muy delgados y no contienen ninguna de las herramientas de red necesarias para extraer la dirección IP del host desde el contenedor.
Además, usar el
--net="host"
enfoque es un enfoque muy aproximado que no es aplicable cuando se desea tener una configuración de red bien aislada con varios contenedores.Entonces, mi enfoque es extraer la dirección de los hosts en el lado del host y luego pasarla al contenedor con el
--add-host
parámetro:o guarde la dirección IP del host en una variable de entorno y use la variable más adelante:
Y luego
docker-host
se agrega al archivo de hosts del contenedor, y puede usarlo en las cadenas de conexión de la base de datos o URL de API.fuente
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 --name 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
Eso se rompe cuando intentas
y te quedas atascado en "curl / wget" devolviendo ninguna "ruta al host".
La razón es la seguridad establecida por la ventana acoplable 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 que esperaría que el ecosistema de las máquinas acoplables que se ejecutan en una máquina local simplemente 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.
Espero que esta información le ayude.
fuente
--link
ahora está en desusoPara mí (Windows 10, Docker Engine v19.03.8) fue una mezcla de https://stackoverflow.com/a/43541732/7924573 y https://stackoverflow.com/a/50866007/7924573 .
por ejemplo: LOGGER_URL = " http: //host.docker.internal: 8085 / log "
version: '3.7' services: server: build: . ports: - "5000:5000" network_mode: bridge
o alternativamente: use--net="bridge"
si no está usando docker-compose (similar a https://stackoverflow.com/a/48806927/7924573 )Como se señaló en respuestas anteriores: Esto solo debe usarse en un entorno de desarrollo local .
Para obtener más información, lea: https://docs.docker.com/compose/compose-file/#network_mode y https://docs.docker.com/docker-for-windows/networking/#use-cases-and-workarounds
fuente