Le DNS de docker.io ne fonctionne pas, il essaye d'utiliser 8.8.8.8

33

Je viens d'installer une nouvelle Ubuntu 14.04 et je veux utiliser Docker pour exécuter mes anciennes choses nécessitant 12.04. Le DNS à l'intérieur de Docker ne fonctionne pas.

Le resolv.conf de mon ordinateur portable ressemble à:

nameserver 127.0.0.1

Ce qui ne fonctionne pas avec Docker, apparemment. Il essaie donc de définir les serveurs de noms sur 8.8.8.8 et 8.8.4.4; quand je fais

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

Ça dit:

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]

Et bien sûr, dans l'instance de Docker, resolv.conf ressemble à:

nameserver 8.8.8.8
nameserver 8.8.4.4

Je peux cingler avec succès les deux à partir de l'instance Docker. Cependant, il n'y a pas de DNS (par exemple, ping google.coméchec).

Sortie ifconfig dans 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)

Maintenant quoi?

RemcoGerlich
la source

Réponses:

23

Lorsque le paquet Ubuntu Docker a été mis à jour pour utiliser systemd, il a cessé de prendre en charge le /etc/default/dockerfichier de configuration, de sorte que la solution initiale suggérée par rocketman10404 ne fonctionnera plus (la désactivation dnsmasqfonctionnerait toujours, mais elle empêchait Ubuntu de mettre à jour automatiquement le serveur DNS). .

Correction dans le nouveau daemon.jsonfichier de configuration

Recherchez le serveur DNS de votre réseau:

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

Ouvrez ou créez, s'il n'existe pas, /etc/docker/daemon.jsonet ajoutez des paramètres DNS à la ExecStartligne:

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

Redémarrez le démon docker:

$ sudo service docker restart

J'ai écrit un article de blog détaillé et j'ai également déposé un bogue sur ce problème si vous souhaitez plus de détails.

(À l'origine, je l'ai résolu en ouvrant /lib/systemd/system/docker.service et en ajoutant des paramètres DNS à la ligne ExecStart , mais c'est dommage - nous ne devrions pas éditer directement les fichiers systemd .)

Robin Winslow
la source
Merci pour votre solution - cela a été utile sur la route que j’ai choisie - ce qui, à mon avis, correspond mieux à mon contexte et aux particularités de l’exécution de Docker sur Ubuntu (ou d’autres distributions de bureau utilisant NetworkManager + dnsmasq).
Adrian
16

Je n'utilise pas moi-même le docker, je ne m'occuperais donc pas normalement d'une question à propos du docker, mais je suis tombé sur le sujet et je suis tombé sur une documentation du docker qui semble régler exactement ce problème . Pour résumer...

La documentation suggère quelques solutions de contournement. La première consiste à spécifier le serveur DNS devant être utilisé par le démon docker pour les conteneurs en ajoutant la ligne suivante à /etc/default/docker:

docker_OPTS="--dns 8.8.8.8"

où le DNS fourni pourrait être un serveur DNS local, tel que 192.168.1.1 (passerelle). Ensuite, redémarrez avec

sudo restart docker

Une solution alternative consiste à désactiver Dnsmasq dans NetworkManager en commentant la configuration de la /etc/NetworkManager/NetworkManager.confmanière suivante:

#dns=dnsmasq

puis, redémarrez les deux

sudo restart network-manager
sudo restart docker
rocketman10404
la source
3
désactiver Dnsmasq a fonctionné pour moi.
bennyl
2
Cette dernière approche signifie bien entendu que le gestionnaire de réseau ne peut pas contrôler Dnsmasq, ce qui signifie par exemple qu’il ne peut pas changer votre serveur DNS lorsque vous changez de réseau, y compris le passage à un VPN. L'ancienne approche me semble meilleure, mais j'aimerais pouvoir faire en sorte que dnsmasq écoute également sur l'IP du docker (172.17.0.1) afin que je puisse pointer les hôtes des dockers à cet égard.
mc0e
1
Depuis que Ubuntu est passé à configurer Docker avec sytemd, il /etc/default/dockern’a plus d’effet. Voir ma solution pour savoir comment résoudre ce problème dans un monde post-init.d / upstart.
Robin Winslow
/etc/NetworkManager/NetworkManager.confn'existe pas sur Ubuntu 18.04 LTS. : /
XtraSimplicity
Notez qu'avec certaines configurations Ubuntu 18.04 (par exemple, l'image minimale sur Amazon), systemd-resolvedle serveur DNS en cache agit par défaut et provoque le WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it.problème (les configurations Ubuntu 16.04 ne semblent pas l'activer par défaut). La solution de contournement consiste à désactiver systemd-resolvedou à utiliser l' --dnsoption lors du démarrage du conteneur comme indiqué dans la réponse principale.
Anon
9

Je me suis heurté à cela dans ma situation qui est spécifiquement

  • Exécution de conteneurs Docker sur ma machine de développement locale
  • Qui est connecté à un VPN
  • Certains de nos scripts de construction de conteneur exécutent npm installdes tâches telles que celles exécutées à partir d'un référentiel personnalisé sur le VPN , à l'intérieur du conteneur.
    • Cela fonctionne à partir d'un pipeline de CI mais pas à partir de nos machines de développement, car npmune recherche DNS réussie est impossible.
    • Nous avons également rencontré des problèmes avec les conteneurs nécessitant des recherches pour appeler des API REST externes.

Ubuntu utilise par défaut, dnsmasqdémarré par NetworkManager, pour mettre en cache les requêtes DNS et configure /etc/resolv.confpour pointer vers cette instance sur127.0.1.1

  • Le client VPN que nous utilisons n’est pas compatible avec NetworkManager et force le sien, /etc/resolv.confce qui écrase la configuration de NetworkManager.
  • Ceci configure les serveurs DNS pour le VPN
  • Docker fait de l'ombre /etc/resolv.confau conteneur par défaut
    • Habituellement sous Ubuntu, il transmet les serveurs DNS Google au conteneur (car il connaît la dnsmasqsituation.
    • Mais c'est un plaisir de passer la configuration du serveur DNS VPN au conteneur
    • Il n'y a aucune route du conteneur sur le docker0pont réseau vers les serveurs DNS via l' tap0adaptateur VPN .
  • Ainsi, toutes les recherches DNS dans le conteneur échouent car il ne peut pas atteindre les seuls serveurs DNS fournis.
  • De plus, certains réseaux bloquent les requêtes adressées aux serveurs DNS Google, car ils veulent pouvoir surveiller toutes vos recherches DNS.

La solution :

Il semblerait plus élégant d’utiliser NetworkManager et son dnsmasqinstance captive dans sa conception.

  1. Dites à Docker d'utiliser votre dnsmasqinstance pour DNS

    • Ajouter ou modifier un fichier /etc/docker/daemon.jsonpour indiquer au menu fixe d'utiliser l' docker0adaptateur de pont pour DNS

      {
        "dns": ["172.17.0.1"]
      }
      
  2. Configurez l' dnsmasqinstance NM pour qu'elle écoute également les ponts Docker, car par défaut, elle n'écoute que 127.0.1.1 - create file/etc/NetworkManager/dnsmasq.d/docker-bridge.conf

    # Default Docker bridge
    interface=docker0
    # Other Docker bridges
    interface=br-*
    
  3. Je n'aime pas le comportement grossier de ce client VPN et je préfère utiliser uniquement le DNS à l'extrémité du VPN pour les recherches de VPN (si vous avez un client VPN poli qui utilise NetworkManager correctement configuré, vous n'aurez pas à le faire.) )

    • Désactiver la fonctionnalité DNS dans le client VPN (cela arrête l'écrasement resolv.confà la connexion et maintenant tout le DNS passe à dnsmasqnouveau)
    • Ajoutez un fichier de configuration pour indiquer dnsmasqaux demandes DNS directes de votre domaine - ajoutez le fichier `/etc/NetworkManager/dnsmasq.d/vpn-dns.conf

      server=/myprivatedomain.net/10.0.0.1  
      # or whatever your private DNS server is
      
    • Ajoutez éventuellement un domaine de recherche pour votre domaine afin de pouvoir utiliser des noms abrégés.

      • Je viens d'ajouter notre domaine local à la liste de recherche dans ma connexion réseau par défaut
  4. Redémarrez NetworkManager et Docker

    sudo service network-manager restart
    sudo service docker restart
    

À ce stade, vos conteneurs Docker devraient pouvoir se passer de nslookupproblèmes lorsque vous êtes sur un réseau VPN, pour les domaines à l'intérieur et à l'extérieur de votre réseau.

Adrian
la source
1
Un petit problème qui n'implique pas de coder en dur l'IP du pont docker0 consiste à utiliser l'interface à la place de la directive listen-address: interface = docker0
siwyd
Des explications et des instructions géniales. Un +1 bien mérité.
ereOn
Cheers @simonwydooghe - J'ai incorporé votre suggestion - vous pouvez également utiliser des caractères génériques dans ce champ. J'ai donc ajouté un motif pour tous les noms de pont utilisés par les réseaux autres que ceux par défaut (du moins, comme utilisé par docker-compose).
Adrian
1
Il semble que la valeur DNS dans daemon.json doit être un tableau, sinon je reçois une erreur: cannot unmarshal string into Go value of type []stringlors du redémarrage du service Docker.
Slaven Rezic
Mise à jour pour Bionic: 18.04 n'utilise plus une instance captive de Dnsmasq gérée par NetworkManager pour DNS mais utilise plutôt la résolution systemd; ce qui pose ses propres problèmes, car cela ne peut pas être configuré pour écouter le pont docker0. J'ai eu recours à sa désactivation, à la réinstallation du dnsmasq de NetworkManager et à sa configuration correcte.
Adrian
2

Voici comment j'ai installé docker sur mon serveur Ubuntu 14.04 fonctionnant sans tête.

J'exécute le serveur Ubuntu 14.04 avec la version suivante de docker installée.

#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

Le fichier /etc/init/docker.io.conf et le script contiennent la ligne suivante:

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

La réponse ci-dessus m'a aidé à trouver le fichier ci-dessus.

J'ai supprimé les commentaires suivants dans /etc/default/docker.io et ajouté mon serveur DNS local:

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

Redémarrage du service avec:

sudo service docker.io restart

A couru docker run <image> /bin/bash

Aucun message DNS lors du démarrage du conteneur.

Commencé un nouveau conteneur, installé dnsutils.

Ran dig et le message du serveur est le serveur DNS local correct.

Hank
la source
0

J'ai eu un problème similaire, signalé à StackOverflow . Il semble que je n’ai pas pu interroger le 8.8.8.8serveur de noms spécifié dans l’installation par défaut de Docker sous Ubuntu; Cependant, je pourrais faire un ping. Dans ce cas, utilisez un serveur DNS sur lequel vous pouvez réellement interroger. Test avec

nslookup - dns.server.name

et démarrez le conteneur via

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

Je n'ai pas encore trouvé de moyen de https://askubuntu.com/q/607172/30266 pour dériver une solution automagic.

krlmlr
la source
Ma réponse est peut-être assez automagique pour vous ...
Adrian
0

Vous pouvez utiliser le résolveur DNS local de l'hôte (par exemple dnsmasq) à partir de vos conteneurs Docker s'ils se trouvent sur un réseau défini par l'utilisateur . Dans ce cas, un conteneur /etc/resolv.confaura le serveur de noms 127.0.0.11(le serveur DNS intégré du Docker ), qui peut transférer correctement les demandes DNS à l'adresse de bouclage de l'hôte.

$ 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 vous utilisez docker-compose, il va configurer automatiquement un réseau personnalisé pour vos conteneurs (avec un format de fichier v2 + ). Notez cependant que même s'il docker-composeexécute des conteneurs dans un réseau défini par l'utilisateur, il les construit toujours dans le réseau par défaut . Pour utiliser un réseau personnalisé pour les constructions, vous pouvez spécifier le networkparamètre dans la configuration de la construction (nécessite le format de fichier v3.4 + ).

Eugene Yarmash
la source