O docker.io DNS não funciona, está tentando usar 8.8.8.8

33

Eu tenho uma nova instalação do Ubuntu 14.04 e quero usar o Docker para executar minhas coisas antigas que precisam da versão 12.04. O DNS no Docker não funciona.

O resolv.conf do meu laptop se parece com:

nameserver 127.0.0.1

O que não funciona com o Docker, aparentemente. Portanto, ele tenta definir os servidores de nomes para 8.8.8.8 e 8.8.4.4; quando eu faço

$ sudo docker run -i -t ubuntu /bin/bash

Diz:

WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it. Using default external servers : [8.8.8.8 8.8.4.4]

E com certeza, dentro da instância do Docker, o resolv.conf se parece com:

nameserver 8.8.8.8
nameserver 8.8.4.4

Posso fazer ping de ambos com êxito na instância do Docker. No entanto, não há DNS (por exemplo, ping google.comfalha).

Saída ifconfig dentro do Docker:

eth0      Link encap:Ethernet  HWaddr aa:e9:9f:83:9d:92  
          inet addr:172.17.0.2  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::a8e9:9fff:fe83:9d92/64 Scope:Link
          UP BROADCAST RUNNING  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:648 (648.0 B)  TX bytes:738 (738.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

O que agora?

RemcoGerlich
fonte

Respostas:

23

Quando o pacote Ubuntu Docker foi atualizado para usar o systemd, ele abandonou o suporte ao /etc/default/dockerarquivo de configuração, então a solução inicial sugerida por rocketman10404 não funcionará mais (a desativação dnsmasqainda funcionaria, mas tem a desvantagem de impedir que o Ubuntu atualize automaticamente o servidor DNS) .

Corrigindo o novo daemon.jsonarquivo de configuração

Encontre o servidor DNS da sua rede:

$ nmcli dev show | grep 'IP4.DNS'
IP4.DNS[1]:                             10.0.0.2

Abra ou crie, se não existir, /etc/docker/daemon.jsone adicione configurações de DNS à ExecStartlinha:

# /etc/docker/daemon.json
{
    "dns": ["10.0.0.2", "8.8.8.8"]
}

Reinicie o daemon do docker:

$ sudo service docker restart

Escrevi uma postagem detalhada no blog e também registrei um bug sobre esse problema, se você quiser obter mais detalhes.

(Originalmente, eu o resolvi abrindo /lib/systemd/system/docker.service e adicionei configurações de DNS à linha ExecStart , mas isso é ruim - não devemos editar arquivos systemd diretamente .)

Robin Winslow
fonte
Obrigado pela sua solução - foi útil no caminho que segui para a minha solução - que eu acho que é uma correspondência um pouco mais elegante para minhas próprias circunstâncias e as peculiaridades de executar o Docker no Ubuntu (ou outras distros de área de trabalho que usam o NetworkManager + dnsmasq).
Adrian
16

Eu mesmo não uso o docker, por isso normalmente não me intrometeria em uma pergunta sobre o docker, mas estava lendo sobre isso e me deparei com alguma documentação do docker que parece resolver esse problema exato . Resumindo...

A documentação sugere algumas soluções alternativas. A primeira é especificar o servidor DNS a ser usado pelo daemon do docker para os contêineres, adicionando a seguinte linha a /etc/default/docker:

docker_OPTS="--dns 8.8.8.8"

onde o DNS fornecido pode ser um servidor DNS local, como 192.168.1.1 (gateway). Em seguida, reinicie com

sudo restart docker

Uma solução alternativa envolve desabilitar o dnsmasq no NetworkManager, comentando a configuração da seguinte /etc/NetworkManager/NetworkManager.confmaneira:

#dns=dnsmasq

depois, reinicie os dois

sudo restart network-manager
sudo restart docker
rocketman10404
fonte
3
desativar dnsmasq funcionou para mim.
bennyl
2
Essa última abordagem obviamente significa que o gerente de rede não pode controlar o dnsmasq, o que significa, por exemplo, que ele não pode alterar o servidor DNS quando você muda de rede, incluindo a mudança para uma VPN. A abordagem anterior me parece melhor, mas eu gostaria que o dnsmasq também escutasse o IP do docker (172.17.0.1) para que eu possa apontar os hosts do docker para isso.
Mc0e 22/03/16
1
Como o Ubuntu mudou para a configuração do Docker com o sytemd, /etc/default/dockernão tem mais efeito. Veja minha solução para saber como resolver isso em um mundo pós-init.d / upstart.
21816 Robin Winslow
/etc/NetworkManager/NetworkManager.confnão existe no Ubuntu 18.04 LTS. : /
XtraSimplicity
Observe que em algumas configurações do Ubuntu 18.04 (por exemplo, a imagem mínima na Amazon) systemd-resolvedestá agindo como um servidor DNS em cache por padrão e provocará o WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it.problema (as configurações do Ubuntu 16.04 não parecem habilitá-lo por padrão). A solução alternativa é desativar systemd-resolvedou usar a --dnsopção ao iniciar o contêiner, conforme mencionado na resposta principal.
Anon
9

Eu me deparei com isso na minha situação, que é especificamente

  • Executando contêineres do Docker na minha máquina de desenvolvimento local
  • O qual está conectado a uma VPN
  • Alguns de nossos scripts de construção de contêiner fazem coisas como executar a npm installpartir de um repositório personalizado na VPN , dentro do contêiner.
    • Isso funciona a partir de um pipeline de IC, mas não de nossas máquinas de desenvolvedor, porque npmnão é possível fazer uma pesquisa de DNS bem-sucedida
    • Também tivemos problemas com contêineres que precisam fazer pesquisas para chamar APIs REST externas

O Ubuntu, por padrão, usa dnsmasqo NetworkManager para armazenar solicitações de DNS em cache e configura /etc/resolv.confpara apontar para esta instância em127.0.1.1

  • O cliente VPN que estamos usando não é compatível com o NetworkManager e força o seu próprio /etc/resolv.confque substitui a configuração do NetworkManager
  • Isso configura os servidores DNS para a VPN
  • /etc/resolv.confPor padrão, o Docker dá sombras ao contêiner
    • Geralmente no Ubuntu, ele passa os servidores DNS do Google para o contêiner (porque conhece a dnsmasqsituação.
    • Mas é um prazer passar a configuração do servidor DNS da VPN para o contêiner
    • Não há rota do contêiner na docker0ponte de rede para os servidores DNS pelo tap0adaptador VPN .
  • Portanto, todas as pesquisas de DNS no contêiner falham porque não conseguem alcançar os únicos servidores DNS com os quais são fornecidos
  • Além disso, algumas redes bloqueiam solicitações aos servidores DNS do Google, porque desejam poder bisbilhotar todas as suas pesquisas de DNS

A solução :

Parece mais elegante usar o NetworkManager e sua dnsmasqinstância cativa da maneira como foi projetada.

  1. Diga ao Docker para usar sua dnsmasqinstância para DNS

    • Adicione ou edite o arquivo /etc/docker/daemon.jsonpara instruir o Docker a usar o docker0adaptador de ponte para DNS

      {
        "dns": ["172.17.0.1"]
      }
      
  2. Configure a dnsmasqinstância do NM para escutar também as pontes do Docker, porque, por padrão, apenas escuta 127.0.1.1 - criar arquivo/etc/NetworkManager/dnsmasq.d/docker-bridge.conf

    # Default Docker bridge
    interface=docker0
    # Other Docker bridges
    interface=br-*
    
  3. Não gosto do comportamento rude desse cliente VPN e prefiro usar apenas o DNS no final da VPN para pesquisas VPN (se você tiver um cliente VPN educado que use o NetworkManager configurado corretamente, não precisará fazer isso )

    • Desative o recurso DNS no cliente VPN (ele pára de sobrescrever resolv.confna conexão e agora todo o DNS passa dnsmasqnovamente)
    • Adicione um arquivo de configuração dnsmasqpara direcionar as solicitações DNS apropriadas para o seu domínio - adicione o arquivo `/etc/NetworkManager/dnsmasq.d/vpn-dns.conf

      server=/myprivatedomain.net/10.0.0.1  
      # or whatever your private DNS server is
      
    • Opcionalmente, adicione um domínio de pesquisa ao seu domínio para poder usar nomes abreviados

      • Acabei de adicionar nosso domínio local à lista de pesquisa na minha conexão de rede padrão
  4. Reinicie o NetworkManager e o Docker

    sudo service network-manager restart
    sudo service docker restart
    

Nesse ponto, seus contêineres do Docker devem poder ficar nslookupsem problemas quando você estiver na VPN, para domínios dentro e fora da sua VPN.

Adrian
fonte
1
Um pequeno puxão que não envolve embutir a ponte docker0 IP é usar a relação, em vez do ouvir-address directiva: interface = docker0
siwyd
Explicações e instruções impressionantes. Um +1 bem merecido.
ereOn
Felicidades @simonwydooghe - incorporei sua sugestão - você também pode usar caracteres curinga nesse campo, então adicionei um padrão para todos os nomes de pontes usados ​​por redes não padrão (pelo menos, como usado pelo docker-compose).
Adrian
1
Parece que o valor dns no daemon.json deve ser uma matriz, caso contrário, recebo um erro: cannot unmarshal string into Go value of type []stringao reiniciar o serviço docker.
Slaven Rezic 15/09/19
A atualização para Bionic: 18.04 não usa mais uma instância cativa do dnsmasq gerenciada pelo NetworkManager para DNS e, em vez disso, usa resolvido pelo sistema; o que traz seus próprios problemas, porque isso não pode ser configurado para escutar a ponte docker0. Tentei desabilitá-lo e reinstalar o NetworkManager dnsmasq e configurá-lo corretamente.
Adrian
2

Aqui está como eu configuro o docker no meu servidor Ubuntu 14.04 rodando sem cabeça.

Estou executando o servidor Ubuntu 14.04 com a seguinte versão do docker instalada.

#docker version
Client version: 0.9.1
Go version (client): go1.2.1
Git commit (client): 3600720
Server version: 0.9.1
Git commit (server): 3600720
Go version (server): go1.2.1

O arquivo /etc/init/docker.io.conf e o script contém a seguinte linha:

# modify these in /etc/default/$UPSTART_JOB (/etc/default/docker)
    DOCKER=/usr/bin/$UPSTART_JOB
    DOCKER_OPTS=

A resposta acima me ajudou a encontrar o arquivo acima.

Descomentei o seguinte em /etc/default/docker.io e adicionei meu servidor DNS local:

# Use DOCKER_OPTS to modify the daemon startup options.  
DOCKER_OPTS="--dns 192.168.X.X"

Reiniciou o serviço com:

sudo service docker.io restart

Correu docker run <image> /bin/bash

Nenhuma mensagem DNS ao iniciar o contêiner.

Iniciou um novo contêiner, instalou o dnsutils.

Ran dig e a mensagem do servidor é o servidor DNS local correto.

Hank
fonte
0

Eu tive um problema semelhante, relatei ao StackOverflow . Parece que não pude consultar o 8.8.8.8servidor de nomes especificado na instalação padrão do Ubuntu do Docker; no entanto, eu poderia fazer ping. Nesse caso, use um servidor DNS que você possa realmente consultar. Teste com

nslookup - dns.server.name

e inicie o contêiner via

docker run --dns=ip.addr.of.dns

Ainda tenho que encontrar uma maneira de https://askubuntu.com/q/607172/30266 para derivar uma solução automagic.

krlmlr
fonte
Minha resposta pode ser suficiente automagic para você ...
Adrian
0

Você pode usar o resolvedor DNS local do host (por exemplo dnsmasq) nos contêineres do Docker se eles estiverem em uma rede definida pelo usuário . Nesse caso, o contêiner /etc/resolv.confterá o servidor de nomes 127.0.0.11(também conhecido como servidor DNS incorporado do Docker ), que pode encaminhar solicitações DNS para o endereço de loopback do host corretamente.

$ cat /etc/resolv.conf
nameserver 127.0.0.1
$ docker run --rm alpine cat /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4
$ docker network create demo
557079c79ddf6be7d6def935fa0c1c3c8290a0db4649c4679b84f6363e3dd9a0
$ docker run --rm --net demo alpine cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0    

Se você usar docker-compose, ele configurará uma rede personalizada para seus contêineres automaticamente (com um formato de arquivo v2 + ). Observe, no entanto, que enquanto docker-composeexecuta contêineres em uma rede definida pelo usuário, ele ainda os cria na rede padrão . Para usar uma rede customizada para construções, você pode especificar o networkparâmetro na configuração de construção (requer o formato de arquivo v3.4 + ).

Eugene Yarmash
fonte