Como obter o endereço IP do host do docker dentro de um contêiner docker

Como o título diz. Preciso recuperar o endereço IP que o docker hospeda e os portmaps do host para o contêiner e fazer isso dentro do contêiner.

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

Como o @MichaelNeale notou, não faz sentido usar esse método no Dockerfile (exceto quando precisarmos desse IP durante o tempo de compilation apenas), porque esse IP será codificado durante o tempo de compilation.

No Docker para Mac , a partir da versão 18.03, você pode usar o host.docker.internal como o IP do host.

Observe, como na documentação , “Isto é para propósito de desenvolvimento [s] e não funcionará em um ambiente de produção fora do Docker para Mac.” Isso ocorre porque, no Docker para Mac, “não é possível ver uma interface docker0 no host. Essa interface está realmente dentro da máquina virtual”.

Esta é uma atualização do docker.for.mac.localhost , disponível desde a versão 17.06, e docker.for.mac.host.internal , disponível desde a versão 17.12, que também pode funcionar.

Por exemplo, tenho variables ​​de ambiente definidas no meu host:

 MONGO_SERVER=host.docker.internal 

No meu arquivo docker-compose.yml , tenho isto:

 version: '3' services: api: build: ./api volumes: - ./api:/usr/src/app:ro ports: - "8000" environment: - MONGO_SERVER command: /usr/local/bin/gunicorn -c /usr/src/app/gunicorn_config.py -w 1 -b :8000 wsgi 

Atualização: no Docker para Mac , a partir da versão 18.03, você pode usar o host.docker.internal como o IP do host. Veja a resposta de allanberry . Para versões anteriores do Docker para Mac, a seguinte resposta ainda pode ser útil:

No Docker para Mac, a ponte docker0 não existe, portanto, outras respostas aqui podem não funcionar. Todo o tráfego de saída, no entanto, é roteado através de seu host pai, portanto, desde que você tente se conectar a um IP, ele reconhece como ele mesmo (e o contêiner docker não pensa em si), você deve poder se conectar. Por exemplo, se você executar isso a partir da máquina pai, execute:

 ipconfig getifaddr en0 

Isso deve mostrar o IP do seu Mac em sua rede atual e o contêiner do docker também deve poder se conectar a esse endereço. É claro que isso é um problema se esse endereço IP mudar, mas você pode adicionar um IP de loopback personalizado ao seu Mac que o contêiner não pensa que está fazendo algo parecido com isso na máquina principal:

 sudo ifconfig lo0 alias 192.168.46.49 

Você pode então testar a conexão a partir do contêiner docker com o telnet. No meu caso eu queria me conectar a um servidor xdebug remoto:

 telnet 192.168.46.49 9000 

Agora, quando o tráfego entrar em seu Mac endereçado para 192.168.46.49 (e todo o tráfego que deixa seu contêiner passar pelo Mac), seu Mac assumirá que o IP é ele mesmo. Quando você terminar de usar este IP, você pode remover o alias de loopback assim:

 sudo ifconfig lo0 -alias 192.168.46.49 

Uma coisa a ser cuidadosa é que o contêiner docker não enviará tráfego para o host pai se achar que o destino do tráfego é ele mesmo. Então, verifique a interface de loopback dentro do contêiner se você tiver problemas:

 sudo ip addr show lo 

No meu caso, isso mostrou inet 127.0.0.1/8 que significa que não pude usar nenhum IP no intervalo 127.* . É por isso que usei 192.168.* no exemplo acima. Verifique se o IP que você usa não entra em conflito com algo em sua própria rede.

Para aqueles que executam o Docker no AWS, os metadados da instância para o host ainda estão disponíveis dentro do contêiner.

 curl http://169.254.169.254/latest/meta-data/local-ipv4 

Por exemplo:

 $ docker run alpine /bin/sh -c "apk update ; apk add curl ; curl -s http://169.254.169.254/latest/meta-data/local-ipv4 ; echo" fetch http://dl-cdn.alpinelinux.org/alpine/v3.3/main/x86_64/APKINDEX.tar.gz fetch http://dl-cdn.alpinelinux.org/alpine/v3.3/community/x86_64/APKINDEX.tar.gz v3.3.1-119-gb247c0a [http://dl-cdn.alpinelinux.org/alpine/v3.3/main] v3.3.1-59-g48b0368 [http://dl-cdn.alpinelinux.org/alpine/v3.3/community] OK: 5855 distinct packages available (1/4) Installing openssl (1.0.2g-r0) (2/4) Installing ca-certificates (20160104-r2) (3/4) Installing libssh2 (1.6.0-r1) (4/4) Installing curl (7.47.0-r0) Executing busybox-1.24.1-r7.trigger Executing ca-certificates-20160104-r2.trigger OK: 7 MiB in 15 packages 172.31.27.238 $ ifconfig eth0 | grep -oP 'inet addr:\K\S+' 172.31.27.238 

A única maneira é passar as informações do host como ambiente quando você cria um contêiner

 run --env = 

O --add-host poderia ser uma solução mais limpa (mas sem a parte de porta, somente o host pode ser tratado com essa solução). Então, no seu comando docker run , faça algo como:

 docker run --add-host dockerhost:`/sbin/ip route|awk '/default/ { print $3}'` [my container] 

(De https://stackoverflow.com/a/26864854/127400 )

Docker para Mac Eu quero conectar de um contêiner a um serviço no host

O host possui um endereço IP de alteração (ou nenhum caso você não tenha access à rede). A partir de 18.03, nossa recomendação é conectar ao nome DNS especial host.docker.internal, que resolve o endereço IP interno usado pelo host.

O gateway também é acessível como gateway.docker.internal. https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds

Se você ativou a API remota do docker (via -H tcp://0.0.0.0:4243 por exemplo) e sabe o nome do host ou o endereço IP da máquina host, isso pode ser feito com muito bash.

Dentro do bashrc do meu contêiner:

 export hostIP=$(ip r | awk '/default/{print $3}') export containerID=$(awk -F/ '/docker/{print $NF;exit;}' /proc/self/cgroup) export proxyPort=$( curl -s http://$hostIP:4243/containers/$containerID/json | node -pe 'JSON.parse(require("fs").readFileSync("/dev/stdin").toString()).NetworkSettings.Ports["DESIRED_PORT/tcp"][0].HostPort' ) 

A segunda linha pega o ID do container do seu arquivo local /proc/self/cgroup .

A terceira linha se curva para a máquina host (supondo que você esteja usando 4243 como porta do docker) e, em seguida, usa o nó para analisar o JSON retornado para o DESIRED_PORT .

Aqui está outra opção para aqueles que executam o Docker no AWS. Esta opção evita usar o apk para adicionar o pacote curl e economiza os preciosos 7mb de espaço. Use o wget interno (parte do binário monolítico do BusyBox):

 wget -q -O - http://169.254.169.254/latest/meta-data/local-ipv4 

Se você estiver executando um contêiner Windows em um cluster do Service Fabric, o endereço IP do host estará disponível por meio da variável de ambiente Fabric_NodeIPOrFQDN . Variáveis ​​de ambiente do Service Fabric

No linux você pode correr

 HOST_IP=`hostname -I | awk '{print $1}'` 

No macOS, sua máquina host não é o host do Docker. O Docker instalará seu sistema operacional host no VirtualBox.

 HOST_IP=`docker run busybox ping -c 1 docker.for.mac.localhost | awk 'FNR==2 {print $4}' | sed s'/.$//'` 

Aqui está como eu faço isso. Nesse caso, ele adiciona uma input de hosts em / etc / hosts na imagem do docker apontando taurus-host para o IP da minha máquina local:

 TAURUS_HOST=`ipconfig getifaddr en0` docker run -it --rm -e MY_ENVIRONMENT='local' --add-host "taurus-host:${TAURUS_HOST}" ... 

Em seguida, a partir do contêiner do Docker, o script pode usar o nome do host taurus-host para sair da máquina local que hospeda o contêiner do Docker.

Com https://docs.docker.com/machine/install-machine/

a) $ docker-machine ip

b) Obtenha o endereço IP de uma ou mais máquinas.

  $ docker-machine ip host_name $ docker-machine ip host_name1 host_name2