doker.io DNS nie działa, próbuje użyć 8.8.8.8

33

Mam nową instalację Ubuntu 14.04 i chcę używać Dockera do uruchamiania starych rzeczy, które wymagają wersji 12.04. DNS wewnątrz Dockera nie działa.

Plik resolv.conf mojego laptopa wygląda następująco:

nameserver 127.0.0.1

Co najwyraźniej nie działa z Dockerem. Dlatego próbuje ustawić serwery nazw na 8.8.8.8 i 8.8.4.4; kiedy robię

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

To mówi:

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]

I rzeczywiście, w instancji Docker resolv.conf wygląda następująco:

nameserver 8.8.8.8
nameserver 8.8.4.4

Mogę pingować oba z powodzeniem z poziomu instancji Docker. Jednak nie ma DNS (np. ping google.comKończy się niepowodzeniem).

Dane wyjściowe ifconfig wewnątrz Dockera:

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)

Co teraz?

RemcoGerlich
źródło

Odpowiedzi:

23

Kiedy pakiet Ubuntu Docker został zaktualizowany do użycia systemd, porzucił obsługę /etc/default/dockerpliku konfiguracyjnego, więc wstępne rozwiązanie sugerowane przez rocketman10404 nie będzie już działać (wyłączenie dnsmasqnadal będzie działać, ale ma tę wadę, że uniemożliwia automatyczne aktualizowanie serwera DNS przez Ubuntu) .

Naprawianie w nowym daemon.jsonpliku konfiguracyjnym

Znajdź serwer DNS swojej sieci:

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

Otwórz lub utwórz, jeśli nie istnieje, /etc/docker/daemon.jsoni dodaj ustawienia DNS do ExecStartlinii:

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

Uruchom ponownie demona dokera:

$ sudo service docker restart

Napisałem szczegółowy post na blogu, a także zgłosiłem błąd dotyczący tego problemu, jeśli chcesz uzyskać więcej informacji.

(Pierwotnie rozwiązałem go, otwierając /lib/systemd/system/docker.service i dodając ustawienia DNS do wiersza ExecStart , ale to źle - nie powinniśmy bezpośrednio edytować plików systemowych .)

Robin Winslow
źródło
Dzięki za twoje rozwiązanie - było pomocne w drodze, którą podjąłem do mojego rozwiązania - które moim zdaniem jest nieco bardziej eleganckie dopasowanie do moich okoliczności i osobliwości uruchamiania Dockera na Ubuntu (lub innych dystrybucjach pulpitu, które używają NetworkManager + dnsmasq).
Adrian
16

Sam nie używam Dockera, więc normalnie nie wchodziłbym tutaj w pytanie dotyczące Dockera, ale akurat czytałem o tym i natknąłem się na dokumentację Dockera, która wydaje się rozwiązać ten konkretny problem . Podsumowując ...

Dokumentacja sugeruje kilka obejść. Pierwszym jest określenie serwera DNS, który ma być używany przez demona dokera dla kontenerów, poprzez dodanie następującego wiersza do /etc/default/docker:

docker_OPTS="--dns 8.8.8.8"

gdzie podany DNS może być lokalnym serwerem DNS, takim jak 192.168.1.1 (brama). Następnie uruchom ponownie za pomocą

sudo restart docker

Alternatywne rozwiązanie polega na wyłączeniu dnsmasq w NetworkManager przez komentowanie konfiguracji w następujący /etc/NetworkManager/NetworkManager.confsposób:

#dns=dnsmasq

następnie uruchom ponownie oba

sudo restart network-manager
sudo restart docker
rocketman10404
źródło
3
wyłączenie dnsmasq działało dla mnie.
bennyl
2
To drugie podejście będzie oczywiście oznaczać, że menedżer sieci nie może kontrolować dnsmasq, co oznacza na przykład, że nie może zmienić serwera dns podczas zmiany sieci, w tym przejścia na VPN. To pierwsze podejście wydaje mi się lepsze, ale chciałbym mieć możliwość, aby dnsmasq również nasłuchiwał na IP dokującego (172.17.0.1), więc mogę wskazać na to hosty dokujące.
mc0e
1
Ponieważ Ubuntu przeszło na konfigurację Dockera za pomocą sytemd, /etc/default/dockernie ma już żadnego efektu. Zobacz moje rozwiązanie, jak to rozwiązać w świecie post-init.d / upstart.
Robin Winslow,
/etc/NetworkManager/NetworkManager.confnie istnieje na Ubuntu 18.04 LTS. : /
XtraSimplicity
Zauważ, że w niektórych konfiguracjach Ubuntu 18.04 (np. Minimalny obraz na Amazon) systemd-resolveddomyślnie działa jako buforujący serwer DNS i spowoduje WARNING: Local (127.0.0.1) DNS resolver found in resolv.conf and containers can't use it.problem (konfiguracje Ubuntu 16.04 domyślnie nie włączają go). Obejściem tego problemu jest wyłączenie systemd-resolvedlub użycie --dnsopcji podczas uruchamiania kontenera, jak wspomniano w głównej odpowiedzi.
Anon
9

Wpadłem na to w mojej konkretnej sytuacji

  • Uruchamianie kontenerów Docker na mojej lokalnej maszynie programistycznej
  • Który jest podłączony do VPN
  • Niektóre z naszych skryptów kompilacji kontenerów wykonują takie czynności, jak uruchamianie npm installz niestandardowego repozytorium w sieci VPN w kontenerze.
    • Działa to z potoku CI, ale nie z naszych maszyn deweloperskich, ponieważ npmnie można przeprowadzić pomyślnego wyszukiwania DNS
    • Mieliśmy również problemy z kontenerami, które muszą wyszukiwać, aby wywoływać zewnętrzne interfejsy API REST

Ubuntu domyślnie używa dnsmasquruchomionego przez NetworkManager do buforowania żądań DNS i konfiguruje, /etc/resolv.confaby wskazywać na to wystąpienie127.0.1.1

  • Klient VPN, którego używamy, nie jest zgodny z NetworkManager i wymusza jego własnego, /etc/resolv.confktóry zastępuje konfigurację NetworkManager
  • To konfiguruje serwery DNS dla VPN
  • Docker /etc/resolv.confdomyślnie ukrywa twój cień w kontenerze
    • Zwykle w systemie Ubuntu przekazuje serwery Google DNS do kontenera (ponieważ wie o dnsmasqsytuacji.
    • Ale z przyjemnością przekazuje konfigurację serwera VPN DNS do kontenera
    • Nie ma trasy z kontenera na docker0moście sieciowym do serwerów DNS przez tap0adapter VPN .
  • Ergo, wszystkie wyszukiwania DNS w kontenerze kończą się niepowodzeniem, ponieważ nie mogą dotrzeć do jedynych serwerów DNS, w które jest wyposażony
  • Ponadto niektóre sieci blokują żądania do serwerów Google DNS, ponieważ chcą mieć możliwość podglądania wszystkich wyszukiwań DNS

Rozwiązanie :

Bardziej eleganckie byłoby używanie NetworkManagera i jego dnsmasqinstancji w sposób, w jaki został zaprojektowany.

  1. Powiedz Dockerowi, aby używał twojej dnsmasqinstancji dla DNS

    • Dodaj lub edytuj plik, /etc/docker/daemon.jsonaby poinformować dokera o użyciu docker0adaptera mostu dla DNS

      {
        "dns": ["172.17.0.1"]
      }
      
  2. Skonfiguruj dnsmasqinstancję NM, aby nasłuchiwała również mostków Docker, ponieważ domyślnie nasłuchuje tylko 127.0.1.1 - utwórz plik/etc/NetworkManager/dnsmasq.d/docker-bridge.conf

    # Default Docker bridge
    interface=docker0
    # Other Docker bridges
    interface=br-*
    
  3. Nie podoba mi się niegrzeczne zachowanie tego klienta VPN i wolę używać DNS po stronie VPN do wyszukiwania VPN (jeśli masz uprzejmego klienta VPN, który używa poprawnie skonfigurowanego NetworkManagera, nie musisz tego robić )

    • Wyłącz funkcję DNS w kliencie VPN (przestaje nadpisywać resolv.confpo połączeniu, a teraz cały DNS przechodzi dnsmasqponownie)
    • Dodaj plik konfiguracyjny, aby dnsmasqodpowiednio kierować żądania DNS dla swojej domeny - dodaj plik `/etc/NetworkManager/dnsmasq.d/vpn-dns.conf

      server=/myprivatedomain.net/10.0.0.1  
      # or whatever your private DNS server is
      
    • Opcjonalnie dodaj domenę wyszukiwania dla swojej domeny, aby móc używać krótkich nazw

      • Właśnie dodałem naszą domenę lokalną do listy wyszukiwania w moim domyślnym połączeniu sieciowym
  4. Uruchom ponownie NetworkManager i Docker

    sudo service network-manager restart
    sudo service docker restart
    

W tym momencie kontenery Docker powinny być w stanie obejść się nslookupbez problemów, gdy jesteś w VPN, dla domen zarówno wewnątrz, jak i poza VPN.

Adrian
źródło
1
Niewielką poprawką, która nie wymaga zakodowania na stałe adresu IP mostka dokera0, jest użycie interfejsu zamiast dyrektywy nasłuchiwania adresu: interfejs = doker0
siwyd
Niesamowite wyjaśnienia i instrukcje. +1 zasłużony.
ereOn
Pozdrawiam @simonwydooghe - Włączyłem twoją sugestię - możesz również używać symboli wieloznacznych w tym polu, więc dodałem wzór dla wszystkich nazw mostów używanych w sieciach innych niż domyślne (przynajmniej tak, jak w przypadku docker-compose).
Adrian
1
Wygląda na to, że wartość dns w daemon.json musi być tablicą, w przeciwnym razie cannot unmarshal string into Go value of type []stringpojawia się błąd: po ponownym uruchomieniu usługi dokowania.
Slaven Rezic
Aktualizacja dla Bionic: 18.04 już nie używa wewnętrznej instancji dnsmasq zarządzanej przez NetworkManager dla DNS i zamiast tego używa systemd-rozwiązany; co powoduje własne problemy, ponieważ nie można tego skonfigurować do nasłuchiwania mostka docker0. Uciekłem się do wyłączenia go, ponownej instalacji dnsmasq NetworkManagera i prawidłowej konfiguracji.
Adrian
2

Oto jak skonfigurowałem dokera na moim serwerze Ubuntu 14.04 działającym bez głowy.

Korzystam z serwera Ubuntu 14.04 z zainstalowaną następującą wersją dokera.

#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

Plik /etc/init/docker.io.conf i skrypt zawiera następujący wiersz:

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

Powyższa odpowiedź pomogła mi znaleźć powyższy plik.

Odkomentowałem następujące elementy w /etc/default/docker.io i dodałem mój lokalny serwer DNS:

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

Uruchomiłem ponownie usługę z:

sudo service docker.io restart

Biegł docker run <image> /bin/bash

Brak komunikatów dns podczas uruchamiania kontenera.

Uruchomiłem nowy kontener, zainstalowałem dnsutils.

Ran dig, a komunikat serwera jest prawidłowym lokalnym serwerem DNS.

Motek
źródło
0

Miałem podobny problem, zgłosiłem go StackOverflow . Wygląda na to, że nie mogłem 8.8.8.8przesłać zapytania do serwera nazw określonego w domyślnej instalacji Docker w systemie Ubuntu; jednak mogę pingować. W takim przypadku skorzystaj z serwera DNS, do którego możesz faktycznie wysłać zapytanie. Przetestuj za pomocą

nslookup - dns.server.name

i uruchom kontener przez

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

Muszę jeszcze znaleźć sposób na https://askubuntu.com/q/607172/30266, aby uzyskać rozwiązanie automagiczne.

krlmlr
źródło
Moja odpowiedź może być dla ciebie wystarczająco automagiczna ...
Adrian,
0

Możesz użyć lokalnego resolvera DNS hosta (np. dnsmasq) Z kontenerów Docker, jeśli są one w sieci zdefiniowanej przez użytkownika . W takim przypadku kontener /etc/resolv.confbędzie miał serwer nazw 127.0.0.11(zwany także wbudowanym serwerem DNS Dockera ), który może poprawnie przekazywać żądania DNS na adres zwrotny hosta.

$ 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    

Jeśli go użyjesz docker-compose, automatycznie skonfiguruje niestandardową sieć dla twoich kontenerów (w formacie pliku v2 + ). Należy jednak pamiętać, że chociaż docker-composedziała kontenery w sieci zdefiniowanej przez użytkownika, nadal buduje je w sieci domyślnej . Aby użyć sieci niestandardowej do kompilacji, możesz określić networkparametr w konfiguracji kompilacji (wymaga formatu pliku v3.4 + ).

Eugene Yarmash
źródło