docker.io DNS no funciona, está tratando de usar 8.8.8.8

33

Tengo una nueva instalación de Ubuntu 14.04 y quiero usar Docker para ejecutar mis cosas viejas que necesitan 12.04. El DNS dentro de Docker no funciona.

El resolv.conf de mi computadora portátil se ve así:

nameserver 127.0.0.1

Lo cual no funciona con Docker, aparentemente. Por lo tanto, intenta establecer los servidores de nombres en 8.8.8.8 y 8.8.4.4; Cuando lo hago

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

Dice:

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]

Y efectivamente, dentro de la instancia de Docker, resolv.conf se ve así:

nameserver 8.8.8.8
nameserver 8.8.4.4

Puedo hacer ping a ambos con éxito desde la instancia de Docker. Sin embargo, no hay DNS (por ejemplo, ping google.comfalla).

Salida de ifconfig dentro de 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)

¿Ahora que?

RemcoGerlich
fuente

Respuestas:

23

Cuando el paquete Ubuntu Docker se actualizó para usar systemd, dejó de admitir el /etc/default/dockerarchivo de configuración, por lo que la solución inicial sugerida por rocketman10404 ya no funcionará (la desactivación dnsmasqaún funcionaría, pero tiene la desventaja de evitar que Ubuntu actualice automáticamente el servidor DNS) .

Arreglando en el nuevo daemon.jsonarchivo de configuración

Encuentra el servidor DNS de tu red:

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

Abra o cree, si no existe, /etc/docker/daemon.jsony agregue la configuración de DNS a la ExecStartlínea:

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

Reinicia el docker daemon:

$ sudo service docker restart

Escribí una publicación de blog en profundidad y también presenté un error sobre este problema si desea obtener más detalles.

(Originalmente lo resolví abriendo /lib/systemd/system/docker.service y agregué la configuración de DNS a la línea ExecStart , pero eso es malo, no deberíamos editar archivos systemd directamente ).

Robin Winslow
fuente
Gracias por su solución, fue útil en el camino que tomé hacia mi solución, que creo que es una combinación un poco más elegante para mis propias circunstancias y las peculiaridades de ejecutar Docker en Ubuntu (u otras distribuciones de escritorio que usan NetworkManager + dnsmasq).
Adrian
16

No uso Docker yo mismo, por lo que normalmente no me toparía aquí con una pregunta de Docker, pero estaba leyendo sobre eso y me topé con alguna documentación de Docker que parece abordar este problema exacto . Para resumir...

La documentación sugiere algunas soluciones alternativas. El primero es especificar el servidor DNS que utilizará el demonio de Docker para los contenedores agregando la siguiente línea a /etc/default/docker:

docker_OPTS="--dns 8.8.8.8"

donde el DNS proporcionado podría ser un servidor DNS local, como 192.168.1.1 (puerta de enlace). Luego, reinicie con

sudo restart docker

Una solución alternativa implica deshabilitar dnsmasq en NetworkManager comentando la configuración de la siguiente /etc/NetworkManager/NetworkManager.confmanera:

#dns=dnsmasq

luego, reinicie ambos

sudo restart network-manager
sudo restart docker
rocketman10404
fuente
3
deshabilitar dnsmasq funcionó para mí.
bennyl
2
Este último enfoque, por supuesto, significará que el administrador de red no puede controlar dnsmasq, lo que significa, por ejemplo, que no puede cambiar su servidor dns cuando cambia la red, incluido el cambio a una VPN. El primer enfoque me parece mejor, pero me gustaría poder hacer que dnsmasq también escuche en el docker IP (172.17.0.1) para poder señalar los hosts de docker en eso.
mc0e
1
Desde que Ubuntu cambió a configurar Docker con sytemd, /etc/default/dockerya no tiene ningún efecto. Vea mi solución sobre cómo resolver esto en un mundo post-init.d / upstart.
Robin Winslow
/etc/NetworkManager/NetworkManager.confno existe en Ubuntu 18.04 LTS. : /
XtraSimplicity
Tenga en cuenta que con algunas configuraciones de Ubuntu 18.04 (por ejemplo, la imagen mínima en Amazon) systemd-resolvedestá actuando como un servidor DNS de almacenamiento en caché de forma predeterminada y provocará el WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it.problema (las configuraciones de Ubuntu 16.04 no parecen habilitarlo de manera predeterminada). La solución alternativa es desactivar systemd-resolvedo usar la --dnsopción al iniciar el contenedor como se menciona en la respuesta principal.
Anon
9

Me encontré con esto en mi situación, que es específicamente

  • Ejecutar contenedores Docker en mi máquina de desarrollo local
  • Que está conectado a una VPN
  • Algunos de nuestros scripts de compilación de contenedores hacen cosas como ejecutarse npm installdesde un repositorio personalizado en la VPN , dentro del contenedor.
    • Esto funciona desde una canalización de CI pero no desde nuestras máquinas de desarrollo, porque npmno puede hacer una búsqueda de DNS exitosa
    • También tuvimos problemas con los contenedores que necesitan realizar búsquedas para llamar a API REST externas

Ubuntu utiliza de manera predeterminada dnsmasqiniciado por NetworkManager para almacenar en caché las solicitudes de DNS y se configura /etc/resolv.confpara apuntar a esta instancia en127.0.1.1

  • El cliente VPN que estamos utilizando no es compatible con NetworkManager y obliga a que sea propio, lo /etc/resolv.confque sobrescribe la configuración de NetworkManager
  • Esto configura los servidores DNS para la VPN
  • Docker sombrea tu /etc/resolv.confal contenedor por defecto
    • Por lo general, en Ubuntu, pasa los servidores DNS de Google al contenedor (porque conoce la dnsmasqsituación.
    • Pero es feliz pasar la configuración del servidor DNS VPN al contenedor
    • No hay una ruta desde el contenedor en el docker0puente de red a los servidores DNS a través del tap0adaptador VPN .
  • Ergo, todas las búsquedas de DNS en el contenedor fallan porque no puede llegar a los únicos servidores DNS con los que se suministra
  • Además, algunas redes bloquean las solicitudes a los servidores DNS de Google porque quieren poder espiar todas sus búsquedas de DNS

La solución :

Parece ser más elegante usar NetworkManager y es una dnsmasqinstancia cautiva en la forma en que fue diseñado.

  1. Dile a Docker que use tu dnsmasqinstancia para DNS

    • Agregue o edite el archivo /etc/docker/daemon.jsonpara indicarle a Docker que use el docker0adaptador de puente para DNS

      {
        "dns": ["172.17.0.1"]
      }
      
  2. Configure la dnsmasqinstancia de NM para escuchar también los puentes de Docker, porque de forma predeterminada solo escucha 127.0.1.1 - crear archivo/etc/NetworkManager/dnsmasq.d/docker-bridge.conf

    # Default Docker bridge
    interface=docker0
    # Other Docker bridges
    interface=br-*
    
  3. No me gusta el comportamiento grosero de ese cliente VPN y prefiero usar solo el DNS en el extremo VPN para las búsquedas VPN (si tiene un cliente VPN educado que usa NetworkManager configurado correctamente, no tendrá que hacer esto )

    • Desactive la función DNS en el cliente VPN (deja de sobrescribirse resolv.confen la conexión y ahora todo el DNS vuelve a pasar dnsmasq)
    • Agregue un archivo de configuración para indicarle dnsmasqque dirija las solicitudes de DNS para su dominio de manera apropiada: agregue el archivo `/etc/NetworkManager/dnsmasq.d/vpn-dns.conf

      server=/myprivatedomain.net/10.0.0.1  
      # or whatever your private DNS server is
      
    • Opcionalmente, agregue un dominio de búsqueda para su dominio para que pueda usar nombres cortos

      • Acabo de agregar nuestro dominio local a la lista de búsqueda en mi conexión de red predeterminada
  4. Reinicie NetworkManager y Docker

    sudo service network-manager restart
    sudo service docker restart
    

En este punto, sus contenedores Docker deberían poder funcionar nslookupsin problemas cuando esté en VPN, para dominios tanto dentro como fuera de su VPN.

Adrian
fuente
1
Una pequeña modificación que no implica la codificación rígida de la IP del puente docker0 es utilizar la interfaz en lugar de la directiva de dirección de escucha: interface = docker0
siwyd
Impresionantes explicaciones e instrucciones. A +1 bien merecido.
antes del
Saludos @simonwydooghe: he incorporado su sugerencia, también puede usar comodines en ese campo, por lo que he agregado un patrón para todos los nombres de puente utilizados por redes no predeterminadas (al menos, como lo usa docker-compose).
Adrian
1
Parece que el valor de dns en daemon.json tiene que ser una matriz; de lo contrario, aparece un error: cannot unmarshal string into Go value of type []stringal reiniciar el servicio docker.
Slaven Rezic
Actualización para Bionic: 18.04 ya no usa una instancia cautiva de dnsmasq administrada por NetworkManager para DNS y en su lugar usa systemd-resolve; lo que trae sus propios problemas, porque eso no se puede configurar para escuchar el puente docker0. He recurrido a deshabilitarlo, reinstalar el dnsmasq de NetworkManager y configurarlo correctamente.
Adrian
2

Así es como configuré docker en mi servidor Ubuntu 14.04 sin cabeza.

Estoy ejecutando el servidor Ubuntu 14.04 con la siguiente versión acoplada 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

El archivo /etc/init/docker.io.conf y el script contienen la siguiente línea:

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

La respuesta anterior me ayudó a encontrar el archivo anterior.

Descomenté lo siguiente en /etc/default/docker.io y agregué mi servidor DNS local:

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

Reinició el servicio con:

sudo service docker.io restart

Corrió docker run <image> /bin/bash

No hay mensajes dns al iniciar el contenedor.

Comenzó un nuevo contenedor, instaló dnsutils.

Ran dig y el mensaje del servidor es el servidor DNS local correcto.

Madeja
fuente
0

Tuve un problema similar, lo informé a StackOverflow . Parece que no pude consultar el 8.8.8.8servidor de nombres que se especifica en la instalación predeterminada de Ubuntu de Docker; Sin embargo, podría hacer ping. En este caso, use un servidor DNS que realmente pueda consultar. Prueba con

nslookup - dns.server.name

e iniciar el contenedor a través de

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

Todavía tengo que encontrar una manera de https://askubuntu.com/q/607172/30266 para derivar una solución automática.

krlmlr
fuente
Mi respuesta puede ser lo suficientemente automática para ti ...
Adrian
0

Puede usar el solucionador DNS local del host (por ejemplo dnsmasq) de sus contenedores Docker si están en una red definida por el usuario . En ese caso, un contenedor /etc/resolv.conftendrá el servidor de nombres 127.0.0.11(también conocido como el servidor DNS incorporado de Docker ), que puede reenviar correctamente las solicitudes DNS a la dirección de bucle invertido del host.

$ 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    

Si lo usa docker-compose, configurará una red personalizada para sus contenedores automáticamente (con un formato de archivo v2 + ). Sin embargo, tenga en cuenta que si bien docker-composeejecuta contenedores en una red definida por el usuario, aún los construye en la red predeterminada . Para utilizar una red personalizada para compilaciones, puede especificar el networkparámetro en la configuración de compilación (requiere el formato de archivo v3.4 + ).

Eugene Yarmash
fuente