docker.io DNS funktioniert nicht, es wird versucht 8.8.8.8 zu verwenden

33

Ich habe eine neue Ubuntu 14.04-Installation und möchte Docker verwenden, um meine alten Sachen auszuführen, die 12.04 benötigen. DNS in Docker funktioniert nicht.

Die resolv.conf meines Laptops sieht so aus:

nameserver 127.0.0.1

Was bei Docker anscheinend nicht funktioniert. Es wird daher versucht, die Nameserver auf 8.8.8.8 und 8.8.4.4 zu setzen; wenn ich es tue

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

Es sagt:

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]

Und tatsächlich sieht die Datei resolv.conf in der Docker-Instanz folgendermaßen aus:

nameserver 8.8.8.8
nameserver 8.8.4.4

Ich kann beide von der Docker-Instanz aus erfolgreich pingen. Es ist jedoch kein DNS vorhanden (z ping google.com. B. fehlgeschlagen).

ifconfig-Ausgabe in 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)

Was jetzt?

RemcoGerlich
quelle

Antworten:

23

Wenn das Paket Ubuntu Docker aktualisiert Verwendung systemd, fiel es Unterstützung für die /etc/default/dockerConfig - Datei, so dass die Ausgangslösung durch rocketman10404 vorgeschlagen wird nicht mehr funktionieren (Deaktivierung dnsmasqwürde immer noch Arbeit, aber es hat den Nachteil Ubuntu zu verhindern , dass automatisch die DNS - Server die Aktualisierung) .

Korrektur in der neuen daemon.jsonKonfigurationsdatei

Finden Sie den DNS-Server Ihres Netzwerks:

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

Öffnen oder erstellen Sie, falls nicht vorhanden, /etc/docker/daemon.jsonund fügen Sie der ExecStartZeile DNS-Einstellungen hinzu:

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

Starten Sie den Docker-Daemon neu:

$ sudo service docker restart

Ich habe einen ausführlichen Blog-Beitrag verfasst und einen Fehler zu diesem Problem gemeldet, wenn Sie weitere Informationen wünschen.

(Ursprünglich habe ich es gelöst, indem ich /lib/systemd/system/docker.service geöffnet und der ExecStart-Zeile DNS-Einstellungen hinzugefügt habe , aber das ist schlecht - wir sollten systemd-Dateien nicht direkt bearbeiten .)

Robin Winslow
quelle
Vielen Dank für Ihre Lösung - es war hilfreich auf dem Weg zu meiner Lösung - die meiner Meinung nach etwas eleganter zu meinen eigenen Umständen und den Besonderheiten der Ausführung von Docker unter Ubuntu (oder anderen Desktop-Distributionen, die NetworkManager + dnsmasq verwenden) passt.
Adrian
16

Ich benutze Docker nicht selbst, daher würde ich normalerweise nicht auf eine Docker-Frage eingehen, aber ich habe gerade darüber gelesen und bin auf eine Docker-Dokumentation gestoßen, die genau dieses Problem zu lösen scheint . Um zusammenzufassen...

In der Dokumentation werden einige Problemumgehungen vorgeschlagen. Der erste besteht darin, den DNS-Server anzugeben, der vom Docker-Daemon für die Container verwendet werden soll, indem die folgende Zeile hinzugefügt wird /etc/default/docker:

docker_OPTS="--dns 8.8.8.8"

Bei dem bereitgestellten DNS kann es sich um einen lokalen DNS-Server handeln, z. B. 192.168.1.1 (Gateway). Starten Sie dann mit neu

sudo restart docker

Eine alternative Lösung besteht darin, dnsmasq in NetworkManager zu deaktivieren, indem Sie die Konfiguration folgendermaßen auskommentieren /etc/NetworkManager/NetworkManager.conf:

#dns=dnsmasq

Starten Sie dann beide neu

sudo restart network-manager
sudo restart docker
rocketman10404
quelle
3
dnsmasq zu deaktivieren hat bei mir funktioniert.
Bennyl
2
Dieser letztere Ansatz bedeutet natürlich, dass der Netzwerkmanager dnsmasq nicht steuern kann, was beispielsweise bedeutet, dass er Ihren DNS-Server nicht ändern kann, wenn Sie das Netzwerk wechseln, einschließlich des Wechsels zu einem VPN. Der frühere Ansatz scheint mir besser zu sein, aber ich möchte, dass dnsmasq auch die Docker-IP (172.17.0.1) überwacht, damit ich Docker-Hosts darauf hinweisen kann.
mc0e
1
Da Ubuntu auf das Einrichten von Docker mit System umgestellt hat, /etc/default/dockerhat dies keine Auswirkung mehr. In meiner Lösung erfahren Sie, wie Sie dieses Problem in einer Welt nach init.d / upstart lösen können.
Robin Winslow
/etc/NetworkManager/NetworkManager.confexistiert nicht auf Ubuntu 18.04 LTS. : /
XtraSimplicity
Beachten Sie, dass bei einigen Ubuntu 18.04-Setups (z. B. das minimale Image bei Amazon) systemd-resolvedstandardmäßig als DNS-Cache-Server fungiert und das WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it.Problem verursacht (Ubuntu 16.04-Setups scheinen es nicht standardmäßig zu aktivieren). Die Problemumgehung besteht darin, systemd-resolveddie --dnsOption beim Starten des Containers zu deaktivieren oder zu verwenden, wie in der Hauptantwort angegeben.
Anon
9

Ich bin in meiner spezifischen Situation darauf gestoßen

  • Ausführen von Docker-Containern auf meinem lokalen Entwicklungscomputer
  • Welches ist mit einem VPN verbunden
  • Einige unserer Container-Build-Skripte werden beispielsweise npm installvon einem benutzerdefinierten Repository im VPN innerhalb des Containers ausgeführt.
    • Dies funktioniert über eine CI-Pipeline, jedoch nicht über unsere Entwicklermaschinen, da npmeine erfolgreiche DNS-Suche nicht möglich ist
    • Wir hatten auch Probleme mit Containern, die Lookups durchführen müssen, um externe REST-APIs aufzurufen

Ubuntu verwendet standardmäßig dnsmasqden von NetworkManager gestarteten Cache für DNS-Anforderungen und konfiguriert /etc/resolv.conf, um auf diese Instanz zu verweisen127.0.1.1

  • Der von uns verwendete VPN-Client ist nicht mit NetworkManager kompatibel und erzwingt einen eigenen Client, /etc/resolv.confder die NetworkManager-Konfiguration überschreibt
  • Dadurch werden die DNS-Server für das VPN konfiguriert
  • Docker schattiert Ihren /etc/resolv.confContainer standardmäßig
    • Normalerweise leitet es unter Ubuntu die Google DNS-Server an den Container weiter (da es die dnsmasqSituation kennt) .
    • Es ist jedoch hilfreich, die VPN-DNS-Serverkonfiguration an den Container zu übergeben
    • Es gibt keine Route vom Container auf der docker0Netzwerkbrücke zu den DNS-Servern über den VPN- tap0Adapter.
  • Ergo schlagen alle DNS-Suchvorgänge im Container fehl, da nicht die einzigen DNS-Server erreicht werden können, mit denen er ausgeliefert wird
  • Darüber hinaus blockieren einige Netzwerke Anforderungen an die Google-DNS-Server, da diese alle Ihre DNS-Lookups abrufen möchten

Die Lösung :

Es scheint eleganter zu sein, NetworkManager und seine Captive- dnsmasqInstanz so zu verwenden, wie sie entworfen wurden.

  1. Weisen Sie Docker an, Ihre dnsmasqInstanz für DNS zu verwenden

    • Fügen Sie eine Datei hinzu oder bearbeiten Sie sie /etc/docker/daemon.json, um Docker anzuweisen, den docker0Bridge-Adapter für DNS zu verwenden

      {
        "dns": ["172.17.0.1"]
      }
      
  2. Konfigurieren Sie die NM- dnsmasqInstanz so, dass sie auch die Docker-Bridges überwacht, da standardmäßig nur 127.0.1.1 - create file abgehört wird/etc/NetworkManager/dnsmasq.d/docker-bridge.conf

    # Default Docker bridge
    interface=docker0
    # Other Docker bridges
    interface=br-*
    
  3. Ich mag das unhöfliche Verhalten dieses VPN-Clients nicht und ich würde das DNS lieber nur am VPN-Ende für VPN-Lookups verwenden (wenn Sie einen höflichen VPN-Client haben, der NetworkManager richtig konfiguriert hat, müssen Sie dies nicht tun )

    • Deaktivieren Sie die DNS-Funktion im VPN-Client (das Überschreiben wird resolv.confbeim Herstellen der Verbindung beendet und alle DNS-Vorgänge werden dnsmasqerneut ausgeführt.)
    • Fügen Sie eine Konfigurationsdatei hinzu, um dnsmasqdie DNS-Anforderungen für Ihre Domain entsprechend zu leiten - fügen Sie die Datei `/etc/NetworkManager/dnsmasq.d/vpn-dns.conf hinzu

      server=/myprivatedomain.net/10.0.0.1  
      # or whatever your private DNS server is
      
    • Fügen Sie optional eine Suchdomäne für Ihre Domäne hinzu, damit Sie Kurznamen verwenden können

      • Ich habe gerade unsere lokale Domain zur Suchliste in meiner Standardnetzwerkverbindung hinzugefügt
  4. Starten Sie NetworkManager und Docker neu

    sudo service network-manager restart
    sudo service docker restart
    

Zu diesem Zeitpunkt sollten Ihre Docker-Container in der Lage sein, nslookupProbleme zu vermeiden, wenn Sie sich in einem VPN befinden, und zwar für Domänen innerhalb und außerhalb Ihres VPN.

Adrian
quelle
1
Eine kleine Änderung, bei der die IP-Adresse der docker0-Brücke nicht hart codiert wird, ist die Verwendung der Schnittstelle anstelle der Anweisung zum Abhören der Adresse: interface = docker0
siwyd
Tolle Erklärungen und Anleitungen. Ein +1 verdient.
ereOn
Cheers @simonwydooghe - Ich habe Ihren Vorschlag aufgenommen. Sie können in diesem Feld auch Platzhalter verwenden. Daher habe ich ein Muster für alle Brückennamen hinzugefügt, die von nicht standardmäßigen Netzwerken verwendet werden (zumindest von docker-compose).
Adrian
1
Es scheint, dass der DNS-Wert in daemon.json ein Array sein muss, ansonsten erhalte ich eine Fehlermeldung: cannot unmarshal string into Go value of type []stringbeim Neustart des Docker-Dienstes.
Slaven Rezic
Update für Bionic: 18.04 verwendet nicht länger eine unverlierbare Instanz von dnsmasq, die von NetworkManager für DNS verwaltet wird, und verwendet stattdessen systemd-resolved. das bringt seine eigenen Probleme mit sich, weil das nicht konfiguriert werden kann, um die docker0-Brücke abzuhören. Ich habe es deaktiviert und den NetworkManager dnsmasq neu installiert und richtig konfiguriert.
Adrian
2

Hier ist, wie ich Docker auf meinem Ubuntu 14.04 Server einrichte, der ohne Kopf läuft.

Ich verwende Ubuntu Server 14.04 mit der folgenden Docker-Version.

#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

Die Datei /etc/init/docker.io.conf und das Skript enthalten die folgende Zeile:

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

Die Antwort oben hat mir geholfen, die Datei oben zu finden.

Ich habe das Folgende in /etc/default/docker.io auskommentiert und meinen lokalen DNS-Server hinzugefügt:

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

Service neu gestartet mit:

sudo service docker.io restart

Ran docker run <image> /bin/bash

Keine DNS-Meldungen beim Starten des Containers.

Startete einen neuen Container, installierte dnsutils.

Ran dig und die Servermeldung ist der richtige lokale DNS-Server.

Strang
quelle
0

Ich hatte ein ähnliches Problem und habe es StackOverflow gemeldet . Es scheint, dass ich den 8.8.8.8in der Ubuntu-Standardinstallation von Docker angegebenen Nameserver nicht abfragen konnte . Ich könnte es jedoch anpingen. Verwenden Sie in diesem Fall einen DNS-Server, den Sie tatsächlich abfragen können. Testen Sie mit

nslookup - dns.server.name

und starte den Container über

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

Ich habe noch keinen Weg zu https://askubuntu.com/q/607172/30266 gefunden , um eine automagic-Lösung abzuleiten.

krlmlr
quelle
Meine Antwort mag für Sie automagisch genug sein ...
Adrian
0

Sie können den lokalen DNS-Resolver des Hosts (z. B. dnsmasq) aus Ihren Docker-Containern verwenden, wenn diese sich in einem benutzerdefinierten Netzwerk befinden . In diesem Fall verfügt ein Container /etc/resolv.confüber den Nameserver 127.0.0.11(auch bekannt als der eingebettete DNS-Server des Dockers ), der DNS-Anforderungen ordnungsgemäß an die Loopback-Adresse des Hosts weiterleiten kann.

$ 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    

Wenn Sie verwenden docker-compose, wird automatisch ein benutzerdefiniertes Netzwerk für Ihre Container eingerichtet (mit einem Dateiformat von v2 + ). Beachten Sie jedoch, dass docker-composeContainer zwar in einem benutzerdefinierten Netzwerk ausgeführt werden, diese jedoch weiterhin im Standardnetzwerk erstellt werden . Um ein benutzerdefiniertes Netzwerk für Builds zu verwenden, können Sie den networkParameter in der Build-Konfiguration angeben (erfordert das Dateiformat v3.4 + ).

Eugene Yarmash
quelle