Moby: Documente cómo conectarse al host de Docker desde el contenedor

Creado en 5 jul. 2013  ·  263Comentarios  ·  Fuente: moby/moby

Tuve algunos problemas para descubrir cómo conectar el host de la ventana acoplable desde el contenedor. No se pudo encontrar documentación, pero sí se encontraron registros de irc que decían algo sobre el uso 172.16.42.1 , que funciona.

Sería bueno si se documentara este comportamiento y cómo se relaciona con docker0 .

Comentario más útil

Creo que el requisito está claro en el título del problema. Debe haber una manera fácil y bien documentada de comunicarse con el host desde el contenedor, independientemente de cómo se implemente.

Todos 263 comentarios

cuando mira dentro de network.go, encuentra que docker sondea las redes internas que no están enrutadas.

primero 172.16.42.1 se adivina como una dirección de puente y luego otros.

Así que documentar esto no ayudará mucho. Es un esquema dinámico en el que no puede confiar.

Creo que lo que necesita es más una forma de definir las direcciones utilizadas para el puente y el cliente.
¿podría ser eso?

Creo que el requisito está claro en el título del problema. Debe haber una manera fácil y bien documentada de comunicarse con el host desde el contenedor, independientemente de cómo se implemente.

+1 Sería muy bueno tener una buena forma de conectarse al sistema host

+1, la rama 1.0 definirá una API de introspección para que cada contenedor pueda interactuar con el host de forma controlada y con alcance.

Esto está planeado actualmente para 0.8.


@solomonstre
@getdocker

El jueves 8 de agosto de 2013 a la 1:10 p. m., EJ Bensing [email protected]
escribió:

+1 Sería muy bueno tener una buena forma de conectarse al sistema host

Responda a este correo electrónico directamente o véalo en GitHub:
https://github.com/dotcloud/docker/issues/1143#issuecomment-22351792

Entonces, ¿cómo puedo conectarme al host docker desde dentro de un contenedor? Estoy tratando de conectarme a un contenedor docker a través del puerto de host en lugar de la IP privada del contenedor.

@gerhard : se planea una API de introspección para 0.8. Mientras tanto, si desea acceder a la API de Docker desde los contenedores, puede configurar Docker para escuchar en la dirección IP del puente de Docker.

Para hacer eso, harías lo siguiente:

  • crear un puente

ip link add docker0 type bridge

  • asignarle una dirección IP

ip link set docker0 up
ip addr add 172.17.0.1/16 dev docker0

  • inicie la ventana acoplable y vincule la API al puente

docker -d -H 172.17.0.1:4242

Ahora puede acceder a la API de Docker desde sus contenedores.

Actualmente (versión 0.7), la ventana acoplable no admite de manera confiable la concesión de acceso ilimitado a su propio socket de control a uno de sus contenedores. Las soluciones alternativas explicadas en este hilo son trucos que no se garantiza que funcionen y, si lo hacen, podrían romperse en cualquier momento; no los use en producción ni espere que los apoyemos. Dado que no hay una característica oficial para documentar, este problema de documentación no se puede solucionar.

Para discutir trucos y soluciones para las funciones que faltan, recomiendo la lista de correo _docker-user_ o el canal _#docker_ irc en Freenode.

piratería feliz

@shykes ¿Hay otro problema que rastree la creación de tal función, en ese caso?

Por cierto, para motivar esta característica: esto es útil cuando se prueba localmente un servidor (donde hubiera usado vagrant en el pasado) y quiero conectar un servidor en el contenedor a una base de datos u otro servidor que se ejecuta en mi máquina de desarrollo (el host docker).

Ya estoy convencido del valor de esta función :)

El lunes 2 de diciembre de 2013 a las 9:09 a. m., Caleb Spare [email protected]
escribió:

Por cierto, para motivar esta característica: esto es útil cuando se prueba localmente un servidor (donde hubiera usado vagrant en el pasado) y quiero conectar un servidor en el contenedor a una base de datos u otro servidor que se ejecuta en mi máquina de desarrollo (el host docker).

Responda a este correo electrónico directamente o véalo en GitHub:
https://github.com/dotcloud/docker/issues/1143#issuecomment-29636528

Estoy en Fedora 20 con docker 0.7.2, configurando la interfaz de usuario de Docker . Tuve que abrir el puerto en el que escucha el demonio docker para que el firewall no lo bloquee:

  • firewall-cmd --permanente --zone=de confianza --add-interface=docker0
  • firewall-cmd --permanente --zone=de confianza --add-port=4243/tcp

Después de eso, _docker-ui_ pudo conectarse al socket de control del demonio docker.

HTH
Esta es una necesidad clara y legítima de tal característica.

Lo siento, si estoy manteniendo vivo un hilo duro.

El título de este problema dice: "Cómo conectarse al host desde el contenedor docker".
No veo cómo se relaciona esto con la función docker inspect . La función de inspección se usa en el lado del host para encontrar la IP del contenedor, si no me equivoco.

Creo que el problema de bkad es encontrar la IP del host desde dentro del contenedor. De acuerdo, no soy un asistente de redes, pero no es bastante seguro asumir que la puerta de enlace IP (desde el interior del contenedor) se asigna al host.
(Suponiendo que uno no configure una configuración de puente o algo así).

Al usar la puerta de enlace por 0.0.0.0 desde netstat -nr , ciertamente no tuve problemas para acceder a un servidor que se ejecuta en mi máquina host. Sospecho que la IP de la puerta de enlace es estática (una vez que se inicia la ventana acoplable), ¿alguien puede confirmarlo?

Una alternativa sería pasar la IP pública de mi host al contenedor usando variables de entorno, pero la IP pública puede no ser estática. Y aunque el nombre de host puede funcionar mejor en producción, son difíciles de usar localmente.

Todavía preferiría una forma de llamar desde el contenedor docker al host a través del loopback y aparecer como 127.0.0.1 en el host. O si la seguridad es una preocupación, otro dispositivo loopback que siempre tenga la misma ip.
¿O tal vez lo que encontré no expone mi comunicación al público? Como dije, no soy un mago de la red :)
Tenga en cuenta que si usar ip-gateway para llamar al host docker es la "manera correcta", ¿no podemos documentarlo?

Para aquellos que buscan encontrar la IP de la puerta de enlace del contenedor /proc/net/route es probablemente el lugar adecuado para leerlo.

La Motivación , para esta característica incluye varios servicios de metadatos. Sería bueno exponer cosas del servicio de metadatos ec2. Distribución de credenciales y datos estructurados más complejos que no encajan en las variables de entorno.

@jonasfj : en realidad hay una manera más fácil, ahora que Docker admite archivos de montaje de enlaces desde el host al contenedor. Puede enlazar el zócalo de control de Docker, es decir: docker run -v /var/run/docker.sock:/var/run/docker.sock … ; esto es más fácil que jugar con las reglas de red.

No estoy seguro de cómo ayuda el zócalo de la ventana acoplable. Sigo pensando que el problema debe reabrirse, no hay documentación para el siguiente escenario:

1) En el 'host', un servicio se ejecuta en el puerto 8080 (digamos 'etcd')
2) Desde ese host se inicia un contenedor docker
3) ¿Cómo se puede acceder al servicio en el puerto 8080 en el host desde el contenedor docker? ¿Cuál sería la URL/IP?

@jpetazzo ¿Cómo entra en juego la configuración de docker.sock para resolver el problema anterior?

@vrvolle , exponer docker.sock no resuelve el problema original descrito por @bkad.
Pero uno expondría un socket de dominio Unix diferente para la comunicación entre el host y el contenedor docker.

Por ejemplo, si quisiera exponer mysql desde el host, expondría el socket de mysql: /tmp/mysql.sock .

O si le gusto, tiene una API de metadatos a través de la cual los contenedores deberían poder consultar el host en busca de varias cosas útiles, cree su propio socket de dominio Unix y expóngalo al contenedor. HTTP sobre sockets de dominio unix debería funcionar muy bien. Además, no tiene todos los problemas de configuración de red y problemas de seguridad.

solo tenía que leer sobre 'sockets de dominio unix'.
pero:

http://stackoverflow.com/questions/14771172/http-over-af-unix-http-connection-to-unix-socket

afirma que no hay URL y, por lo tanto, ningún cliente habitual puede usar ese mecanismo de forma inmediata.

Por otro lado:

http://stackoverflow.com/questions/14771172/http-over-af-unix-http-connection-to-unix-socket

muestra que de alguna manera es posible usar tal socket.

Pero aún así me gustaría poder tener una dirección IP y un puerto, que un programa dentro de una ventana acoplable podría usar. Yo, por ahora, usaré

 netstat -nr | grep '^0\.0\.0\.0' | awk '{print $2}'

¿Debo crear un nuevo problema o alguien puede reabrir este?

@vrvolle
No soy un tipo de redes, pero imagino que hay algunos trucos que se pueden hacer para enviar un proxy localhost al contenedor a través de un socket Unix y luego dentro del socket UNIX del proxy del contenedor al host local de contenedores (dispositivo de bucle invertido)...

Sería bueno documentar cómo hacerlo. Pero parece que no es necesariamente una función que la ventana acoplable necesita para soporte activo.

Hay varias formas de abordar eso, dependiendo de lo que quieras lograr exactamente.

Si desea conectarse a un servicio que se ejecuta en el host (cualquier tipo de servicio, por ejemplo, alguna API o base de datos que se ejecutaría directamente en el host), debe averiguar la dirección IP del host.

Una forma es confiar en el hecho de que se puede acceder al host Docker a través de la dirección del puente Docker, que resulta ser la puerta de enlace predeterminada para el contenedor. En otras palabras, un análisis inteligente de ip route ls | grep ^default podría ser todo lo que necesita en ese caso. Por supuesto, se basa en un detalle de implementación (la puerta de enlace predeterminada es una dirección IP del host de Docker) que podría cambiar en el futuro.

Otra forma es usar la API de Docker para recuperar esa información. Entonces, el problema se convierte en "¿cómo me conecto a la API de Docker desde un contenedor?", y una posible solución (¡utilizada por muchos, muchos contenedores!) es unir-montar /var/run/docker.sock desde el host a El contenedor. Esto tiene una gran desventaja: la API está disponible en su totalidad para el contenedor, lo que podría causarle problemas.

A largo plazo, Docker expondrá una mejor API de introspección, lo que permitirá acceder a esa información sin ceder demasiados privilegios a los contenedores.

TL, DR: a corto plazo, verifique la ruta predeterminada del contenedor. A largo plazo, habrá una API de introspección impresionante.

También tengo un problema debido al advenedizo. no puedo encontrar nada en /var/run/docker.sock. y usé el comando "-v /etc/run/docker.sock:/etc/run/docker.sock" pero no pasó nada.
Creo que es un problema debido a algunas actualizaciones nuevas sobre las capacidades del kernel. por favor, dame una breve nota sobre este tema. y comando completo para resolver esto. Gracias

use -v /var/run/docker.sock - no /etc (que normalmente está reservado para archivos conf).

alguna actualización sobre esto en la nueva versión 1.0.0?

Hay nsenter, pero creo que la forma recomendada es ejecutar sshd en este
escenario.

El viernes 13 de junio de 2014, Camilo Aguilar [email protected] escribió:

alguna noticia sobre esto en la nueva versión 1.0.0?


Responda a este correo electrónico directamente o véalo en GitHub
https://github.com/dotcloud/docker/issues/1143#issuecomment-45958769 .

Michael D. Neale
Inicio: www.michaelneale.net
blog: michaelneale.blogspot.com

vrvolle, gracias por eso. Mucha gente como nosotros está buscando un pequeño detalle como este.

netstat -nr | grep '^0\.0\.0\.0' | awk '{print $2}'

La actualización automática de Docker /etc/hosts en cada contenedor con la IP del host, por ejemplo, 172.17.42.1 y llamarlo, por ejemplo dockerhost sería una solución conveniente.
Supongo que por ahora estamos atrapados con netstat -nr | grep '^0\.0\.0\.0' | awk '{print $2}'

+1 por dockerhost en /etc/hosts

+1 para dockerhost en /etc/hosts, suena como una buena idea

La edición de un archivo en una imagen nunca debe realizarse A MENOS QUE proporcione específicamente un argumento o un indicador para hacerlo. Además, no es obligatorio que el 100% de las imágenes sigan el LSB, por lo que es posible que ni siquiera haya un directorio /etc . El nombre de archivo que se usará para contener la IP del host también debe especificarse mediante el argumento del comando.

docker --host /etc/hosts

+1 para dockerhost en /etc/hosts

+1 para una entrada /ec/hosts

@Sepero docker ya está completando /etc/hosts con los contenedores vinculados, por lo que sus argumentos realmente no se sostienen.

@matleh Eso es cierto, pero creo que la forma correcta no es llenar/etc/hosts directamente, o al menos dejarnos especificar la ubicación en caso de que no la tengamos.

De todos modos, la entrada de dockerhost en hosts.

También me gustaría tener la IP del host docker en /etc/hosts .

+1 en la IP del host docker en /etc/hosts

Quizás una mejor manera de facilitar el acceso a los servicios de red en el host sería facilitar la configuración de las entradas de iptables que reenvían los puertos a la inversa, es decir, desde el contenedor al host. Creo que la opción -p o --publish se complementaría muy bien con una opción -s o --subscribe que tiene el efecto inverso. Sin embargo, supongo que los habría llamado --hacia delante y --hacia atrás. Como sea que lo llames, este me parece un enfoque mucho más consistente que las otras sugerencias aquí.

Esto podría ser obvio, pero una forma simple de hacer esto que funciona actualmente y quizás depende menos de la implementación sería determinar la dirección IP en el host antes de iniciar el contenedor y establecer una variable de entorno en el contenedor de manera adecuada. A lo largo de estas líneas:

#!/bin/bash
HOSTNAME=$(hostname)
HOST_IP=$(ip route | awk '/docker/ { print $NF }')
docker run -e HOST=$HOSTNAME -e HOST_PORT=tcp://$HOST_IP:8000 mycontainer

Esto sería esencialmente paralelo a la forma en que funciona --link . Todavía depende de que el puente tenga un nombre que coincida con /docker/ y que solo haya uno de esos puentes, pero el puente se establece cuando se inicia el demonio docker. Sería bueno si docker info nos diera el nombre del puente en uso y/o la dirección IP del host. Otro pensamiento sería agregar una opción --link-host PORT a docker run que haría esencialmente lo anterior.

En mi opinión, esta es la mejor opción. Con --link-host , el contenedor no necesitaría saber si el servicio al que accede está en el host o en otro contenedor.

No estoy seguro de cómo otros están invocando sus contenedores, pero cuando los ejecuto con --net=host , puedo ver la misma configuración de red que mi host docker. Sin este conmutador, obtengo una pila de red independiente, como se describe en las páginas man docker-run .

$ docker run -i --net=host fedora ip route ls
default via 10.0.2.2 dev eth0  metric 1
10.0.2.0/24 dev eth0  proto kernel  scope link  src 10.0.2.15
127.0.0.1 dev lo  scope link
172.17.0.0/16 dev docker0  proto kernel  scope link  src 172.17.42.1
192.168.59.0/24 dev eth1  proto kernel  scope link  src 192.168.59.103

ejecutar sin el interruptor produce esto:

$ docker run -i fedora ip route ls
default via 172.17.42.1 dev eth0
172.17.0.0/16 dev eth0  proto kernel  scope link  src 172.17.0.4

Lo que estamos buscando es un método para obtener la dirección IP de 10.0.2.15 (la IP del eth0 i/f de mi docker host) o 172.17.42.1 (la IP del docker0 bridge i/f de mi docker).

No me importa especialmente el enfoque de agregar algún host a mi archivo de contenedores /etc/hosts, eso me parece un poco raro. En lugar de tener esta información expuesta internamente para que pueda obtenerla cuando sea necesario, parecería ser la forma más prudente de hacerlo aquí.

+1 por --link-host o alguna otra forma intuitiva

+1 para una entrada de /etc/hosts
Parece bastante conveniente y sigue las convenciones de comunicación actuales.

Solo para aclarar mis comentarios anteriores: lo bueno de --link <container>:<alias> es que expone un _servicio_ a través de un _alias_. De manera similar, un mecanismo para exponer el host al contenedor debe proporcionar acceso a un servicio específico, no solo a una dirección IP. El contenedor accedería a ese servicio a través de un alias; no debería necesitar saber dónde está realmente el servicio. La opción debe tener la semántica inversa de -p y comportarse como --link . En otras palabras --link-host <ip address>:<port>:<alias> configuraría variables env y una entrada /etc/hosts , y configuraría entradas de iptables según sea necesario, es decir, si el servicio en el host está escuchando en una dirección IP que de otro modo sería inaccesible al contenedor.

@altaurog ¿Qué tal algo así?

docker run --name someservice -d host-exposing-image --expose 8000

someservice sería simplemente cualquier nombre al que luego pueda --link , y host-exposing-image sería una imagen especial que reenvía puertos de host en puertos expuestos. Probablemente la idea sería implementable al compartir el /var/run/docker.sock del host con la imagen.

Quizá ya exista algo así, no sé.

Editar:

docker run --name someservice -d --expose 8000 host-exposing-image

Olvídese de lo anterior, no he leído todos los comentarios aquí (todavía no lo hice). Esto es lo que funciona para mí en docker-osx (y perdón por no publicar en la lista de correo):

docker run --rm -ti -e HOST_IP="$(docker-osx ssh -c 'route -n' 2> /dev/null |
  awk '/^0.0/ { print $2 }')" debian:jessie

+1. --link-host es una buena idea además de tener una entrada dockerhost en /etc/hosts

Creé un nuevo problema ya que este problema está cerrado (pero no resuelto): #8395

+1 por dockerhost o cualquier otra forma conveniente.

+1 para cualquier forma conveniente

Como el enfoque dockerhost obtuvo algunos votos aquí, la forma más fácil que encontré (desde los comentarios hasta los 3 problemas relacionados #8395 #10023) para tener una entrada de hosts de este tipo es agregar el argumento --add-host=dockerhost:$(ip route | awk '/docker0/ { print $NF }') al ejecutar la imagen, por ejemplo:

run --add-host=dockerhost:$(ip route | awk '/docker0/ { print $NF }')  ubuntu ping -c2 dockerhost

Si bien esto agrega la entrada requerida de /etc/hosts, es una pena que dockerhost no esté allí de manera predeterminada. Al distribuir una imagen, tengo la opción de

  • indicar a los usuarios que agreguen el parámetro anterior
  • haga algunos scripts ejecutándose en el contenedor que adapten los archivos de configuración en función de la tabla de enrutamiento

Personalmente, no entiendo por qué dockerhost no está ahí de forma predeterminada, haría que la creación y distribución de imágenes que acceden a los servicios normalmente en el host (XServer, CUPS, Puleaudio) sea mucho más conveniente.

+1 para docker host. De hecho, expondría esto como una entrada var env, /etc/hosts y un indicador cli. Está destinado a ser utilizado de muchas maneras.

:+1: para docker host

dentro de su contenedor:

cat << EOF > /etc/profile.d/dockerhost.sh
 grep dockerhost /etc/hosts || echo $(ip r ls | grep ^default | cut -d" " -f3) dockerhost >> /etc/hosts
EOF

funciona para mí cada vez que inicio sesión (con cuenta raíz)

+1 para docker host

+1 para docker host

+1 para docker host

+1 para docker host

+1 para dockerhost :yum:

+1 para docker host

+1 para dockerhost :+1:

Terminé escribiendo este script, alguien podría encontrarlo útil:

#!/bin/bash

SED="$(which sed)"
NETSTAT="$(which netstat)"
GREP="$(which grep)"
AWK="$(which awk)"
CAT="$(which cat)"


$SED '/dockerhost$/d' /etc/hosts > /etc/hosts.tmp
DOCKERHOST="$($NETSTAT -nr | $GREP '^0\.0\.0\.0' | $AWK '{print $2}')"

echo "$DOCKERHOST dockerhost" >> /etc/hosts.tmp

$CAT /etc/hosts.tmp > /etc/hosts

rm -rf /etc/hosts.tmp

+1 docker host

Como hay bastante interés en este tema, creo que tendría sentido abrir una nueva solicitud de función en lugar de discutir un ticket cerrado.

Abrí https://github.com/docker/docker/issues/8395 hace algún tiempo, también lo cerré. Todavía no hay una solución documentada

Bien, aunque hay soluciones alternativas, creo que la razón principal es probablemente que acceder al host es un caso de uso parcialmente aislado.

Como hay una función de enlaces acoplables, creo que tiene sentido poder proporcionar un enlace al host.

¡Hola!

FYI esto ahora está documentado :

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

Gracias, @icecrime.

¿Puede una persona acoplable bloquear este problema para que la gente deje de actualizarlo?

+1 para docker host

+1 para dockerhost: tener que ejecutar un comando local alias hostip no es compatible con, por ejemplo, docker-compose, docker-swarm, etc., etc.

+1 para docker host

@icecrime , eso da la puerta de enlace del host y no la IP del host en mi ubuntu. ¿No debería ser solo el siguiente comando?

$ ip address show

+1, algo utilizable sin tener que ejecutar comandos sería ideal

¿Cómo es que esto sigue sin resolverse? Ejecutar comandos en un contenedor para hacer que el contenedor funcione como red de host es completamente inaceptable.

+1 para cualquier cosa simple
Por cierto, la solución con ip funciona en mi Ubuntu, pero no funciona en OS X, ¿verdad?

+1 Este es un problema de 2 años y una característica útil. Quiero una manera fácil de conectarme a la API remota de Docker desde dentro de un contenedor.

@iannidress si tiene su daemon configurado para aceptar conexiones de socket, simplemente monte el socket en su contenedor, por ejemplo, docker run -d -v /var/run/docker.sock:/var/run/docker.sock myimage

+1 para docker host
Encontré este problema al buscar soluciones para el caso de uso: xdebug.remote_host=dockerhost

+1 para docker host

@thaJeztah y ¿cómo llego al nombre de host o la dirección IP desde allí?

@mbonaci Estaba respondiendo a @iannidress , que quería conectarse a la API de Docker dentro de un contenedor (para el cual usar una conexión de socket es el enfoque general)

Estoy confundido. @icecrime dijo anteriormente que esto ahora está documentado, pero el enlace que dio está muerto. No puedo encontrar rápidamente la parte citada de la documentación. Observo que el ejemplo de apt-cache-ng usa dockerhost, pero no define qué es (#11556). La única referencia que pude encontrar fácilmente fue este hilo. He buscado en todas las fuentes y documentación de Docker y no parece mencionarse en este contexto .

@pwaller Desde marzo, hemos dividido ese enorme documento largo en referencias separadas. La nueva ubicación de este material es:

http://docs.docker.com/reference/commandline/run/#adding-entries-to-a-container-hosts-file

+1 para docker host

@moxiegirl Creo que el parámetro --add-host es satisfactorio. Gracias

¿Y cómo conectarse al host desde el contenedor docker? Por ejemplo, para hacer que git pull? Sin volúmenes usando?

@a93ushakov todo se explica en el enlace que proporcionó @moxiegirl .
Cuando esté haciendo docker run , agregue el siguiente parámetro: --add-host=dockerhost:replace_with_docker_host_ip , que crea una entrada en el archivo /etc/hosts del contenedor.
Lo que, por supuesto, significa que puede hacer referencia a su host docker desde dentro de ese contenedor usando su nombre, dockerhost .

@mbonaci > Lo que, por supuesto, significa que puede referirse a su docker host desde ese contenedor usando su nombre, dockerhost.

A través de ssh?

@thaJeztah > si tiene su daemon configurado para aceptar conexiones de socket, ...
¿Como hacer esto?

@a93ushakov SSH: si lo tiene instalado y ejecutándose en el host (y su puerto no está bloqueado), sí.

@a93ushakov @thaJeztah se refiere a la conexión de socket Unix. Creo que ese es el valor predeterminado: vea si tiene un archivo /var/run/docker.sock en su host.

+1 para docker host

+1 para docker host

+1 para docker host

+1 para docker host
Sería bueno obtener este nombre de host sin ningún paso adicional.

1 para docker host

+1 por dockerhost

Parece que no se puede conectar al host de la ventana acoplable desde dentro de un contenedor. ¿Alguna idea de lo que estoy haciendo mal?

$ hostip=$(ip route show 0.0.0.0/0 | grep -Eo 'via \S+' | awk '{ print $2 }')
$ nc -l -p 1234 &
[1] 17361
$ docker run --add-host=docker:$(hostip) --rm -it hiromasaono/curl curl docker:1234
curl: (7) Failed to connect to docker port 1234: Connection refused

+1 para docker host

Cuando agrego la IP del puente Docker, funciona.

Primera escucha en el puerto 1234 con netcat

$ nc -l -p 1234

Obtener la IP del puente

$ ifconfig docker0 | grep 'inet addr'
          inet addr:172.17.42.1  Bcast:0.0.0.0  Mask:255.255.0.0

Luego conecta

$ docker run --add-host=docker:172.17.42.1 --rm -it hiromasaono/curl curl 172.17.42.1:1234

Entonces veo la respuesta.

GET / HTTP/1.1
User-Agent: curl/7.35.0
Host: 172.17.42.1:1234
Accept: */*

+1 para docker host
Diablos, ¿cuándo?

+1 para dockerhost que también funciona en Mac, es decir, maneja la máquina virtual de forma transparente

¿Podría alguien decirme cómo llamaré a la API de Docker desde dentro del contenedor? No soy un tipo de Linux. Ya comencé el contenedor con -v /var/run/docker.sock:/var/run/docker.sock.
Todos están hablando de cómo hacer el montaje, pero nadie ha mencionado cómo llamar a la API interna.

Intenté llamar usando curl pero no funcionó. Usé la IP del host, por ejemplo

curl -XGET http://hostip :2375/images/json

Así es como comencé mi daemon. es decir, ventana acoplable -H unix:///var/run/docker.sock -H tcp://0.0.0.0 :2375

Cualquier ayuda será apreciada.

@jprogn el rastreador de problemas de github no está diseñado para preguntas generales de soporte; es mejor hacer estas preguntas en el canal IRC #docker, el grupo de usuarios de docker en Google o forums.docker.com

Esta pregunta está relacionada con el tema original, que no ha sido respondido completamente. Por favor, vea el título de arriba

¿Puede alguien responder cómo llamar a la API de la ventana acoplable dentro del contenedor?????????????

@jprogn , siga mi comentario anterior; este es un rastreador de problemas, utilizado para rastrear errores y solicitudes de funciones; no es un foro de soporte para usar docker; use los otros métodos que mencioné anteriormente https://github.com/docker/docker/issues/1143#issuecomment -146924892

+1 para docker host

En mi host acoplable CentOS7, no puedo obtener una ruta desde el contenedor hasta el host:

[root@docker-host-fkb slehmann]# ifconfig docker0 | grep 'inet'

inet 172.17.42.1  netmask 255.255.0.0  broadcast 0.0.0.0
inet6 fe80::42:a7ff:fe4d:4cb2  prefixlen 64  scopeid 0x20<link>


[root@docker-host-fkb slehmann]# docker run --add-host=docker:172.17.42.1 --rm -it hiromasaono/curl curl 172.17.42.1:1234

curl: (7) Failed to connect to 172.17.42.1 port 1234: No route to host

¿Algunas ideas?

+1, puede haber una variable de entorno para esto.

A mí mismo me gustaría que fuera al revés; un enlace de mi máquina host a los contenedores docker por nombre

+1 para la variable de entorno dockerhost

Es realmente complicado combinar una entrada DNS personalizada que acceda al host sin codificar 172.17.42.1. p.ej

extra_hosts:
     - "docker:172.17.42.1"

+1 para dockerhost donde sea (/etc/host de ENV)

¡+1 esto todavía es necesario!

mi +1 también porque agregar ip route list dev eth0 | grep -Eo 'via \S+' | awk '{ print \$2 }' a cada proyecto (porque en desarrollo, todos los proyectos están en el mismo host y deben poder llamarse entre sí) está empezando a parecer un mal truco

¿Cómo resolvemos este problema en un clúster, por ejemplo, Docker Swarm, donde no sabemos a qué máquina se asignará un contenedor cuando lo ejecutemos? La IP de la puerta de enlace docker0 podría ser diferente de un host a otro dentro del clúster de enjambre, por lo que no podemos simplemente ejecutar el comando ip route en un host y luego asumir que la IP es la misma para todos los hosts.

También me gustaría poder asignar un puerto de contenedor a un puerto en el puente docker0 sin tener que saber cuál es la IP del puente docker0. Algo como esto:

eval $(docker-machine env --swarm swarm-master-node)
docker run -d -p "$HOST_GATEWAY_IP:80:80" my-image

$HOST_GATEWAY_IP se reemplaza con la misma IP que obtendría al ejecutar el comando ip route en el host en el que finalmente se implementa el contenedor en el clúster.

Esto debería ser compatible con cualquier otro comando que involucre IP, por ejemplo, la opción --dns en docker run .

Encontré este comando para ser más fácil:

ip ro | grep docker | sed 's|.* \(\([0-9]\+\(.[0-9]\+\)\{3\}\)\)\s*|\1|'

+1 para dockerhost en /etc/hosts

+1 docker host

+1 por tener dockerhost en /etc/hosts

+1000 para docker host

+1 docker host

+1

+1, o más.

Estoy ejecutando un servidor web en un contenedor y necesito conectarlo a mi mysql que se ejecuta en el host.
La ip del host cambia con dhcp, por lo que algo dinámico es imprescindible.

@wederbrand, un enfoque alternativo (y probablemente con mejor rendimiento) podría ser conectarse al socket mysql, por ejemplo;

docker run -v /var/lib/mysql/mysql.sock:/mysql.sock mywebapp

Eso haría que el socket MySQL estuviera disponible como /mysql.sock dentro del contenedor

@thaJeztah Esa podría ser una opción. Sin embargo, la imagen de la ventana acoplable que estoy usando también se usa para otros entornos donde el servidor mysql está en un servidor remoto y la imagen tiene una configuración para host: puerto para la base de datos.

Me gustaría que mi contenedor se comporte lo más cerca posible del que está en producción, así que no juegue con las propiedades de conexión, excepto para configurar el host y el puerto.

+1

+1

+1

+1

@peterbollen @radek1st @BradRuderman @aldarund @wederbrand @pataiadam @jllado @geniousphp @coreylenertz @dgtlmoon @xlight (todos +1 solo en diciembre de 2015)
_este_ problema está cerrado al igual que #8395
No creo que agregar +1 a un problema anterior ayude. Cree uno nuevo (lo hice con el n.° 8395) o intente alguna otra ruta para solucionar este problema.

¡Gracias!

+1

+1 docker host

+1 para docker host

+1 para docker host

+1 para dockerhost, vamos...

+1 para docker host

el uso de docker-compose y el escalado de contenedores n-arios en un enjambre naturalmente no proporciona un medio para realizar búsquedas de direcciones IP de nodo sobre la marcha en todas las máquinas.

Esto, como se indicó anteriormente y se modificó a la puerta de enlace, no es una opción:

extra_hosts:
     - "docker:172.18.0.1"

👍 para dockerhost también...

+1 para docker host

+1

+1

+1

+1 docker host

+1 docker host

+1 docker host

+1 para docker host

+1 para docker host

+1 para docker host.
Ya que este tema se cierra abriendo un nuevo ticket.

+1

+1

Para obtener el host en una configuración docker-machine , puede usar este comando:

docker-machine ssh "${DOCKER_MACHINE_NAME}" 'echo ${SSH_CONNECTION%% *}'

Informa la máquina a la que se conecta a través ssh , por lo que debería funcionar razonablemente bien tanto para máquinas locales como remotas, siempre que no haya NAT en el camino. Sería bueno si docker-machine inspect informara este valor en alguna parte también, si eso es técnicamente factible.

+1

+1 para docker host. Suena como una característica valiosa con prácticamente ningún esfuerzo para implementar.

Por ahora, si necesita acceder a dockerhost dentro de contenedores creados a partir de imágenes que controla, puede agregar esta esencia al script entrypoint.sh para su imagen: https://gist.github.com/dimitrovs/493678fd86c7cdf0c88312d9ddb4906b

O supongo que puede agregarlo a /etc/rc.local si su imagen no usa un script de shell como punto de entrada. Lo que hace esta esencia es verificar dockerhost en /etc/hosts y agregarlo si no está allí. Debería suceder cada vez que se inicia el contenedor.

Obtenga la IP de la puerta de enlace de /proc/net/route:

export ipaddr=$(printf "%d." $(
  echo $(awk '$2 == "00000000" {print $3}' /proc/net/route) | sed 's/../0x& /g' | tr ' ' '\n' | tac
  ) | sed 's/\.$/\n/')

@dimitrovs ¿Puedes mostrar una configuración de ejemplo? Jugué con eso y no pude obtener los resultados correctos.

¿Qué resultados obtuvo @amcdnl ? Puede colocar la esencia que vinculé en el archivo entrypoint.sh para que se ejecute cada vez que se inicia el contenedor o en /etc/rc.local dentro del contenedor. Tendrá que hacer esto cuando esté creando la imagen, pero el script en sí se ejecutará cuando se inicie un contenedor.

+1 para el host acoplable

@dimitrovs Terminé escribiendo un script que generaría una composición en tiempo de ejecución.

StartDocker.sh

#!/bin/bash
built_docker_file="docker-compose.dev.built.yml"

rm -rf docker-compose.dev.built.yml
localhost_ip="$(ifconfig en0 inet | grep "inet " | awk -F'[: ]+' '{ print $2 }')"
sed -e "s/\${localhost}/$localhost_ip/" docker-compose.dev.template.yml > $built_docker_file

docker-compose -f $built_docker_file build
docker-compose -f $built_docker_file up

ventana acoplable-compose.dev.template.yml

version: '2'

services:
  nginx:
    container_name: sw_nginx
    image: nginx:latest
    ports:
      - 80:80
    links:
     - search
    volumes:
      - ./Web/wwwroot:/var/www/public
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    extra_hosts:
      - "dockerhost:${localhost}"

@amcdnl Buena solución. Tenga en cuenta que docker-compose admite la sustitución de variables (entorno).

por ejemplo (bash):

$ export localhost=$(...)
$ docker-compose (...)

@sebastiannm , mi sugerencia debería ser independiente del host porque se ejecuta dentro de la imagen de la ventana acoplable, pero si lo está ejecutando en Mac en VirtualBox, la IP que obtendrá es la IP de VirtualBox VM, no la IP de su Mac. Creo que este es el requisito que estamos discutiendo. Si desea conocer la IP de Mac desde dentro de una instancia de Docker, se necesita un enfoque diferente.

+1 para docker host.

Pero por ahora, estoy haciendo un truco similar al publicado anteriormente, que te permite obtener dinámicamente la dirección IP del host con un script simple que funciona tanto en Linux como en OSX : http://stackoverflow.com/questions/24319662/from-inside -de-un-contenedor-docker-cómo-me-conecto-al-host-local-de-mach#38753971

+1 para docker host.

+1 para docker host

+1+1 alojamiento acoplable

+1 para docker host

+1 para docker host

+1 para docker host

No puedo conectarme a un servidor host netcat básico desde dentro de un contenedor docker cuando --net=bridge (predeterminado) a través de las diversas técnicas discutidas en este número.

@frankscholten No puedo reproducir su prueba exitosa de netcat

Hice un problema de stackoverflow que describe el problema exacto: http://stackoverflow.com/questions/38936738/communicate-to-docker-host-from-docker-container
y quería publicar aquí en caso de que ayude a alguien en el futuro

Si bien todo esto habla sobre la comunicación desde el contenedor al host usando docker0 ip en modo puente, quiero saber si el contenedor también puede comunicarse con la ip pública del host (digamos, su eth0 ip original). Agradezco su respuesta. No he tenido éxito en esto.

@sburnwal No veo por qué no podría comunicarse con la ip eth0 del host. El contenedor enviará una solicitud a su puerta de enlace predeterminada (docker0) y el host debe responder sin más reenvíos porque sabe que tiene la ip. ¿Sus pings a la ip eth0 desde el contenedor se agotan o no obtiene una ruta al host o qué está sucediendo? ¿Puede el contenedor conectarse a Internet?

Desafortunadamente, esto no funciona para mí. Si bien puedo hacer ping a la IP del contenedor desde el host, no puedo hacer ping a la IP del host (LAN/eth0 del host) desde el contenedor. Estoy usando la ventana acoplable 1.9.1. Estoy atascado aquí porque necesito que mi contenedor se comunique con el servidor web escuchando solo en la ip eth0 del host.

Personalicé docker0 usando la opción:
/bin/demonio docker --bip=169.254.0.254/24 --fixed-cidr=169.254.0.0/24

Así que tengo estas interfaces en mi host (no se enumeran las interfaces veth* aquí):

[root@pxgrid-106 irf]# ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtg 1500
        inet 169.254.0.254  netmask 255.255.255.0  broadcast 0.0.0.0
        inet6 fe80::42:84ff:fe87:d510  prefixlen 64  scopeid 0x20<link>
        ether 02:42:84:87:d5:10  txqueuelen 0  (Ethernet)
        RX packets 512  bytes 150727 (147.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 653  bytes 281686 (275.0 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtg 1500
        inet 172.23.166.176  netmask 255.255.255.128  broadcast 172.23.166.255
        inet6 fe80::20c:29ff:fecc:7d0f  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:cc:7d:0f  txqueuelen 1000  (Ethernet)
        RX packets 58462  bytes 12056152 (11.4 MiB)
        RX errors 0  dropped 69  overruns 0  frame 0
        TX packets 30877  bytes 18335042 (17.4 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Mi contenedor tiene la IP 169.254.0.2 y puedo hacer ping a esta IP del contenedor desde el host. Por supuesto, puedo hacer ping desde el contenedor a su puerta de enlace 169.254.0.254 (docker0 ip) pero no puedo hacer ping al host eth0 ip 172.23.166.176.

Intenté detener por completo el cortafuegos y agregué estas reglas explícitas también al cortafuegos en la cadena de ENTRADA, pero todavía no tuve suerte. ¿Quién me puede ayudar en esto? ¿O es esto un error?

ACCEPT     all  --  172.23.166.176       169.254.0.0/24      
ACCEPT     all  --  169.254.0.0/24       172.23.166.176   

Además, permítanme también dar la salida 'ip route' en mi host:

[root@pxgrid-106 bin]# ip route
default via 172.23.166.129 dev eth0 
169.254.0.0/24 dev docker0  proto kernel  scope link  src 169.254.0.254 
172.23.166.128/25 dev eth0  proto kernel  scope link  src 172.23.166.176 

@tn-osimis gracias por la sugerencia, actualicé y funciona bien, aquí está mi código para otros:

docker-compose.yml

version: '2'

services:
  nginx:
    image: nginx:latest
    ports:
      - 80:80
    volumes:
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
    extra_hosts:
      - "dockerhost:${localhost_ip}"

StartDocker.sh

#!/bin/bash
dev_docker_file="docker-compose.yml"

export localhost_ip="$(ifconfig en0 inet | grep "inet " | awk -F'[: ]+' '{ print $2 }')"

docker-compose -f $dev_docker_file build
docker-compose -f $dev_docker_file up

+1 para docker host

+1 para docker host

+1 para docker host

La solución de @magicalbob es realmente mágica 🎉

+1 para docker host

+1, por cierto, ¿por qué está cerrado? La solicitud de problema/función aún no se ha resuelto

¿Alguna actualización sobre esto? Cuál es la manera correcta ?

+1

¿Alguien tiene una actualización sobre cómo conectarse al host (IP pública del host como eth0 ip y no docker0 interface ip) desde el contenedor?

@sburnwal docker run --add-host=publicip:$(hostname --ip) ubuntu ping -c2 publicip

Ver la respuesta de @retog

+1 para docker host

+1 para docker host

+1 para docker host

dejándolo aquí, ya que tal vez ayude al menos a algunos de ustedes:

Me dijeron que la interfaz de red predeterminada no siempre tiene que ser docker0 y obtener la IP docker0 no funcionará en sistemas que no sean Linux, esto fue un problema para nosotros porque algunos de nuestros desarrolladores donde usaban macs

entonces, en lugar de usar los scripts mágicos para obtener la IP del host desde la conexión de red, me recomendaron forzar la configuración de red del contenedor en lugar de intentar averiguarlo mediante programación

Configuré la configuración de red de la ventana acoplable en mi archivo de composición acoplable de esta manera:

``` redes:
por defecto:
conductor: puente
ipam:
configuración:
- subred: 10.10.0.0/24
puerta de enlace: 10.10.0.1

if you are only running one container, you could first create a network (`docker network create`) and connect to it with `docker run --network=<network-name>|<network-id> <image name>`

BUT if you don't want to do this (i.e. force the docker network) and really want to get the default gateway IP, you could get it more cleanly than using `docker0` network interface, for example by parsing the `docker network inspect <network name>`, which outputs the gateway IP (among other things):

...
"IPAM": {
"Conductor": "predeterminado",
"Configuración": [
{
"Subred": "172.17.0.1/16",
"Puerta de enlace": "172.17.0.1"
}
]
}
...

you could also use the `--format` option of `docker network inspect` to get only the fields that are of interest, like this:

$ docker network inspeccionar el puente --format='{{range .IPAM.Config}}{{.Gateway}}{{end}}'
$ 172.17.0.1
```

NOTA: si hubiera más entradas .IPAM.Config , las obtendría todas en la salida, por lo que se necesitaría una lógica adicional para elegir la correcta

+1 para docker host

Tenga en cuenta que esto sería muy útil cuando simplemente desee usar xdebug dentro de un contenedor php-fpm para conectarse a su IDE para la depuración, ya que obviamente no puede ejecutar un IDE en un contenedor.

+1 para docker host

Mi resumen de los trucos anteriores:

en docker-compose.yml :

nginx:
  restart: always
  build: ./nginx/
  ports:
    - "80:80"
  extra_hosts:
    # requires `export DOCKERHOST="$(ifconfig en0 inet | grep "inet " | awk -F'[: ]+' '{ print $2 }')"` in ~/.bash_profile
    - "dockerhost:$DOCKERHOST"

en ~/.bash_profile :

# see https://github.com/docker/docker/issues/1143
export DOCKERHOST="$(ifconfig en0 inet | grep "inet " | awk -F'[: ]+' '{ print $2 }')"

en nginx-conf :

location / {
        proxy_pass http://dockerhost:3000;
        proxy_set_header host $host;
        proxy_set_header x-real-ip $remote_addr;
        proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
}

Tiendo a usar la imagen acoplable svendowideit/ambassador para solucionar este problema.

Por ejemplo, si quiero vincularme a un nodo de búsqueda elástica que se ejecuta en el host de Docker:

docker run --restart always -d --name elasticsearch --expose 9200 -e ELASTICSEARCH_PORT_9200_TCP=tcp://<host>:9200 svendowideit/ambassador

Ahora, otros contenedores docker pueden encontrar elasticsearch usando --link elasticsearch, sin saber si elasticsearch se ejecuta en un contenedor docker, en el host o donde sea.

+1 para docker host

... por ahora, aunque podrías hacer esto:

$ docker build --build-arg HTTP_PROXY=172.16.42.1 .

... o en mi caso similar con docker-compose - Hago esto:

client:
        build: ./client
        extra_hosts:
            - "foobar:${HTTP_PROXY}"

configure su host en el momento de la compilación:

export HTTP_PROXY=172.16.42.1 && docker-compose build

@rattrayalex en mac, encontré que esto imprime la IP directamente: ipconfig getifaddr en0

+1 para docker host

¿Pueden aquellos de ustedes que acaban de hacer +1 para dockerhost, simplemente agregar un pulgar hacia arriba (reacción) a un comentario existente de la misma naturaleza? Los comentarios de +1 solo amplían/llenan este hilo de problemas innecesariamente. Ya hay tantos, no es necesario agregar más, ¡pero siempre nos vendría bien un pulgar hacia arriba! 👍

Creo que los comentaristas están escribiendo un extenso +1 para resaltar que este es un caso de uso común, con soluciones alternativas conocidas, y debería requerir un tiempo estimable en horas para que el equipo de Docker lo codifique.
Aún así, está abierto desde hace 3 años 👍

Entonces, me parece que es más un "¿todavía estamos aquí?" En cambio, solo un emoji

La solución de @magicalbob en https://github.com/docker/docker/issues/1143#issuecomment -233152700 funciona perfectamente en todas las configuraciones de contenedores y puentes que he probado hasta ahora.

solución de https://github.com/docker/docker/issues/1143#issuecomment -70052272 no funciona cuando se usa docker compose extra_hosts

+1 para docker host

¿Aún no tienes dockerhost?

+1 para docker host

+1 para docker host

no sucederá, se cerró hace 3 años y no planean implementar esto nunca. la misma razón por la que docker.sock es un arma para la seguridad, dockerhost también lo es. tener un nombre de dominio resoluble desde dentro de su aplicación es un problema de seguridad importante en mi humilde opinión. si es necesario, use las soluciones provisionales, de forma selectiva solo cuando el acceso a los servicios del host por IP no sea una superficie de ataque mayor.

No esté en desacuerdo con que no suceda, pero no veo cómo dockerhost es un riesgo de seguridad a menos que también cierre las muchas soluciones fáciles ....⁣

Enviado desde BlueMail

El 16 de diciembre de 2016, 17:58, a las 17:58, Paulo Cesar [email protected] escribió:

no sucederá, fue cerrado hace 3 años, y no planean hacerlo nunca
implementar esto. la misma razón por la que docker.sock es una pistola para la seguridad,
dockerhost también lo es. tener un nombre de dominio resoluble desde dentro de su
aplicación es un importante problema de seguridad en mi humilde opinión. si es necesario, solo use el
alternativas, de forma selectiva solo cuando el acceso a los servicios de host por IP no
ser una mayor superficie de ataque.

--
Estás recibiendo esto porque te mencionaron.
Responda a este correo electrónico directamente o véalo en GitHub:
https://github.com/docker/docker/issues/1143#issuecomment -267655915

+1 para docker host

+1 para docker host

La IP de la máquina host es 192.168.0.208 .

El archivo docker-compose es el siguiente:

version: '2'
 services:
   zl-tigervnc:
     image: zl/dl-tigervnc:1.5
     container_name: zl_dl_tigervnc
     restart: always
     tty: true
     ports:
       - "8001:8888"
       - "6001:6006"
       - "8901:5900"
       - "10001:22"
     devices:
       - /dev/nvidia0
     volumes:
       - ~/data:/root/data
       - /var/run/docker.sock:/var/run/docker.sock
     extra_hosts:
       - "dockerhost:192.168.0.208"

Este script lanzó un contenedor. El contenedor desea acceder al puerto 8080 en la máquina host (por ejemplo 192.168.0.208:8080 ). Pero no funciona.

Sin embargo, uso el reenvío de puertos para asignar 8080 en la máquina host a 8080 en el enrutador. La IP del enrutador era 63.25.20.83 . El contenedor podría acceder a 8080 de la máquina host mediante el reenvío de puertos (por ejemplo 63.25.20.83:8080 ).

He probado muchas soluciones desde esta página, pero sigue sin funcionar.

Tenga en cuenta que esto sería muy útil cuando simplemente desee usar xdebug dentro de un contenedor php-fpm para
conéctese a su IDE para la depuración, ya que obviamente no puede ejecutar un IDE en un contenedor.

¡Exactamente @colinmollenhour ! Excepto que hay un problema adicional. Puede hacer ping al host, pero en realidad no puede conectarse a los puertos del host (por ejemplo, un depurador remoto que se ejecuta en 9000).

Un montón de cosas viejas y/o no del todo correctas en la red. Mucha gente parece pensar que configurar una IP de alias y adjuntarla a la interfaz lo debería funcionar, pero no es así.

(probando con netcat en el host y telnet en el contenedor docker, así que estoy bien despojado).

@bitwombat verifique el firewall de su host en busca de una regla de puerto 9000

@gregmartyn Eso fue exactamente. ¡Gracias! ¡Hubiera sido lo primero que verifiqué en una configuración más simple! Todas las capas de engaño me hicieron revisar cosas más extrañas.

Julio de 2013 a 2017. Casi 4 años, ¿cómo es que esto aún no es una característica? Esto claramente no es un caso de uso aislado.

No es una característica porque no se alinea con la estrategia de Docker de ser una solución de administración de implementación de múltiples hosts.

Sigo creyendo que hay muchos casos de uso válidos y agregar la función no causaría ningún daño a la estrategia de Docker. De todos modos, aquí hay una solución algo simple para resolver la dirección del host de la ventana acoplable desde un contenedor que creo que debería funcionar de manera bastante universal:

ip route | awk '/^default via /{print $3}'

+1 por dockerhost

Muy necesario. +1 por dockerhost

+1 por dockerhost

+1 para docker host

+1 para docker host

+1 para cualquier solución que no sea una solución alternativa. Nada funciona aquí.

Acordado. +1 para una solución. Lo necesita para realizar trabajos de desarrollo y prueba en proyectos que usan docker.

+1 para docker host

+1 para docker host

+1 para docker host

wow.. 4 años y va fuerte. +1 para dockerhost?

+1 servidor acoplado!!

+1 servidor acoplado!!!

Esto probablemente esté silenciado. Tal vez deberíamos hacer un nuevo número que haga referencia a este.

:+1: para dockerhost... Ahora mismo lo estoy configurando por env:

export DOCKERHOST=$(ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1)

Hace las cosas engorrosas.

Incluso algo tan simple como usar docker-compose en un contenedor con registro privado ssh-tunneled no funciona porque Docker está tan decidido a no querer dockerhost.

NOTA: este problema está cerrado, por lo que no tiene sentido agregar más comentarios :-)

Si necesita esta característica, puede agregar fácilmente un alias de DNS dockerhost usando --add-host y opciones equivalentes.

¿Por qué no está disponible de forma predeterminada? Porque solo funciona en casos triviales. Es decir:

  • ¿Qué sucede con los contenedores que _no_ tienen acceso a la red?
  • ¿Qué pasa con los contenedores que tienen _múltiples_ redes?
  • ¿Qué pasa con los contenedores que se ejecutan en un clúster Swarm?

Si tiene un buen caso de uso (es decir, "Me gustaría hacer XXX y, para hacerlo, me gustaría tener dockerhost ..."), así como respuestas sólidas a las preguntas anteriores (y otros casos de esquina que puedan surgir), ¡siéntase libre de abrir un nuevo problema que haga referencia a este!

Gracias.

El problema es que su IP de host podría ser dinámica y depende de la red en la que se encuentre. Si está desarrollando, es imprescindible conectarse al host para la depuración. La razón por la que todos quieren Dockerhost no es porque las opciones que no están allí sean convenientes o útiles.
Docker tiene toneladas de opciones que no son relevantes para todos, ¿qué hace que esto sea diferente? ¿Por qué no tener la opción en docker para habilitar dockerhost si es necesario? Eso haría feliz al 99%, supongo.

@jpetazzo

¿Qué pasa con los contenedores que no tienen acceso a la red?

Entonces dockerhost no funcionará.

¿Qué pasa con los contenedores que tienen varias redes?

Entonces dockerhost no funcionará.

¿Qué pasa con los contenedores que se ejecutan en un clúster Swarm?

¿A quien le importa?

Si está desarrollando algún software que involucra componentes fuera del ecosistema de la ventana acoplable (como algún software que se ejecuta dentro de una VM de Windows en el host), entonces es complicado conectarlo a la ventana acoplable. ¿Por qué tiene que ser un dolor?

Todos los casos que ha enumerado no son de lo que hablan los 226 comentarios en este hilo, están hablando del caso básico.

Edit: Lo siento, he borrado parte de mi comentario. No quise despotricar. Es un poco frustrante, esta es una característica muy necesaria para algunos usuarios de docker y si está desarrollando un software que lo requiere, es aún más frustrante tener que piratearlo sin razón aparente.

@jpetazzo a veces los casos "triviales" son el 80% de los casos de uso. Dockerhost sería muy valioso para las personas que usan Docker en entornos de desarrollo o ensayo , o en realidad cualquier entorno que no dependa de redes de enjambre/multi-host. Aquí hay algunos ejemplos en los que me gustaría usar Dockerhost:

1) Docker-Compose en Windows con registro privado. Tenemos un registro de Docker privado autohospedado. Los desarrolladores pueden acceder al registro a través del túnel SSH con reenvío de puertos (es decir, en localhost:5000). Pero cuando Docker-Compose se ejecuta en su propio contenedor Docker, no hay forma de especificar el host de registro privado. Si tuviéramos dockerhost , podríamos usar dockerhost:5000 en nuestro archivo docker-compose.yml para darle acceso al puerto reenviado en el host.

2) Cualquier aplicación que necesite comunicarse con los servicios que se ejecutan en el host. Por ejemplo, un cliente SSH basado en web que se ejecuta en un contenedor docker podría usarse para establecer una conexión SSH con el host si hubiera dockerhost . Hay innumerables ejemplos de servicios que se ejecutan en el host de un contenedor Docker que se pueden usar si hay dockerhost .

3) Reenvío de puerto inverso. Podemos tener nuestro servidor SSH u OpenVPN ejecutándose en un contenedor Docker y podría dar acceso a los clientes a los servicios que se ejecutan en el host si hubiera dockerhost . Puede configurar el reenvío de puertos desde el contenedor a dockerhost.

Me encantaría escuchar alguna justificación técnica de por qué los desarrolladores de Moby se niegan a escuchar a la comunidad cuando se trata de dockerhost. Hasta ahora solo escucho razones políticas/comerciales.

Encontré este hilo mientras intentaba encontrar una manera de adjuntar una interfaz de red macvlan a un servicio de enjambre... Swarm parece una solución a medio terminar, la incapacidad de exponer los servicios directamente al mundo exterior es una frustración continua para mí. Parece que Docker perdió tracción con los casos de uso del mundo real, avanzando rápidamente 4 años desde que comenzó este hilo y todavía no hay una implementación nativa para que los contenedores se administren solos.

Soy relativamente nuevo en Docker. Todo lo que he leído de los documentos oficiales tiene sentido. _Docker es en realidad una herramienta bastante fácil de aprender._

De hecho, lo único que he pasado varias horas tratando de averiguar es _cómo conectarme al host desde dentro de un contenedor._ Todo lo demás fue fácil de determinar. Todavía no sé cómo hacerlo. Muchos de los "hacks" en este foro y en SO simplemente no funcionan. Necesitamos acceder al host para consumir una aplicación heredada que no está configurada para ser "Dockerizada" durante muchos meses.

Nunca sucederá, me temo, Josh. Los desarrolladores lo han dejado claro.
Lo que hace que docker sea peor que inútil para una gran clase de aplicaciones,
desafortunadamente, a docker (o "moby") no le importan esos
desarrolladores o esas aplicaciones.

El 19 de junio de 2017 a las 01:08, "Josh Wedekind" [email protected] escribió:

Soy relativamente nuevo en Docker. Todo lo que he leído de los documentos oficiales.
tiene sentido. Docker es en realidad una herramienta bastante fácil de aprender.

De hecho, lo único que he pasado varias horas tratando de averiguar
es cómo conectarse al host desde dentro de un contenedor. Todo lo demas
fue fácil de determinar. Todavía no sé cómo hacerlo. muchos de los
"hacks" en este foro y en SO simplemente no funcionan. Necesitamos acceder a la
host para consumir una aplicación heredada que no está configurada para ser "Dockerizada"
durante muchos meses.


Estás recibiendo esto porque comentaste.
Responda a este correo electrónico directamente, véalo en GitHub
https://github.com/moby/moby/issues/1143#issuecomment-309311997 , o silenciar
la amenaza
https://github.com/notifications/unsubscribe-auth/AA-shyjglsJXawxHHWGhQH0d1LlZeJqxks5sFbwXgaJpZM4Ayw00
.

Es realmente frustrante que pueda manejar cada situación con un simple archivo de composición de docker declarativo, pero debe usar miles de trucos para conectarse a una aplicación heredada desde su contenedor en su entorno de desarrollo.
@thaJeztah No da una buena primera impresión de Docker en absoluto.

Para su información, terminamos abandonando Docker en producción precisamente por esta razón. Sé que los desarrolladores de Docker están totalmente en contra (y entiendo que no es una característica tan trivial como algunos afirman), pero solo quería intervenir: estás perdiendo clientes del mundo real debido a la obstinada negativa a siquiera considerar este problema. Como un "experto" reacio de Docker en mi empresa, ahora debo advertir a las personas que me preguntan al respecto diciendo "Docker es excelente... excepto si necesita comunicarse con cualquier cosa que se ejecute en el host local".

Entonces, nuevamente, estoy seguro de que el problema está silenciado, pero si alguna vez miran hacia atrás en este hilo, los desarrolladores de Docker, esto está causando un dolor real y está causando que los clientes reales de Docker dejen de usar Docker. Recomiendo reconsiderar su obstinada negativa a abordar el tema; El hecho de que no se ajuste a su visión de cómo se "supone" que se debe usar Docker no significa que sea una característica inútil o innecesaria.

No solo podrían (están) perdiendo clientes existentes. Podríamos haber migrado todo a Docker si cumpliera su promesa de desarrollo. Esta es una verdadera anti-promoción para que docker la use a gran escala para todos los procesos.

La forma en que lo hago funcionar por ahora es creando una red. Así es como se ve mi archivo docker-compose:

version: '2'
services:
  <container_name>:
    image: <image_name>
    networks:
      - dockernet

networks:
  dockernet:
    driver: bridge
    ipam:
      config:
        - subnet: 192.168.0.0/24
          gateway: 192.168.0.1

Después de hacer esto, puede acceder al host con 192.168.0.1.
Puede ser útil para algunos de ustedes, ya que esta función no estará disponible pronto.

@deltabweb ¿Las solicitudes que ingresan a las aplicaciones en la máquina host aparecerán como tráfico "localhost" o tendré que modificar las aplicaciones para responder a 192.168.0.1?

Gracias por tu ayuda.

@halfnibble
No he mirado la documentación de networks en detalles, pero entiendo que se crea una nueva red en su máquina host donde:

  • La IP del "dockerhost" es 192.168.0.1
  • La IP del primer contenedor es 192.168.0.2
  • La IP del segundo contenedor es 192.168.0.3
  • y así ...

A partir de ahí, todo debería funcionar como si tuviera máquinas físicas conectadas entre sí en una red local:

  • Las máquinas pueden conectarse entre sí.
  • e incluso debería poder usar ping 192.168.0.2 del host; sin embargo, esto solo funcionará si su contenedor responde a los pings.

Entonces, para responder a su pregunta, creo que sus aplicaciones en la máquina host deberán responder a 192.168.0.X (dependiendo del contenedor que intente conectarse).

@deltabweb ¿cómo accedo a la nube al puerto del host del servidor? >>> Conexión rechazada

@nooperpudd Solo para estar seguro: está tratando de acceder a una aplicación que se ejecuta en el host desde un contenedor, ¿verdad?
Primero verificaría si la aplicación permite conexiones entrantes desde el exterior (0.0.0.0 y no solo localhost). ¿Y tal vez también asegurarse de que no tiene un firewall que bloquee la conexión?

@nooperpudd si está usando Docker for mac no puede usar el modo host , la solución @deltabweb tampoco funciona para mí (todos mis servidores están escuchando 0.0.0.0 y los firewalls de mi máquina host fueron apagados pero obtengo Connection refused cada vez). Después de aproximadamente 2 días de prueba y error, la única forma que encontré para solucionar este problema es el siguiente script:

#!/bin/bash
export DOCKERHOST=$(ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1)

# You should use DOCKERHOST env variable in your `docker-compose.yml` 
# and put it everywhere you want to connect to `localhost` of the host machine
docker-compose $@

El único problema con este enfoque es que si su IP cambia después de ejecutar sus contenedores, debe ejecutarlos nuevamente y no pueden encontrar su nueva IP.

Una observación notable para mí es que el comando, que se ejecuta al iniciar los contenedores docker, no puede conectarse al contenedor a través de su dirección IP de host. Sin embargo, cuando ese comando no realiza tales intentos de conexión y termina de ejecutarse con éxito, el contenedor puede llegar a sí mismo a través de su dirección IP de host.

Hice esta observación al tratar de exponer los puntos finales de las instancias del clúster de base de datos NoSql a clientes fuera del clúster de enjambre. Después de todo, estos puntos finales deben configurarse con direcciones IP privadas o públicas de la máquina virtual para que el cliente externo pueda llegar a ellos. Sin embargo, Cassandra está diseñada de tal manera que, cuando se inicia, intenta conectarse de inmediato con la dirección IP del host (establecida como variable de entorno CASSANDRA_BROADCAST_ADDRESS ; consulte a continuación) y, por lo tanto, falla. Por otro lado, los nodos de los conjuntos de réplicas de Mongodb primero se inician en un estado limpio y luego se ejecuta un comando de inicio por separado de modo que los nodos primario y secundario puedan formar un conjunto de réplicas.

A continuación, verá una descripción detallada de esta observación para Cassandra (los creo con Docker Swarm pero aparece el mismo problema en docker run -d (en modo NAT, por lo tanto, sin la opción --net=host)

1) Por un lado, un contenedor creado por

docker service create  --name cassandra-service
--publish mode=host,target=7000,published=7000,protocol=tcp 
-e CASSANDRA_SEEDS=host IP address  -e CASSANDRA_BROADCAST_ADDRESS=host IP address

falla con el mensaje de que no puede conectarse a la dirección de escucha: <host IP address>:7000

2) Por otro lado, un contenedor adjunto a una red superpuesta, creada por

docker service create  --network cassandra-net --name cassandra-service
-e CASSANDRA_SEEDS=cassandra-service  -e CASSANDRA_BROADCAST_ADDRESS=cassandra-service

se inicia correctamente y, al mismo tiempo, puedo conectarme a la dirección IP del host en cualquier puerto que esté expuesto en el Dockerfile de la imagen cassandra: 2.0 :

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                                         NAMES
07603a75a379        cassandra:2.0       "/docker-entrypoin..."   About a minute ago   Up About a minute   7000-7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp   cassandra-service-1.1.m243u97zku15w08m6puytdngs

$ docker exec -it 1e61ec16f8d0 bash
root<strong i="5">@1e61ec16f8d0</strong>:/# cqlsh 172.17.13.151
Connected to Test Cluster at 172.17.13.151:9160.
[cqlsh 4.1.1 | Cassandra 2.0.17 | CQL spec 3.1.1 | Thrift protocol 19.39.0]

Del mismo modo, se puede observar lo mismo durante la creación de un segundo nodo de Cassandra.

1) Si creo un segundo contenedor Cassandra en otro nodo por

docker service create  --network cassandra-net --name cassandra-service-2
-e CASSANDRA_SEEDS=172.17.13.151  -e CASSANDRA_BROADCAST_ADDRESS=cassandra-service-2

el contenedor falla con la excepción de tiempo de ejecución de que no puede chismear con la semilla:

java.lang.RuntimeException: Unable to gossip with any seeds
        at org.apache.cassandra.gms.Gossiper.doShadowRound(Gossiper.java:1322)
        at org.apache.cassandra.service.StorageService.checkForEndpointCollision(StorageService.java:457)

2) Por otro lado, si creo un contenedor cassandra a través docker run -d , puedo llegar al nodo semilla a través de su dirección IP de host:

$ docker run -d cassandra:2.0
d87a79cc3de8cd7e4cf40284d1eca91ceb660581cc71082fe64a6b84a09fbd77
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                         NAMES
d87a79cc3de8        cassandra:2.0       "/docker-entrypoin..."   3 seconds ago       Up 2 seconds        7000-7001/tcp, 7199/tcp, 9042/tcp, 9160/tcp   trusting_ardinghelli
$ docker exec -it d87a79cc3de8 bash
root<strong i="17">@d87a79cc3de8</strong>:/# cqlsh 172.17.13.151
Connected to Test Cluster at 172.17.13.151:9160.
[cqlsh 4.1.1 | Cassandra 2.0.17 | CQL spec 3.1.1 | Thrift protocol 19.39.0]
Use HELP for help.
cqlsh>

Específicamente para Cassandra, este problema se resuelve desactivando el arranque automático de los nodos de Cassandra. Lo hace configurando auto_bootstrap a false en /etc/cassandra/cassandra.yaml usando un comando de punto de entrada en Compose V3:

version: '3'
services:
  cassandra-1:
    image: cassandra:2.0
    entrypoint:
    - "sh"
    - "-c"
    - "echo auto_bootstrap: false >> /etc/cassandra/cassandra.yaml; /docker-entrypoint.sh cassandra -f"
    environment:
      CASSANDRA_BROADCAST_ADDRESS: 172.17.13.151
    volumes:
    - volume1:/var/lib/cassandra
    ports:
    - "7000:7000"
    - "7001"
    - "7199"
    - "9042:9042"
    - "9160:9160"

y luego inicie manualmente los nodos de Cassandra ejecutando docker exec -it <container id> nodetool rebuild .

Podría usar esta característica en desarrollo, bueno...

@jpetazzo Desarrollamos soluciones PHP en equipos en una combinación de plataformas. Nuestro depurador (xdebug) necesita volver a conectarse al IDE en el host. En Windows y Linux, esto funciona 'fuera de la caja', pero en Mac, nuestros desarrolladores tienen que cambiar el archivo xdebug.ini para mencionar específicamente su IP local. Pero el Dockerfile está bajo control de fuente... conflictos constantes en cola y palabrotas mientras los desarrolladores se enfrentan por la edición de este archivo. Sí, hay soluciones alternativas con secuencias de comandos, pero ¿por qué Docker para Windows y Mac tiene docker.for.win.localhost y docker.for.mac.localhost? Es parcialmente útil, pero aún necesitamos scripts para detectar en qué plataforma estamos para configurar esto correctamente. Simplemente parece mucho más complicado de lo que debería ser. Por favor, reconsidere esta característica. Docker puede ser una curva de aprendizaje empinada, pero problemas como este hacen que los usuarios busquen en Google con incredulidad durante horas y horas.

Verificar la página https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds ayudó, usar docker.for.mac.localhost funcionó para nosotros :)

Para bien o para mal, docker-compose sigue siendo, con mucho, la forma más fácil que conozco de activar un Selenium Hub y nodos de cuadrícula Firefox/Chrome sin cabeza para probar un servidor web que se ejecuta en una máquina de desarrollo local o en CI (lanzamiento el servidor web en un contenedor docker es demasiado lento para ser conveniente para el desarrollo). No es en absoluto para lo que Docker estaba destinado, pero Docker es la mejor herramienta para ese trabajo, y es culpa de Docker 😆 Excepto que el único problema es descubrir fácilmente la IP del host de una manera que funcione en cualquier sistema operativo.

@rskuipers , ¿puede explicar qué hizo exactamente con docker.for.mac.localhost ? Estoy tratando de hacer solicitudes desde el interior de mis contenedores para resolverlas en la máquina host. Mis contenedores se ejecutan en traefik, lo que significa que puedo acceder a ellos a través de domain.docker.localhost, pero si intento acceder a una URL que comienza con eso desde dentro de mi contenedor, no se resuelve.

Actualmente, lo que hice fue agregar esto a mi docker-compose.yml , que agrega una línea a /etc/hosts para que el dominio se resuelva bien:

extra_hosts: - "domain.docker.localhost:172.18.0.1"

La IP es la IP del host dentro de mi contenedor, que puedo obtener usando ip route | awk '/^default via /{print $3}' . Pero no me gustaría codificar eso si es posible ...

@jzavrl Todo lo que hice fue usar docker.for.mac.localhost para que mis solicitudes HTTP pasaran por un proxy que se ejecuta en el host. No uso ninguna otra capa además de docker-compose .

Eso es exactamente lo que me interesa. ¿Qué tipo de cambios específicamente tuviste que hacer?

@jzavrl Ninguno: P simplemente funcionó.

No lo entiendo, ¿qué hiciste con docker.for.mac.localhost entonces?

@jzavrl Usé eso en lugar de la IP para conectarme. Así que docker.for.mac. servidor local: 8888

Ahhhhhh, ahora que está empezando a tener sentido ahora. Intentare esto entonces. Salud @rskuipers.

simplemente use la ip de "en0" en su computadora.

por ejemplo

ssh [email protected]

'192.168.1.100' tal vez del servicio DHCP de su enrutador.

@acuthbert , gracias por tu sugerencia.
docker.for.win.localhost me funciona en Docker para Windows. Todavía hay esperanza para Docker y Windows. 😣

hay pocas razones técnicas por las que esto no se puede hacer y satisfacer al 90% de las personas en este hilo, los casos de esquina y las situaciones en las que realmente no funciona, las personas que se están desarrollando en esa situación podrían estar satisfechas con un conjunto simple de "casos de uso" que explican qué escenarios es probable que no funcionen.

Esto es principalmente basura política y no un razonamiento técnico real aquí. Espero que uno de los otros motores de contenedores se active y pueda cambiar kubernetes para usarlo en su lugar. Entonces ya no tendré que lidiar con esta basura.

@NdubisiOnuora , ¿qué tipo de aplicación? ¿Aplicación web?

Tengo 2 aplicaciones de consola (tcp-server en host y tcp-client en contenedor).
Debido a que usan tcp, necesito exactamente IP ( docker.for.win.localhost no encajan, porque es un dominio).

Por ejemplo, ¿Qué ip:port debo configurar en tcp-client, si configuro ip:port 127.0.0.1:9595 en tcp-server?

¿Simplemente resolver el dominio a una dirección IP?

@orf ,
Quiero usar este código en C#:
IPAddress hostAddr = Dns.Resolve("docker.for.win.localhost").AddressList[0];
Pero antes de eso, intento hacer ping a docker.for.win.localhost , pero no veo eso, error: Ping request could not find host docker.for.win.localhost. Please check the name and try again.
Mi Dockerfile:
FROM microsoft/windowsservercore
ADD . /
ENTRYPOINT powershell ping docker.for.win.localhost

En caso de que alguien se lo haya perdido, creo que la solución a partir del 18.03 es host.docker.internal aunque, por alguna razón, ¡esto solo funciona en Docker para Windows! ¿Por qué no otros?

EDITAR: No vi que Github colapsó los comentarios... 🤦‍♂️

Funciona para mi:
docker run --rm -it --add-host "docker.for.localhost:$(ip -4 addr show docker0 | grep -Po 'inet \K[\d.]+')" alpine:latest ping docker.for.localhost

@lukasmrtvy Eso funciona para un caparazón, pero ¿qué tal para docker-compose.yml ?

He creado un contenedor para resolver este problema de forma genérica trabajando en todas las plataformas https://github.com/qoomon/docker-host

¿Fue útil esta página
0 / 5 - 0 calificaciones