Moby: Documentar como se conectar ao host do Docker a partir do contêiner

Criado em 5 jul. 2013  ·  263Comentários  ·  Fonte: moby/moby

Eu tive alguns problemas para descobrir como conectar o host do docker do contêiner. Não foi possível encontrar a documentação, mas encontrei logs do irc dizendo algo sobre o uso de 172.16.42.1 , o que funciona.

Seria bom se esse comportamento e como ele está relacionado a docker0 fosse documentado.

Comentários muito úteis

Acho que a exigência é clara a partir do título da edição. É preciso haver uma maneira fácil e bem documentada de falar com o host a partir do contêiner, independentemente da forma como ela é implementada.

Todos 263 comentários

quando você olha dentro do network.go, descobre que o docker investiga redes internas que não são roteadas.

primeiro 172.16.42.1 é adivinhado como um endereço de ponte e depois outros.

Então documentar isso não vai ajudar muito. É um esquema dinâmico no qual você não pode confiar.

Acho que o que você precisa é mais uma forma de definir os endereços usados ​​para bridge e cliente.
pode ser isso?

Acho que a exigência é clara a partir do título da edição. É preciso haver uma maneira fácil e bem documentada de falar com o host a partir do contêiner, independentemente da forma como ela é implementada.

+1 Seria muito bom ter uma boa maneira de se conectar ao sistema host

+1, a ramificação 1.0 definirá uma API de introspecção para que cada contêiner possa interagir com o host de maneira controlada e com escopo definido.
Em
Isso está atualmente planejado para 0,8.


@solomonstre
@getdocker

Na quinta-feira, 8 de agosto de 2013 às 13h10, EJ Bensing [email protected]
escrevi:

+1 Seria muito bom ter uma boa maneira de se conectar ao sistema host

Responda a este e-mail diretamente ou visualize-o no GitHub:
https://github.com/dotcloud/docker/issues/1143#issuecomment -22351792

Então, como posso me conectar ao host do docker de dentro de um contêiner? Estou tentando me conectar a um contêiner docker por meio da porta do host em vez do IP privado do contêiner.

@gerhard : uma API de introspecção está planejada para 0.8. Enquanto isso, se você quiser acessar a API do Docker dos contêineres, poderá configurar o Docker para escutar o endereço IP da ponte do Docker.

Para fazer isso, você faria:

  • criar uma ponte

ip link add docker0 type bridge

  • atribuir um endereço IP a ele

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

  • inicie o docker e vincule a API à ponte

docker -d -H 172.17.0.1:4242

Agora você pode acessar a API do Docker de seus contêineres.

Atualmente (versão 0.7) o docker não oferece suporte confiável à concessão de acesso ilimitado ao seu próprio soquete de controle para um de seus contêineres. As soluções explicadas neste tópico são hacks que não têm garantia de funcionar e, se funcionarem, podem quebrar a qualquer momento - por favor, não os use em produção ou espere que nós os suportemos. Como não há recurso oficial para documentar, esse problema de documento não pode ser corrigido.

Para discutir hacks e soluções alternativas para recursos ausentes, recomendo a lista de discussão _docker-user_ ou o canal _#docker_ irc no Freenode.

Feliz hack

@shykes Existe outro problema que rastreia a criação de tal recurso, nesse caso?

A propósito, para dar motivação para tal recurso: isso é útil ao testar localmente um servidor (onde eu teria usado o vagrant no passado) e quero conectar um servidor no contêiner a um banco de dados ou outro servidor em execução minha máquina de desenvolvimento (o host docker).

Já estou convencido do valor desse recurso :)

Em segunda-feira, 2 de dezembro de 2013 às 9h09, Caleb Spare [email protected]
escrevi:

A propósito, para dar motivação para tal recurso: isso é útil ao testar localmente um servidor (onde eu teria usado o vagrant no passado) e quero conectar um servidor no contêiner a um banco de dados ou outro servidor em execução minha máquina de desenvolvimento (o host docker).

Responda a este e-mail diretamente ou visualize-o no GitHub:
https://github.com/dotcloud/docker/issues/1143#issuecomment -29636528

Estou no Fedora 20 com o docker 0.7.2, configurando o Docker UI . Eu tive que abrir a porta na qual o docker daemon escuta para que o firewall não a bloqueie:

  • firewall-cmd --permanent --zone=trusted --add-interface=docker0
  • firewall-cmd --permanent --zone=trusted --add-port=4243/tcp

Depois disso, o _docker-ui_ conseguiu se conectar ao soquete de controle do daemon do docker.

HTH
Esta é uma necessidade clara e legítima de tal recurso.

Me desculpe, se eu estou mantendo um fio duro vivo.

O título deste problema diz: "Como se conectar ao host a partir do contêiner docker".
Não vejo como isso se relaciona com o recurso docker inspect . O recurso de inspeção é usado no lado do host para encontrar o IP do contêiner, se não me engano.

Acho que o problema do bkad é encontrar o IP do host de dentro do contêiner. Concedido eu não sou assistente de rede, mas não é bastante seguro assumir que o gateway ip (de dentro do contêiner) mapeia para o host.
(Supondo que não se configure uma configuração de ponte ou algo assim).

Usando o gateway para 0.0.0.0 de netstat -nr Eu certamente não tive problemas para acessar um servidor rodando na minha máquina host. Eu suspeito que o ip do gateway é estático (uma vez que o docker é iniciado), alguém pode confirmar isso?

Uma alternativa seria passar o IP público dos meus hosts para o container usando variáveis ​​de ambiente, mas o IP público pode não ser estático. E embora o nome do host possa funcionar melhor em produção, eles são difíceis de usar localmente.

Eu ainda preferiria uma maneira de chamar do contêiner docker para hospedar por meio do loopback e aparecer como 127.0.0.1 no host. Ou se a segurança é uma preocupação outro dispositivo de loopback que sempre tem o mesmo ip.
Ou talvez a coisa que encontrei não exponha minha comunicação ao público? Como disse, não sou um assistente de rede :)
Observe que, se usar o ip-gateway para chamar o host do docker é o "caminho certo", não podemos documentá-lo?

Para quem procura encontrar o ip do gateway do container /proc/net/route é provavelmente o lugar certo para lê-lo.

A Motivação , para este recurso, inclui vários serviços de metadados. Expor coisas do serviço de metadados ec2 seria bom. Distribuição de credenciais e dados estruturados mais complexos que não se encaixam em variáveis ​​de ambiente.

@jonasfj : na verdade, existe uma maneira mais fácil, agora que o Docker suporta arquivos de montagem de ligação do host para o contêiner. Você pode ligar o soquete de controle do Docker, ou seja: docker run -v /var/run/docker.sock:/var/run/docker.sock … ; isso é mais fácil do que mexer nas regras de rede.

Não tenho certeza de como o soquete do docker ajuda. Ainda acho que o problema deve ser reaberto, não há documentação para o seguinte cenário:

1) No 'host' um serviço é executado na porta 8080 (digamos 'etcd')
2) A partir desse host, um contêiner docker é iniciado
3) Como o serviço na porta 8080 no host pode ser alcançado a partir do contêiner docker? Qual seria o URL/IP?

@jpetazzo Como a configuração do docker.sock entra em jogo para resolver o problema acima?

@vrvolle , expor docker.sock não resolve o problema original descrito por @bkad.
Mas seria exposto um soquete de domínio unix diferente para comunicação entre o host e o contêiner docker.

Por exemplo, se você quisesse expor o mysql do host, você exporia o socket mysql: /tmp/mysql.sock .

Ou se você como eu tiver uma API de metadados através da qual os contêineres devem poder consultar o host para várias coisas úteis, você cria seu próprio soquete de domínio unix e o expõe ao contêiner. HTTP sobre soquetes de domínio unix deve funcionar muito bem. Além disso, você não tem todos os problemas de configuração de rede e problemas de segurança.

apenas tive que ler sobre 'soquetes de domínio unix'.
mas:

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

afirma que não há URL e, portanto, nenhum cliente comum pode usar esse mecanismo imediatamente.

Por outro lado:

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

mostra que é de alguma forma possível usar tal soquete.

Mas ainda assim eu gostaria de ter um endereço IP e uma porta, que um programa dentro de um docker poderia simplesmente usar. Eu vou - por enquanto - usar

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

Devo criar um novo problema ou alguém pode reabrir este.

@vrvolle
Eu não sou um cara de rede, mas imagino que há alguns truques que se pode fazer para proxy localhost no contêiner sobre um soquete unix e, em seguida, dentro do soquete unix do proxy do contêiner para o container-localhost (dispositivo de loopback) ...

Seria bom documentar como fazer isso. Mas parece que não é necessariamente um docker de recursos que precisa de suporte ativo.

Existem várias maneiras de resolver isso, dependendo do que exatamente você deseja alcançar.

Se você quiser se conectar a um serviço executado no host (qualquer tipo de serviço, por exemplo, alguma API ou banco de dados que seria executado diretamente no host), você deve descobrir o endereço IP do host.

Uma maneira é confiar no fato de que o host do Docker pode ser acessado por meio do endereço da ponte do Docker, que é o gateway padrão para o contêiner. Em outras palavras, uma análise inteligente de ip route ls | grep ^default pode ser tudo o que você precisa nesse caso. Obviamente, ele depende de um detalhe de implementação (o gateway padrão é um endereço IP do host do Docker) que pode mudar no futuro.

Outra maneira é usar a API do Docker para recuperar essas informações. Então, o problema se torna "como me conecto à API do Docker a partir /var/run/docker.sock um contêiner?", e uma solução potencial (usada por muitos, muitos contêineres por aí!) o recipiente. Isso tem uma grande desvantagem: a API fica totalmente disponível para o contêiner, o que pode fazer coisas ruins com ela.

A longo prazo, o Docker exporá uma API de introspecção melhor, permitindo acessar essas informações sem dar muitos privilégios aos contêineres.

TL,DR: curto prazo, verifique a rota padrão do contêiner. A longo prazo, haverá uma API de introspecção incrível.

eu também tenho problema devido ao upstart. não consigo encontrar nada em /var/run/docker.sock. e usei o comando "-v /etc/run/docker.sock:/etc/run/docker.sock" mas nada aconteceu.
eu acho que é um problema devido a algumas novas atualizações sobre os recursos do kernel. por favor, dê-me uma breve nota sobre esta questão. e comando completo para resolver isso. obrigado

use -v /var/run/docker.sock - não /etc (que normalmente é reservado para arquivos conf).

alguma atualização sobre isso na nova versão 1.0.0?

Existe o nsenter - mas acho que a maneira encorajada é executar o sshd neste
etapa.

Na sexta-feira, 13 de junho de 2014, Camilo Aguilar [email protected] escreveu:

alguma notícia sobre isso na nova versão 1.0.0?


Responda a este e-mail diretamente ou visualize-o no GitHub
https://github.com/dotcloud/docker/issues/1143#issuecomment -45958769.

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

vrvolle, obrigado por isso. Muitas pessoas como nós estão procurando um petisco como este

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

A atualização automática do Docker /etc/hosts em cada contêiner com o IP do host, por exemplo, 172.17.42.1 e chamá-lo, por exemplo dockerhost seria uma correção conveniente.
Acho que por enquanto estamos presos com netstat -nr | grep '^0\.0\.0\.0' | awk '{print $2}'

+1 por dockerhost em /etc/hosts

+1 para dockerhost em /etc/hosts, parece uma boa ideia

A edição de um arquivo em uma imagem nunca deve ser feita, a menos que forneça especificamente um argumento ou sinalizador para fazê-lo. Além disso, não é obrigatório que 100% das imagens sigam o LSB, então pode não haver um diretório /etc . O nome do arquivo a ser usado para conter o IP do host também deve ser especificado pelo argumento do comando.

docker --host /etc/hosts

+1 para dockerhost em /etc/hosts

+1 para uma entrada /ec/hosts

@Sepero docker já está preenchendo /etc/hosts com os contêineres vinculados, portanto, seus argumentos realmente não são válidos.

@matleh Isso é verdade, mas acho que a maneira correta não é preencher /etc/hosts diretamente, ou pelo menos nos deixar especificar o local caso não o tenhamos.

De qualquer forma, entrada dockerhost em hosts.

Eu também gostaria de ter o IP do host do docker em /etc/hosts .

+1 no IP do host do docker em /etc/hosts

Talvez uma maneira melhor de facilitar o acesso aos serviços de rede no host seja facilitar a configuração de entradas iptables que encaminham portas em sentido inverso, ou seja, do contêiner para o host. Eu acho que a opção -p ou --publish seria bem complementada por uma opção -s ou --subscribe que tem o efeito inverso. Acho que eu os teria chamado --forward e --reverse, no entanto. Como quer que você chame, essa me parece uma abordagem muito mais consistente do que as outras sugestões aqui.

Isso pode estar afirmando o óbvio, mas uma maneira simples de fazer isso que funciona atualmente e talvez seja menos dependente da implementação seria determinar o endereço IP no host antes de iniciar o contêiner e definir uma variável de ambiente no contêiner adequadamente. Ao longo destas linhas:

#!/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

Isso seria essencialmente paralelo ao modo --link funciona. Ainda depende da ponte ter um nome que corresponda /docker/ e haver apenas uma dessas pontes, mas a ponte é definida quando o daemon do docker é iniciado. Seria bom se docker info nos desse o nome da ponte em uso e/ou o endereço IP do host. Outro pensamento seria adicionar uma opção --link-host PORT a docker run que faria essencialmente o acima.

IMO esta é a melhor opção. Com --link-host , o contêiner não precisaria saber se o serviço que está acessando está no host ou em outro contêiner.

Não tenho certeza de como os outros estão invocando seus contêineres, mas quando os executo com o --net=host , consigo ver a mesma configuração de rede do meu host do docker. Sem esse switch, obtenho uma pilha de rede autônoma, conforme descrito nas 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

executando sem o switch produz isso:

$ 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

O que estamos procurando é um método para obter o endereço IP de 10.0.2.15 (o IP da eth0 i/f do meu host docker) ou 172.17.42.1 (o IP da ponte docker0 i/f do meu docker).

Eu particularmente não me importo com a abordagem de adicionar algum host ao meu arquivo de contêineres /etc/hosts, que parece um pouco hackey para mim. Em vez disso, ter essas informações expostas internamente para que eu possa pegá-las quando necessário parece ser a maneira mais prudente de ir aqui.

+1 por --link-host ou alguma outra forma intuitiva

+1 para uma entrada /etc/hosts
Parece bastante conveniente e segue as convenções de comunicação atuais.

Apenas para esclarecer meus comentários anteriores: o que é ótimo em --link <container>:<alias> é que ele expõe um _service_ por meio de um _alias_. Da mesma forma, um mecanismo para expor o host ao contêiner deve fornecer acesso a um serviço específico, não apenas a um endereço IP. O contêiner acessaria esse serviço por meio de um alias; ele não precisa saber onde o serviço realmente está. A opção deve ter a semântica inversa de -p e se comportar como --link . Em outras palavras --link-host <ip address>:<port>:<alias> configuraria variáveis ​​env e uma entrada /etc/hosts , e configuraria entradas iptables conforme necessário, ou seja, se o serviço no host estiver escutando em um endereço IP que de outra forma é inacessível ao recipiente.

@altaurog Que tal algo assim?

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

someservice seria apenas qualquer nome para o qual você pode --link , e host-exposing-image seria uma imagem especial que encaminha portas de host em portas expostas. Provavelmente a ideia seria implementável compartilhando o /var/run/docker.sock do host com a imagem.

Talvez já exista algo assim, não sei.

Editar:

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

Esqueça o acima, não li todos os comentários aqui (ainda não li). Isto é o que funciona para mim no docker-osx (e desculpe por não postar na lista de discussão):

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 é uma boa ideia, assim como apenas ter uma entrada dockerhost em /etc/hosts

Eu criei um novo problema, pois este problema foi encerrado (mas não resolvido): #8395

+1 por dockerhost ou qualquer outra forma conveniente.

+1 para qualquer maneira conveniente

Como a abordagem dockerhost recebeu alguns votos aqui, a maneira mais fácil que encontrei (dos comentários aos 3 problemas relacionados #8395 #10023) de ter uma entrada de hosts é adicionar o argumento --add-host=dockerhost:$(ip route | awk '/docker0/ { print $NF }') ao executar a imagem, por exemplo:

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

Embora isso adicione a entrada /etc/hosts necessária, ainda é uma pena que dockerhost não esteja lá por padrão. Ao distribuir uma imagem, tenho a opção de

  • instrua os usuários a adicionar o parâmetro acima
  • faça alguns scripts rodando no container que adaptam os arquivos de configuração com base na tabela de roteamento

Eu pessoalmente não entendo porque dockerhost não está lá por padrão, isso tornaria a criação e distribuição de imagens que acessam serviços normalmente no host (XServer, CUPS, Puleaudio) muito mais convenientes.

+1 para dockerhost. Na verdade, eu exporia isso como uma env var, entrada /etc/hosts e sinalizador cli. É obrigado a ser usado de muitas maneiras.

:+1: para dockerhost

dentro do seu recipiente:

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 mim sempre que eu faço login (com conta root)

+1 para dockerhost

+1 para dockerhost

+1 para dockerhost

+1 para dockerhost

+1 para dockerhost :yum:

+1 para dockerhost

+1 para dockerhost :+1:

Acabei escrevendo este script, alguém pode achar ú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 dockerhost

como há bastante interesse neste tópico, acho que faria sentido, em vez de discutir um ticket fechado, abrir uma nova solicitação de recurso.

Abri https://github.com/docker/docker/issues/8395 há algum tempo - fechei também. Ainda sem solução documentada

ok, embora existam soluções alternativas, acho que o principal motivo é provavelmente que acessar o host é um caso de uso parcialmente isolado.

como existe um recurso de links do docker, acho que faz sentido fornecer um link para o host.

Olá!

FYI isso agora está documentado :

Observação: às vezes, você precisa se conectar ao host do Docker, o que significa obter o endereço IP do host. Você pode usar os seguintes comandos de shell para simplificar esse processo:

$ 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

Obrigado, @icecrime.

Uma pessoa do docker pode bloquear esse problema para que as pessoas parem de atualizá-lo?

+1 para dockerhost

+1 para dockerhost - ter que executar um alias de comando local hostip não é compatível com, por exemplo, docker-compose, docker-swarm etc. etc.

+1 para dockerhost

@icecrime , que fornece o gateway do host e não o ip do host no meu Ubuntu. Não deveria ser apenas o comando abaixo?

$ ip address show

+1, algo utilizável sem ter que executar comandos seria o ideal

Como isso ainda não foi resolvido? A execução de comandos em um contêiner para tornar a rede do contêiner para o host funcional é completamente inaceitável.

+1 para qualquer coisa simples
BTW a solução alternativa com ip funciona no meu Ubuntu, mas não funciona no OS X, certo?

+1 Este é um problema de 2 anos e um recurso útil. Eu quero uma maneira fácil de se conectar à API remota do docker de dentro de um contêiner.

@ianchildress se você tiver seu daemon configurado para aceitar conexões de soquete, simplesmente monte o soquete em seu contêiner, por exemplo, docker run -d -v /var/run/docker.sock:/var/run/docker.sock myimage

+1 para dockerhost
Encontrei este problema ao procurar soluções para o caso de uso: xdebug.remote_host=dockerhost

+1 para dockerhost

@thaJeztah e como chego ao nome do host ou endereço IP de lá?

@mbonaci eu estava respondendo a @ianchildress , que queria se conectar à API do Docker dentro de um contêiner (para o qual usar uma conexão de soquete é a abordagem geral)

Estou confuso. @icecrime acima disse acima que isso agora está documentado, mas o link que ele deu está morto. Não consigo encontrar rapidamente a parte citada da documentação. Observo que o exemplo apt-cache-ng usa dockerhost, mas não define o que é (#11556). A única referência que encontrei facilmente foi este tópico. Eu pesquisei toda a fonte e documentação do docker e não parece ser mencionado neste contexto .

@pwaller Desde março, dividimos esse enorme documento longo em referências separadas. O novo local para este material é:

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

+1 para dockerhost

@moxiegirl Eu acho que o parâmetro --add-host é satisfatório. Obrigado

E como se conectar ao host do contêiner docker? Por exemplo, para fazer git pull? Sem volumes usando?

@a93ushakov está tudo explicado no link que @moxiegirl forneceu.
Quando estiver fazendo docker run , adicione o seguinte parâmetro: --add-host=dockerhost:replace_with_docker_host_ip , que cria uma entrada no arquivo /etc/hosts do contêiner.
O que, é claro, significa que você pode fazer referência ao seu host docker de dentro desse contêiner usando seu nome, dockerhost .

@mbonaci > O que, é claro, significa que você pode se referir ao seu host docker de dentro desse contêiner usando seu nome, dockerhost.

Através do ssh?

@thaJeztah > se você tiver seu daemon configurado para aceitar conexões de soquete, ...
Como fazer isso?

@a93ushakov SSH: Se você o tiver instalado e em execução no host (e sua porta não estiver bloqueada), sim.

@a93ushakov @thaJeztah refere-se à conexão de soquete Unix. Acho que esse é o padrão - veja se você tem um arquivo /var/run/docker.sock no seu host.

+1 para dockerhost

+1 para dockerhost

+1 para dockerhost

+1 para dockerhost
Seria bom obter esse nome de host sem etapas extras.

1 para dockerhost

+1 por dockerhost

Não consigo se conectar ao host do docker de dentro de um contêiner. Alguma ideia do que estou fazendo de errado?

$ 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 dockerhost

Quando eu adiciono o IP da ponte do Docker ele funciona.

Primeiro ouça na porta 1234 com netcat

$ nc -l -p 1234

Obtenha o IP da ponte

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

Em seguida, conecte

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

Então eu vejo a resposta

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

+1 para dockerhost
Inferno, quando?

+1 para dockerhost que também funciona no Mac, ou seja, manipulando a VM de forma transparente

Alguém poderia me dizer como chamarei a API do Docker de dentro do contêiner? Eu não sou um cara linux. Já iniciei o container com -v /var/run/docker.sock:/var/run/docker.sock .
Todo mundo está falando como fazer a montagem, mas ninguém mencionou como chamar api dentro.

Tentei ligar usando curl não funcionou. Eu usei o IP do host, por exemplo

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

Foi assim que eu comecei meu daemon. ou seja, docker -H unix:///var/run/docker.sock -H tcp://0.0.0.0 :2375

Qualquer ajuda será muito apreciada.

@jprogn o rastreador de problemas do github não se destina a perguntas gerais de suporte; é melhor fazer essas perguntas no canal #docker IRC, no grupo docker-users no Google ou forums.docker.com

Esta pergunta está relacionada ao tópico original, que não foi respondido completamente. Por favor, veja o título acima

Alguém pode responder como chamar a API do docker dentro do contêiner?????????????

@jprogn por favor siga meu comentário acima; este é um rastreador de problemas, usado para rastrear bugs e solicitações de recursos; não é um fórum de suporte para usar o docker; use os outros métodos que mencionei acima https://github.com/docker/docker/issues/1143#issuecomment -146924892

+1 para dockerhost

No meu host docker CentOS7, não consigo obter uma rota do contêiner para o 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

Alguma ideia?

+1, pode haver uma variável de ambiente para isso.

Eu mesmo gostaria que fosse ao contrário; um link da minha máquina host para os contêineres do docker por nome

+1 para variável de ambiente dockerhost

É realmente complicado combinar uma entrada de DNS sob medida acessando o host sem codificar 172.17.42.1. por exemplo

extra_hosts:
     - "docker:172.17.42.1"

+1 para dockerhost em qualquer lugar (/etc/host do ENV)

+1 isso ainda é necessário!

meu +1 também porque adicionar ip route list dev eth0 | grep -Eo 'via \S+' | awk '{ print \$2 }' a todos os projetos (porque no dev, todos os projetos estão no mesmo host e precisam poder chamar uns aos outros) está começando a parecer um hack ruim

Como resolvemos esse problema em um cluster, por exemplo, Docker Swarm, onde não sabemos a qual máquina um container será atribuído ao executá-lo? O IP do gateway docker0 pode ser diferente de um host para outro no cluster swarm, portanto, não podemos simplesmente executar o comando ip route em um host e assumir que o IP é o mesmo para todos os hosts.

Eu também gostaria da capacidade de mapear uma porta de contêiner para uma porta na ponte docker0 sem precisar saber qual é o IP da ponte docker0. Algo assim:

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

$HOST_GATEWAY_IP é substituído pelo mesmo IP que você obteria executando o comando ip route no host em que o contêiner é implantado no cluster.

Isso precisaria ser suportado por quaisquer outros comandos que envolvam IPs, por exemplo, a opção --dns em docker run .

Achei esse comando mais fácil:

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

+1 para dockerhost em /etc/hosts

+1 dockerhost

+1 por ter dockerhost em /etc/hosts

+1000 para dockerhost

+1 dockerhost

+1

+1 ou mais.

Estou executando um servidor web em um container e preciso conectá-lo ao meu mysql rodando no host.
O ip do host muda com o dhcp, então algo dinâmico é obrigatório.

@wederbrand uma abordagem alternativa (e provavelmente com melhor desempenho) poderia ser conectar ao soquete mysql, por exemplo;

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

Isso tornaria o soquete MySQL disponível como /mysql.sock dentro do contêiner

@thaJeztah Isso pode ser uma opção. No entanto, a imagem do docker que estou usando também é usada para outros ambientes em que o servidor mysql está em um servidor remoto e a imagem tem uma configuração para host:port para o banco de dados.

Eu gostaria que meu contêiner se comportasse o mais próximo possível daquele em produção, portanto, sem mexer nas propriedades de conexão, exceto para definir o host e a porta.

+1

+1

+1

+1

@peterbollen @radek1st @BradRuderman @aldarund @wederbrand @pataiadam @jllado @geniousphp @coreylenertz @dgtlmoon @xlight (todos +1 em dezembro de 2015)
_este_ problema está encerrado, assim como #8395
Não acho que adicionar +1 a um problema antigo ajude. Crie um novo (eu fiz com # 8395) ou tente alguma outra rota para resolver isso.

THX!

+1

+1 dockerhost

+1 para dockerhost

+1 para dockerhost

+1 para dockerhost, vamos lá...

+1 para dockerhost

O uso de docker-compose e dimensionamento de contêineres n-ary em um swarm não fornece naturalmente um meio de realizar pesquisas de endereço IP de nó em tempo real em todas as máquinas.

Isso, conforme indicado acima e modificado para o gateway, não é uma opção:

extra_hosts:
     - "docker:172.18.0.1"

👍 para dockerhost também...

+1 para dockerhost

+1

+1

+1

+1 dockerhost

+1 dockerhost

+1 dockerhost

+1 para dockerhost

+1 para dockerhost

+1 para dockerhost.
Uma vez que esta questão está encerrada abrindo um novo ticket.

+1

+1

Para obter o host em uma configuração docker-machine , você pode usar este comando:

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

Ele relata a máquina à qual você se conecta via ssh , portanto, deve funcionar razoavelmente bem tanto para máquinas locais quanto para remotas, desde que não haja NAT ao longo do caminho. Seria bom se docker-machine inspect informasse esse valor em algum lugar também, se isso for tecnicamente viável.

+1

+1 para dockerhost . Parece um recurso valioso com praticamente nenhum esforço para implementar.

Por enquanto, se você precisar acessar o dockerhost em contêineres criados a partir de imagens que você controla, você pode adicionar este gist ao script entrypoint.sh para sua imagem: https://gist.github.com/dimitrovs/493678fd86c7cdf0c88312d9ddb4906b

Ou acho que você pode adicioná-lo ao /etc/rc.local se sua imagem não usar um script de shell como ponto de entrada. O que essa essência faz é verificar se há dockerhost em /etc/hosts e adicioná-lo se não estiver lá. Isso deve acontecer toda vez que o contêiner for iniciado.

Obtenha o ip do gateway 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 Você pode mostrar uma configuração de exemplo? Eu mexi com isso e não consegui obter os resultados corretos.

Quais resultados você estava obtendo @amcdnl ? Você pode colocar a essência que eu vinculei no arquivo entrypoint.sh para que ele seja executado toda vez que o contêiner for iniciado ou em /etc/rc.local dentro do contêiner. Você terá que fazer isso quando estiver construindo a imagem, mas o próprio script será executado quando um contêiner for iniciado.

+1 para host do docker

@dimitrovs Acabei escrevendo um script que geraria uma composição em tempo de execução.

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

docker-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 Boa solução alternativa. Observe que docker-compose suporta substituição de variável (ambiente).

por exemplo (bash):

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

@sebastiannm minha sugestão deve ser independente do host porque ele é executado dentro da imagem do docker, mas se você estiver executando no Mac no VirtualBox, o IP que você obterá é o IP da VirtualBox VM, não o IP do seu Mac. Acho que esse é o requisito que estamos discutindo. Se você deseja conhecer o IP do Mac de dentro de uma instância do docker, é necessária uma abordagem diferente.

+1 para dockerhost.

Mas, por enquanto, estou fazendo um hack semelhante ao postado acima, que permite obter dinamicamente o endereço IP do host com um script simples que funciona tanto no Linux quanto no OSX : http://stackoverflow.com/questions/24319662/from-inside -of-a-docker-container-how-do-i-connect-to-the-localhost-of-the-mach#38753971

+1 para dockerhost.

+1 para dockerhost

+1+1 dockerhost

+1 para dockerhost

+1 para dockerhost

+1 para dockerhost

Não consigo me conectar a um servidor netcat de host básico de dentro de um contêiner docker quando --net=bridge (o padrão) por meio das várias técnicas discutidas neste problema.

@frankscholten Não consigo reproduzir seu teste netcat bem-sucedido

Eu fiz um problema de stackoverflow descrevendo o problema exato: http://stackoverflow.com/questions/38936738/communicate-to-docker-host-from-docker-container
e queria postar aqui caso ajude alguém no futuro

Enquanto tudo isso fala sobre a comunicação do contêiner para o host usando o ip docker0 no modo bridge, quero saber se o contêiner também pode se comunicar com o ip público do host (digamos, seu ip eth0 original). Aprecie sua resposta. Não tenho tido sucesso nisso.

@sburnwal Não vejo por que você não seria capaz de se comunicar com o ip eth0 do host. O container enviará uma requisição para seu gateway padrão (docker0) e o host deverá responder sem reencaminhamento pois sabe que tem o ip. Seus pings para o ip eth0 do contêiner estão expirando ou você não obtém nenhuma rota para o host ou o que está acontecendo? O contêiner é capaz de se conectar à Internet?

Infelizmente isso não está funcionando para mim. Embora eu possa pingar o IP do contêiner do host, não consigo pingar o ip do host (LAN/eth0 do host) do contêiner. Estou usando o docker 1.9.1. Estou preso aqui, pois preciso que meu contêiner se comunique com o servidor web ouvindo apenas no ip eth0 do host.

Eu personalizei o docker0 usando a opção:
/bin/docker daemon --bip=169.254.0.254/24 --fixed-cidr=169.254.0.0/24

Então eu tenho essas interfaces no meu host (não listando veth* interfaces aqui):

[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

Meu container tem ip 169.254.0.2 e consigo pingar esse ip do container do host. Claro, eu posso pingar do container seu gateway 169.254.0.254 (docker0 ip) mas não consigo pingar o host eth0 ip 172.23.166.176.

Eu tentei parar completamente o firewall e adicionei essas regras explícitas também ao firewall para a cadeia INPUT, mas ainda não tive sorte. Quem pode me ajudar nisso? Ou isso é um bug ?

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

Além disso, deixe-me também fornecer a saída 'ip route' no meu 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 obrigado pela sugestão, atualizei e funciona bem, aqui está meu código para outros:

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 dockerhost

+1 para dockerhost

+1 para dockerhost

A solução do @magicalbob é realmente mágica 🎉

+1 para dockerhost

+1, a propósito, por que isso está fechado? O problema/solicitação de recurso ainda não foi resolvido

Alguma atualização sobre isso? Qual é o caminho certo ?

+1

Alguém tem atualização sobre como se conectar ao host (IP público do host como eth0 ip e não docker0 interface ip) do contêiner?

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

Veja a resposta do @retog

+1 para dockerhost

+1 para dockerhost

+1 para dockerhost

deixando aqui, pois talvez ajude pelo menos alguns de vocês:

Foi-me dito que a interface de rede padrão nem sempre precisa ser docker0 também, obter o IP docker0 não funcionará em sistemas diferentes do linux, isso foi um problema para nós porque alguns dos nossos desenvolvedores onde usar macs

então, em vez de usar os scripts mágicos para obter o IP do host da conexão de rede, fui recomendado para forçar as configurações de rede do contêiner em vez de tentar descobri-lo programaticamente

Eu configurei as configurações de rede do docker no meu arquivo docker-compose assim:

``` redes:
predefinição:
motorista: ponte
ipam:
configuração:
- sub-rede: 10.10.0.0/24
porta de entrada: 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": {
"Driver": "padrão",
"Configurar": [
{
"Sub-rede": "172.17.0.1/16",
"Portal": "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 inspect bridge --format='{{range .IPAM.Config}}{{.Gateway}}{{end}}'
$ 172.17.0.1
```

NOTA: se houvesse mais entradas .IPAM.Config você obteria todas elas na saída, portanto, seria necessária uma lógica adicional para escolher a correta

+1 para dockerhost

Observe que isso seria muito útil para quando você simplesmente deseja usar o xdebug dentro de um contêiner php-fpm para se conectar ao seu IDE para depuração, pois obviamente não pode executar um IDE em um contêiner.

+1 para dockerhost

Meu resumo dos hackarounds acima:

em 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"

em ~/.bash_profile :

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

em 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;
}

Costumo usar a imagem docker svendowideit/embaixador para contornar esse problema.

Por exemplo, se eu quiser vincular a um nó elasticsearch em execução no host do Docker:

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

Agora, outros contêineres do Docker podem encontrar o elasticsearch usando --link elasticsearch, permanecendo agnósticos quanto a se o elasticsearch está sendo executado em um contêiner do Docker, no host ou em qualquer outro lugar.

+1 para dockerhost

... por enquanto, embora você possa fazer isso:

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

... ou no meu caso semelhante com docker-compose - eu faço isso:

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

defina seu host em tempo de compilação:

export HTTP_PROXY=172.16.42.1 && docker-compose build

@rattrayalex no mac, descobri que isso imprime o IP diretamente: ipconfig getifaddr en0

+1 para dockerhost

Aqueles de vocês podem apenas fazer +1 para dockerhost, apenas adicionar um polegar para cima (reação) a um comentário existente da mesma natureza? Comentários +1 apenas estendem/preenchem este tópico desnecessariamente. Já são tantos, não há necessidade de adicionar mais, mas sempre podemos usar um polegar para cima! 👍

Acho que os comentaristas estão escrevendo um +1 extenso para destacar que este é um caso de uso comum, com soluções alternativas conhecidas, e deve exigir tempo estimado em horas para ser codificado pela equipe do docker
Ainda assim, está aberto há 3 anos 👍

Então, parece-me que é mais um "ainda estamos aqui"? Em vez disso, apenas um emoji

A solução @magicalbob em https://github.com/docker/docker/issues/1143#issuecomment -233152700 funciona perfeitamente em todas as configurações e pontes de contêiner que tentei até agora!

solução de https://github.com/docker/docker/issues/1143#issuecomment -70052272 não funciona ao usar o docker compose extra_hosts

+1 para dockerhost

Ainda sem dockerhost?

+1 para dockerhost

+1 para dockerhost

isso não vai acontecer, foi fechado há 3 anos, e eles não planejam implementar isso. Da mesma forma que o docker.sock é uma arma de segurança, o dockerhost também é. ter um nome de domínio resolvível de dentro de seu aplicativo é um grande problema de segurança IMHO. se for necessário, apenas use as soluções alternativas, seletivamente apenas onde o acesso a serviços de host por IP não for uma superfície de ataque maior.

Não discorde sobre isso não acontecer, mas não vejo como o dockerhost é um risco de segurança, a menos que você desligue as muitas soluções fáceis também ....⁣

Enviado do BlueMail

Em 16 de dezembro de 2016, 17:58, às 17:58, Paulo Cesar [email protected] escreveu:

isso não vai acontecer, foi fechado há 3 anos, e eles não planejam nunca
implementar isso. pela mesma razão docker.sock ser uma arma de segurança,
dockerhost também. ter um nome de domínio resolvível de dentro do seu
aplicação é um grande problema de segurança IMHO. se precisar, basta usar o
soluções alternativas, seletivamente apenas onde o acesso a serviços de host por IP não
ser uma superfície de ataque aumentada.

--
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente ou visualize-o no GitHub:
https://github.com/docker/docker/issues/1143#issuecomment -267655915

+1 para dockerhost

+1 para dockerhost

O IP da máquina host é 192.168.0.208 .

O arquivo docker-compose é o seguinte:

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"

Um contêiner foi lançado por este script. O contêiner deseja acessar a porta 8080 na máquina host (por exemplo 192.168.0.208:8080 ). Mas não funciona.

No entanto, eu uso o encaminhamento de porta para mapear 8080 na máquina host para 8080 no roteador. O IP do roteador era 63.25.20.83 . O contêiner pode acessar 8080 da máquina host por encaminhamento de porta (por exemplo 63.25.20.83:8080 ).

Eu tentei muitas soluções desta página, mas ainda não funciona.

Observe que isso seria muito útil para quando você simplesmente deseja usar o xdebug dentro de um contêiner php-fpm para
conecte-se ao seu IDE para depuração, pois obviamente você não pode executar um IDE em um contêiner.

Exatamente @colinmollenhour ! Exceto que há um problema adicional. Você pode fazer ping no host, mas não pode se conectar às portas do host (por exemplo, um depurador remoto rodando em 9000).

Muitas coisas antigas e/ou não muito certas na rede. Muitas pessoas parecem pensar que configurar um IP de alias e anexá-lo à interface lo deve funcionar, mas não funciona.

(testando com netcat no host e telnet no contêiner docker, então estou bem despojado).

@bitwombat verifique o firewall do seu host para uma regra de porta 9000

@gregmartyn Foi exatamente isso. Obrigado! Teria sido a primeira coisa que eu verifiquei em uma configuração mais simples! Todas as camadas de engano me fizeram verificar coisas mais estranhas.

Julho de 2013 a 2017. Quase 4 anos, como isso ainda não é um recurso? Este claramente não é um caso de uso isolado.

Não é um recurso porque não se alinha com a estratégia do Docker de ser uma solução de gerenciamento de implantação de vários hosts.

Ainda acredito que existem muitos casos de uso válidos e adicionar o recurso não causaria nenhum dano à estratégia do Docker. De qualquer forma, aqui está uma solução um tanto simples para resolver o endereço do host do docker de dentro de um contêiner que acho que deve funcionar universalmente:

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

+1 por dockerhost

Muito necessário. +1 por dockerhost

+1 por dockerhost

+1 para dockerhost

+1 para dockerhost

+1 para qualquer solução que não seja uma solução hacky. Nada funciona aqui.

Acordado. +1 para uma solução. Preciso dele para fazer o trabalho de desenvolvimento e teste em projetos que usam o docker.

+1 para dockerhost

+1 para dockerhost

+1 para dockerhost

wow .. 4 anos e indo forte. +1 para dockerhost?

+1 dockerhost!!

+1 dockerhost!!!

Isso provavelmente está silenciado. Talvez devêssemos fazer uma nova edição referenciando esta.

:+1: for dockerhost... Agora estou 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)

Isso torna as coisas complicadas.

Mesmo algo tão simples como usar o docker-compose em um contêiner com registro privado ssh-tunneled não funciona porque o Docker está tão decidido a não querer o dockerhost.

NOTA: este problema está encerrado, então não faz sentido adicionar mais comentários a ele :-)

Se você precisar desse recurso, poderá adicionar facilmente um alias DNS dockerhost usando --add-host e opções equivalentes.

Por que isso não está disponível por padrão? Porque só funciona em casos triviais. Ou seja:

  • e os contêineres que _não_ têm acesso à rede?
  • e quanto aos contêineres que possuem _várias_ redes?
  • e quanto aos containers rodando em um cluster Swarm?

Se você tiver um bom caso de uso (por exemplo, "Eu gostaria de fazer XXX, e para isso, gostaria de ter dockerhost ..."), bem como respostas sólidas para as perguntas acima (e outros casos de canto que possam surgir), sinta-se à vontade para abrir um novo problema fazendo referência a este!

Obrigada.

O problema é que o ip do seu host pode ser dinâmico e dependendo de qual rede você está. Se você estiver desenvolvendo a conexão com o host para depuração, é obrigatório. A razão pela qual todos querem o dockerhost não é porque as opções que não estão lá são convenientes ou úteis.
O Docker tem muitas opções que não são relevantes para todos, o que torna isso diferente? Por que não ter a opção no docker para habilitar o dockerhost, se necessário, isso deixaria 99% feliz, eu acho.

@jpetazzo

e os contêineres que não têm acesso à rede?

Então o dockerhost não funcionará.

e quanto aos contêineres que têm várias redes?

Então o dockerhost não funcionará.

e quanto aos containers rodando em um cluster Swarm?

Quem se importa?

Se você estiver desenvolvendo algum software envolvendo componentes fora do ecossistema do docker (como algum software executado dentro de uma VM do Windows no host), será difícil conectá-lo ao docker. Por que tem que ser uma dor?

Todos os casos que você listou não são sobre o que os 226 comentários deste tópico estão falando, eles estão falando sobre o caso básico.

Edit: Desculpe, apaguei parte do meu comentário. Eu não queria reclamar. É um pouco frustrante, esse é um recurso muito necessário para alguns usuários do docker e, se você estiver desenvolvendo um software que o exija, é ainda mais frustrante ter que hackeá-lo aparentemente sem motivo.

@jpetazzo às vezes os casos "triviais" são 80% dos casos de uso. O Dockerhost seria muito valioso para pessoas que usam o Docker em ambientes de desenvolvimento ou preparação , ou realmente em qualquer ambiente que não dependa de rede swarm/multi-host. Aqui estão alguns exemplos em que eu gostaria de usar o Dockerhost:

1) Docker-Compose no Windows com registro privado. Temos um registro privado do Docker auto-hospedado. Os desenvolvedores podem acessar o registro através do túnel SSH com encaminhamento de porta (ou seja, em localhost:5000). Mas quando o Docker-Compose está sendo executado em seu próprio contêiner do Docker, não há como especificar o host do registro privado. Se tivéssemos dockerhost , poderíamos usar d ockerhost:5000 em nosso arquivo docker-compose.yml dando acesso à porta encaminhada no host.

2) Qualquer aplicativo que precise se comunicar com serviços executados no host. Por exemplo, um cliente SSH baseado na Web executado em um contêiner docker pode ser usado para estabelecer uma conexão SSH com o host se houver dockerhost . Existem inúmeros exemplos de serviços executados no host de um contêiner do Docker que podem ser usados ​​se houver dockerhost .

3) Encaminhamento de porta reverso. Podemos ter nosso servidor SSH ou OpenVPN rodando em um container Docker e poderia dar aos clientes acesso a serviços rodando no host se houvesse dockerhost . Você pode configurar o encaminhamento de porta do contêiner para o dockerhost.

Eu adoraria ouvir qualquer justificativa técnica por que os desenvolvedores do Moby se recusam a ouvir a comunidade quando se trata de dockerhost. Até agora estou ouvindo apenas razões políticas/comerciais.

Me deparei com este tópico enquanto tentava encontrar uma maneira de anexar uma interface de rede macvlan a um serviço swarm ... Swarm parece uma solução inacabada, a incapacidade de expor serviços diretamente ao mundo exterior é uma frustração contínua para mim. Parece que o Docker perdeu força com casos de uso do mundo real, avançando 4 anos a partir do início desse segmento e ainda não há implementação nativa para que os contêineres se gerenciem.

Sou relativamente novo no Docker. Tudo o que li nos documentos oficiais faz sentido. _O Docker é, na verdade, uma ferramenta bastante fácil de aprender._

Na verdade, a única coisa que passei várias horas tentando descobrir é _como se conectar ao host de dentro de um contêiner._ Todo o resto foi fácil de determinar. Ainda não sei como fazê-lo. Muitos dos "hacks" neste fórum e no SO simplesmente não estão funcionando. Precisamos acessar o host para consumir um aplicativo herdado que não está definido para ser "dockerizado" por muitos meses.

Nunca vai acontecer, temo Josh. Os desenvolvedores deixaram isso claro.
O que torna o docker pior do que inútil para uma grande classe de aplicativos,
infelizmente o docker (ou "moby") não deu a mínima para aqueles
desenvolvedores ou esses aplicativos.

Em 19 de junho de 2017 01:08, "Josh Wedekind" [email protected] escreveu:

Sou relativamente novo no Docker. Tudo o que li nos documentos oficiais
faz sentido. Na verdade, o Docker é uma ferramenta bastante fácil de aprender.

Na verdade, a única coisa que passei várias horas tentando descobrir
é como se conectar ao host de dentro de um contêiner. Todo o resto
foi fácil de determinar. Ainda não sei como fazê-lo. Muito do
"hacks" neste fórum e no SO simplesmente não estão funcionando. Precisamos acessar o
host para consumir um aplicativo herdado que não está definido como "Dockerized"
por muitos meses.


Você está recebendo isso porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/1143#issuecomment-309311997 ou silenciar
o segmento
https://github.com/notifications/unsubscribe-auth/AA-shyjglsJXawxHHWGhQH0d1LlZeJqxks5sFbwXgaJpZM4Ayw00
.

É realmente frustrante que você possa lidar com todas as situações com um arquivo de composição docker declarativo simples, mas você deve usar milhares de truques para se conectar a um aplicativo legado de seu contêiner em seu ambiente de desenvolvimento.
@thaJeztah Não causa uma boa primeira impressão do docker.

Para sua informação, acabamos abandonando o Docker na produção exatamente por esse motivo. Eu sei que os desenvolvedores do Docker são totalmente contra isso (e eu entendo que não é um recurso tão trivial quanto alguns diriam), mas eu só queria entrar na conversa: você está perdendo clientes do mundo real por causa da recusa teimosa em sequer considerar esse problema. Como um "especialista" relutante em Docker na minha empresa, agora tenho que alertar as pessoas que me perguntam sobre isso dizendo "O Docker é ótimo... exceto se você precisar se comunicar com qualquer coisa em execução no localhost".

Então, novamente, tenho certeza de que o problema está silenciado, mas se você olhar para este tópico, desenvolvedores do Docker, isso está causando muita dor e está fazendo com que os clientes reais do Docker parem de usar o Docker. Eu recomendo reconsiderar sua recusa obstinada em abordar o assunto; só porque não se encaixa na sua visão de como o Docker "deveria" ser usado não significa que seja um recurso inútil ou desnecessário.

Não só poderiam (estão) perdendo clientes existentes. Poderíamos ter migrado tudo para o docker se cumprisse sua promessa de desenvolvimento. Isso é uma verdadeira antipromoção para o docker usar em larga escala para todos os processos.

A maneira como faço isso funcionar agora é criando uma rede. Aqui está como meu arquivo docker-compose se parece:

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

Depois de fazer isso, você pode acessar o host com 192.168.0.1.
Pode ser útil para alguns de vocês, pois esse recurso não chegará tão cedo.

@deltabweb As solicitações que chegam aos aplicativos na máquina host aparecerão como tráfego "localhost" ou terei que modificar os aplicativos para responder a 192.168.0.1?

Obrigado pela ajuda.

@halfnibble
Eu não olhei a documentação de networks em detalhes, mas meu entendimento é que uma nova rede em sua máquina host é criada onde:

  • IP do "dockerhost" é 192.168.0.1
  • O IP do primeiro contêiner é 192.168.0.2
  • O IP do segundo contêiner é 192.168.0.3
  • e assim por diante ...

A partir daí, tudo deve funcionar como se você tivesse máquinas físicas conectadas em uma rede local:

  • máquinas podem se conectar umas às outras
  • e você deve até poder usar ping 192.168.0.2 do host - isso só funcionará se o seu contêiner responder a pings.

Então, para responder à sua pergunta, acho que seus aplicativos na máquina host precisarão responder a 192.168.0.X (dependendo do contêiner tentando se conectar).

@deltabweb como a nuvem acesso a porta do host do servidor? >>> Conexão recusada

@nooperpudd Só para ter certeza: você está tentando acessar um aplicativo em execução no host a partir de um contêiner, certo?
Eu verificaria primeiro se o aplicativo permite conexões de entrada de fora (0.0.0.0 e não apenas localhost). E talvez também verifique se você não tem um firewall bloqueando a conexão?

@nooperpudd se você estiver usando Docker for mac você não pode usar o modo host , a solução @deltabweb também não está funcionando para mim (meus servidores estão todos ouvindo 0.0.0.0 e meus firewalls de máquina host foram desligados, mas eu recebo Connection refused toda vez). Após cerca de 2 dias de tentativa e erro, a única maneira que encontrei para corrigir esse problema é o script abaixo:

#!/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 $@

O único problema com essa abordagem é que, se seu IP mudar após executar seus contêineres, você deverá executá-los novamente e eles não conseguirão encontrar seu novo IP.

Uma observação notável para mim é que o comando, que é executado ao iniciar os contêineres do docker, não pode se conectar ao contêiner por meio do endereço IP do host. No entanto, quando esse comando não executa essas tentativas de conexão e termina a execução com êxito, o contêiner pode acessar a si mesmo por meio do endereço IP do host.

Fiz essa observação ao tentar expor os endpoints de instâncias de cluster de banco de dados NoSql para clientes fora do cluster swarm. Afinal, esses endpoints precisam ser configurados com endereços IP privados ou públicos da VM para que o cliente externo os alcance. No entanto, o Cassandra é projetado de tal forma que, quando é iniciado, tenta se conectar imediatamente ao endereço IP do host (definido como a variável de ambiente CASSANDRA_BROADCAST_ADDRESS - veja abaixo) e, portanto, falha. Por outro lado, os nós de replicasets do Mongodb são todos iniciados primeiro em um estado limpo e, em seguida, um comando de inicialização separado é executado de modo que os nós primário e secundário possam formar um replicaset.

Abaixo você vê um relato detalhado desta observação para cassandra (eu os crio com o docker swarm, mas o mesmo problema aparece em docker run -d (no modo NAT, portanto, sem a opção --net=host)

1) Por um lado, um container criado 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

falha com a mensagem de que não pode se conectar ao endereço de escuta: <host IP address>:7000

2) Por outro lado, um container conectado a uma rede overlay, criada por

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

inicia corretamente e ao mesmo tempo consigo me conectar ao endereço ip do host em qualquer porta que esteja exposta no Dockerfile da imagem 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]

Da mesma forma, o mesmo pode ser observado durante a criação de um segundo nó cassandra

1) Se eu criar um segundo container cassandra em outro nó

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

o contêiner falha com a exceção de tempo de execução de que não pode fofocar com a semente:

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 outro lado, se eu criar um container cassandra via docker run -d , posso acessar o nó seed através do endereço IP do 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>

Especificamente para o Cassandra, você resolve esse problema desativando a inicialização automática de nós do cassandra. Você faz isso definindo auto_bootstrap para false em /etc/cassandra/cassandra.yaml usando um comando de ponto de entrada no 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"

e, em seguida, inicie manualmente os nós do cassandra executando docker exec -it <container id> nodetool rebuild .

Eu poderia usar esse recurso no desenvolvimento, bem...

@jpetazzo Desenvolvemos soluções PHP em equipes em um mix de plataformas. Nosso depurador (xdebug) precisa se conectar novamente ao IDE no host. No Windows e no Linux, isso funciona 'fora da caixa', mas no mac nossos desenvolvedores precisam alterar o arquivo xdebug.ini para mencionar especificamente seu IP local. Mas o Dockerfile está sob controle de origem... enfileira conflitos constantes e palavrões enquanto os desenvolvedores se chocam sobre a edição deste arquivo. Sim, existem soluções de script, mas por que o docker para windows e mac tem docker.for.win.localhost e docker.for.mac.localhost? É parcialmente útil, mas ainda precisamos de scripts para detectar em qual plataforma estamos para configurar isso corretamente. Parece muito mais complicado do que deveria ser. Por favor, reconsidere este recurso. O Docker pode ser uma curva de aprendizado íngreme, mas problemas como esse deixam seus usuários pesquisando incrédulos no google por horas a fio.

Verificar a página https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds ajudou, usando docker.for.mac.localhost funcionou para nós :)

Para o bem ou para o mal, docker-compose ainda é de longe a maneira mais fácil que conheço de ativar um Selenium Hub e nós de grade do Firefox/Chrome sem cabeça para testar um servidor web rodando em uma máquina de desenvolvimento local ou em CI (iniciando o servidor web em um contêiner docker é muito lento para ser conveniente para o desenvolvimento). Não é para o que o Docker se destina, mas o Docker é a melhor ferramenta para esse trabalho, e é culpa do próprio Docker 😆 Exceto que o único problema é descobrir facilmente o ip do host de uma maneira que funcione em qualquer sistema operacional.

@rskuipers você pode explicar o que exatamente você fez com docker.for.mac.localhost ? Estou tentando fazer solicitações de dentro dos meus contêineres para resolver na máquina host. Meus contêineres estão sendo executados no traefik, o que significa que posso acessá-los através de domain.docker.localhost, mas se eu tentar acessar uma URL que comece com isso de dentro do meu contêiner, não está resolvendo.

Atualmente, o que fiz foi adicionar isso ao meu docker-compose.yml , que adiciona uma linha a /etc/hosts para que o domínio resolva bem:

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

O IP é o IP do host de dentro do meu contêiner, que posso obter usando ip route | awk '/^default via /{print $3}' . Mas eu não gostaria de codificar isso, se possível ...

@jzavrl Tudo o que fiz foi usar docker.for.mac.localhost para que minhas solicitações HTTP passassem por um proxy em execução no host. Eu não uso outras camadas além de docker-compose .

É exatamente nisso que estou interessado. Que tipo de mudanças especificamente você teve que fazer?

@jzavrl Nenhum: P simplesmente funcionou.

Não entendi, o que você fez com docker.for.mac.localhost então?

@jzavrl Eu usei isso em vez do IP para conectar. Então docker.for.mac. localhost:8888

Ahhhhhh, agora que está começando a fazer sentido agora. Vai tentar isso então. Abraços @rskuipers.

basta usar o ip do "en0" do seu computador.

por exemplo

ssh [email protected]

'192.168.1.100' talvez do serviço DHCP do seu roteador.

@acuthbert , obrigado pela sugestão.
docker.for.win.localhost funciona para mim no Docker para Windows. Ainda há esperança para o Docker e o Windows. 😣

há pouca razão técnica para que isso não possa ser feito e satisfaça 90% das pessoas neste tópico, os casos de canto e situações em que realmente não funciona, as pessoas que estão desenvolvendo nessa situação podem ficar satisfeitas com um simples conjunto de "casos de uso" que explicam quais cenários provavelmente não funcionarão.

Isso é principalmente lixo político e não raciocínio técnico real aqui. Espero que um dos outros mecanismos de contêiner seja ativado e eu possa trocar o kubernetes para usá-lo. Então não terei mais que lidar com esse lixo.

@NdubisiOnuora , que tipo de seu aplicativo? aplicação web?

Eu tenho 2 aplicativos de console (tcp-server no host e tcp-client no contêiner).
Porque eles usam tcp, eu preciso exatamente de IP ( docker.for.win.localhost não cabe, porque é domínio).

Por exemplo, qual ip:port devo definir no tcp-client, se eu definir ip:port 127.0.0.1:9595 no tcp-server?

Basta resolver o domínio para um endereço IP?

@orf ,
Eu quero usar este código em C#:
IPAddress hostAddr = Dns.Resolve("docker.for.win.localhost").AddressList[0];
Mas antes disso eu tento pingar para docker.for.win.localhost , mas não vejo isso, erro: Ping request could not find host docker.for.win.localhost. Please check the name and try again.
Meu Dockerfile:
FROM microsoft/windowsservercore
ADD . /
ENTRYPOINT powershell ping docker.for.win.localhost

Caso alguém tenha perdido, acredito que a solução a partir de 18.03 seja host.docker.internal embora por algum motivo isso funcione apenas no Docker para Windows!? Por que não outros?

EDIT: Não vi que os comentários foram recolhidos pelo Github... 🤦‍♂️

Funciona para mim:
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 Isso funciona para um shell, mas que tal docker-compose.yml ?

Criei um container para resolver esse problema de forma genérica trabalhando em todas as plataformas https://github.com/qoomon/docker-host

Esta página foi útil?
0 / 5 - 0 avaliações