Mój kontener docker nie ma internetu

139

Miałem to dobrze, ale teraz przestało. Bezskutecznie wypróbowałem następujące polecenia:

docker run -dns 8.8.8.8 base ping google.com

docker run base ping google.com

sysctl -w net.ipv4.ip_forward=1 - zarówno na hoście, jak i na kontenerze

Wszystko co dostaję to unknown host google.com. Docker w wersji 0.7.0

Jakieś pomysły?

PS również ufwwyłączony

Romeo Mihalcea
źródło
9
Twoje pytanie rozwiązało mój problem: musiałem uruchomić sysctl -w net.ipv4.ip_forward=1(na
Centos
Ponieważ możesz mieć problem z routingiem dns
docker
To samo tutaj, po tym, jak naprawiłem /etc/resolv.conf na komputerze hosta, bez niego nie będzie działaćsysctl -w net.ipv4.ip_forward=1
Reeebuuk
Sprawdź również, czy masz poprawne wartości /etc/resolv.confna komputerze hosta
Hanxue
dla mnie po tym, sysctl -w net.ipv4.ip_forward=1jak musiałem biec sudo service docker restart.
Asif Ali

Odpowiedzi:

100

Pierwszą rzeczą do sprawdzenia jest uruchomienie cat /etc/resolv.confw kontenerze docker . Jeśli ma nieprawidłowy serwer DNS, na przykład nameserver 127.0.x.x, kontener nie będzie w stanie przekształcić nazw domen w adresy IP, więc ping google.comzakończy się niepowodzeniem.

Drugą rzeczą do sprawdzenia jest uruchomienie cat /etc/resolv.confna komputerze głównym . Docker w zasadzie kopiuje hosta /etc/resolv.confdo kontenera za każdym razem, gdy kontener jest uruchamiany. Więc jeśli host /etc/resolv.confjest zły, to samo będzie w kontenerze docker.

Jeśli zauważyłeś, że host /etc/resolv.confjest zły, masz 2 opcje:

  1. Zakoduj serwer DNS na stałe w daemon.json. Jest to łatwe, ale nie idealne, jeśli spodziewasz się zmiany serwera DNS.

  2. Napraw plik gospodarzy /etc/resolv.conf. Jest to trochę trudniejsze, ale jest generowane dynamicznie i nie kodujesz na stałe serwera DNS.


1. Serwer DNS z twardym kodem w docker daemon.json

  • Edytować /etc/docker/daemon.json

    {
        "dns": ["10.1.2.3", "8.8.8.8"]
    }
    
  • Zrestartuj demona Dockera, aby zmiany odniosły skutek:
    sudo systemctl restart docker

  • Teraz, gdy uruchomisz / uruchomisz kontener, docker zapełni /etc/resolv.confwartości z daemon.json.


2. Napraw pliki hostów /etc/resolv.conf

A. Ubuntu 16.04 i wcześniejsze

  • Dla Ubuntu 16.04 i wcześniejszych /etc/resolv.confbył dynamicznie generowany przez NetworkManager.

  • Skomentuj linię dns=dnsmasq(z a #) w /etc/NetworkManager/NetworkManager.conf

  • Uruchom ponownie NetworkManager, aby zregenerować /etc/resolv.conf:
    sudo systemctl restart network-manager

  • Zweryfikuj na hoście: cat /etc/resolv.conf

B. Ubuntu 18.04 i nowsze

  • Ubuntu 18.04 zmieniono na używanie systemd-resolveddo generowania/etc/resolv.conf . Teraz domyślnie używa lokalnej pamięci podręcznej DNS 127.0.0.53. To nie zadziała w kontenerze, więc Docker domyślnie użyje serwera DNS Google 8.8.8.8, który może się zepsuć dla osób za zaporą ogniową.

  • /etc/resolv.confjest właściwie dowiązaniem symbolicznym ( ls -l /etc/resolv.conf), które /run/systemd/resolve/stub-resolv.confdomyślnie wskazuje na (127.0.0.53) w Ubuntu 18.04.

  • Po prostu zmień łącze symboliczne, na które wskazuje /run/systemd/resolve/resolv.conf, które zawiera listę prawdziwych serwerów DNS:
    sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf

  • Zweryfikuj na hoście: cat /etc/resolv.conf

Teraz powinieneś mieć ważny /etc/resolv.confna hoście, aby docker mógł skopiować do kontenerów.

wisbucky
źródło
1
To rozwiązało problem w Ubuntu 16.04 z Dockerem 17.09.
Luís de Sousa
2
To rozwiązało mój problem (tak samo jak w przypadku OP, Ubuntu 14.04 / Docker 18.01.0-ce). To łącze może być przydatne do testowania połączenia internetowego bez pingowania, jeśli nie masz polecenia ping w obrazie dockera. Jeśli Twój host nie ma systemctl(Ubuntu 14.04), spróbuj Jak zrestartować usługę sieciową? i / lub uruchom ponownie komputer.
Benjamin,
Działał jak urok!
Homewrecker,
1
Działa to na Ubuntu 18.04 (opcja B). Jednak docker nie przeniósł poprawnego teraz /etc/resolv.confdo kontenera podczas budowy, musiałem ręcznie skopiować plik do kontenera.
glaux
1
Na moim komputerze (RedHat 7.4) plik konfiguracyjny hosta jest poprawny, ale plik kontenerów nadal wskazuje na 172.0.0.11. Więc co teraz zrobić?
Martin Majewski
90

Naprawiono postępując zgodnie z tą radą:

[...] czy możesz spróbować zresetować wszystko?

pkill docker
iptables -t nat -F
ifconfig docker0 down
brctl delbr docker0
docker -d

Zmusi to docker do odtworzenia mostka i ponownego wprowadzenia wszystkich reguł sieciowych

https://github.com/dotcloud/docker/issues/866#issuecomment-19218300

Wygląda na to, że interfejs został jakoś „powieszony”.

Aktualizacja dla nowszych wersji Dockera:

Powyższa odpowiedź może nadal wykonać zadanie za Ciebie, ale minęło sporo czasu, odkąd ta odpowiedź została opublikowana, a docker jest teraz bardziej dopracowany, więc upewnij się, że wypróbujesz je najpierw, zanim przejdziesz do zniekształcenia iptables.

sudo service docker restart lub (jeśli jesteś w dystrybucji Linuksa, która nie używa Upstart) sudo systemctl restart docker

Romeo Mihalcea
źródło
31
docker -dzawodzi. Nie ma -dflagi.
Luís de Sousa
1
Dla tych, którzy nadal mają problem, istnieje otwarty problem na githubie
Nepoxx
1
@Pawan:ip link del docker0
drewrockshard
1
lub zainstaluj bridge-utils
cjdcordeiro
5
docker -dnie istnieje w nowszych wersjach. Zamiast: service docker stop, a następnie dockerd, po czymservice docker start
Telmo Marques
64

Zamierzonym sposobem ponownego uruchomienia dockera nie jest zrobienie tego ręcznie, ale użycie polecenia serviceor init:

service docker restart
maska ​​bitowa
źródło
5
jeśli jesteś w dystrybucji Linuksa, która nie używa upstartu, sudo systemctl restart docker działał dla mnie
jeffrey
ponowne uruchomienie działało dobrze. Nie wiem, czy ma to coś wspólnego z tym, że włączyłem go do „automatycznego startu” ( systemctl enable docker)
Lucas Pottersky
Wydaje się, że nie ma to związku z pytaniem PO.
Kevin Buchs
W pewnym sensie tak, ponieważ w sytuacji opisywanej przez OP, resetowanie dockera powoduje ponowne zainicjowanie interfejsów sieciowych, a tym samym ponowne włączenie dostępu do Internetu. Prawdą jest, że nie wyjaśnia to DLACZEGO czasami się psuje, ale zapewnia rozwiązanie problemu.
maska ​​bitów
Jednak w środowisku produkcyjnym ponowne uruchomienie dockera jest niemożliwe. Jak rozwiązać problem w tej sprawie?
Suyanhanx
22

Aktualizacja tego pytania z odpowiedzią dla OSX (przy użyciu Docker Machine)

Jeśli używasz Dockera na OSX przy użyciu Docker Machine, wtedy zadziałało:

docker-machine restart

<...wait for it to restart, which takes up to a minute...>

docker-machine env
eval $(docker-machine env)

Wtedy (przynajmniej z mojego doświadczenia), jeśli pingujesz google.com z kontenera, wszystko będzie dobrze.

lefthandme
źródło
Pracował również w systemie Windows, aby ponownie uruchomić dostęp do sieci.
Mikael Lepistö
1
To zadziałało dla mnie. Na górnym pasku menu mam ikonę dockera, w menu opcję „restart”. Potem sieciowanie znów było w porządku
olidem
8

Nie wiem, co robię, ale to zadziałało:

OTHER_BRIDGE=br-xxxxx # this is the other random docker bridge (`ip addr` to find)    
service docker stop

ip link set dev $OTHER_BRIDGE down
ip link set dev docker0 down
ip link delete $OTHER_BRIDGE type bridge
ip link delete docker0 type bridge
service docker start && service docker stop

iptables -t nat -A POSTROUTING ! -o docker0 -s 172.17.0.0/16 -j MASQUERADE
iptables -t nat -A POSTROUTING ! -o docker0 -s 172.18.0.0/16 -j MASQUERADE

service docker start
dctremblay
źródło
2
ładna taśma klejąca!
dctremblay
1
Twoja odpowiedź pomogła rozwiązać podobny problem. Spędziłem nad tym wiele godzin! Po niekompletnej instalacji Kubespray kontenery Dockera straciły połączenie internetowe z komunikatem „Tymczasowe rozwiązywanie problemów” podczas próby pingowania dowolnego hosta publicznego lub adresu IP. Więc nie miałem tej zasady, która jest obowiązkowa - iptables -t nat -A POSTROUTING ! -o docker0 -s 172.17.0.0/16 -j MASQUERADE. Możesz sprawdzić, czy masz tę zasadęiptables -t nat -L POSTROUTING
laimison
6

Używałem DOCKER_OPTS="--dns 8.8.8.8"i później odkryłem, że mój kontener nie miał bezpośredniego dostępu do Internetu, ale mógł uzyskać dostęp do mojego firmowego intranetu. Zmieniłem DOCKER_OPTSna następujące:

DOCKER_OPTS="--dns <internal_corporate_dns_address"

Zastąpienie internal_corporate_dns_addressadresem IP lub FQDN naszego DNS i zrestartowałem docker przy użyciu

sudo service docker restart

a następnie stworzyłem mój kontener i sprawdziłem, czy ma dostęp do internetu.

Praca w
źródło
5

Byłem zaskoczony, gdy stało się to dla mnie losowo dla jednego z moich pojemników, podczas gdy inne pojemniki były w porządku. Kontener został dołączony do co najmniej jednej sieci innej niż wewnętrzna , więc Composedefinicja nie zawierała żadnych błędów . Ponowne uruchomienie demona VM / Docker nie pomogło. Nie był to również problem z DNS, ponieważ kontener nie mógł nawet pingmieć zewnętrznego adresu IP. Rozwiązaniem dla mnie było odtworzenie sieci (sieci) dockera. W moim przypadku docker-compose down && docker-compose upzadziałało.

Komponować

Wymusza to odtworzenie wszystkich sieci wszystkich kontenerów:

docker-compose down && docker-compose up

Tryb roju

Przypuszczam, że wystarczy usunąć i odtworzyć usługę, która odtwarza sieci usługi:

docker service rm some-service

docker service create ...

Jeśli sieci kontenera są zewnętrzne

Po prostu usuń i utwórz ponownie zewnętrzne sieci tej usługi:

docker network rm some-external-network

docker network create some-external-network

LJ
źródło
4

Dla mnie był to firewall hosta. Musiałem zezwolić na DNS na zaporze hosta. Po zmianie ustawienia zapory hosta musiałem również ponownie uruchomić docker.

Adrian Gunawan
źródło
Lub możesz wyłączyć iptables przez sudo service iptables stopi sudo chkconfig iptables off(na CentOS / RHEL).
MichaelZ
4

Brak dostępu do Internetu może być również spowodowany brakiem ustawień proxy . W takim przypadku --network hostmoże też nie działać. Serwer proxy można skonfigurować, ustawiając zmienne środowiskowe http_proxyi https_proxy:

docker run -e "http_proxy=YOUR-PROXY" \
           -e "https_proxy=YOUR-PROXY"\
           -e "no_proxy=localhost,127.0.0.1" ... 

Nie zapomnij również ustawić no_proxy, w przeciwnym razie wszystkie żądania (w tym kierowane do localhost) będą przechodzić przez proxy.

Więcej informacji: Ustawienia proxy na Archlinux Wiki.

Simon A. Eugster
źródło
1
To było dla mnie rozwiązanie. Uważaj jednak: używałem alpine, który ma implementację wget busybox, która wydaje się ignorować ustawienia proxy, więc nie widziałem korzyści z ustawienia zmiennych środowiskowych.
pelson
Dzięki za podpowiedź dotyczącą busybox; Jeszcze o tym nie wiedziałem!
Simon A. Eugster
1
należy pamiętać, że niektóre systemy operacyjne wymagają wielkich liter, jak w linku do dokumentacji .
Flo
3

Dla mnie była to reguła przekierowania iptables. Z jakiegoś powodu poniższa reguła, w połączeniu z regułami iptables platformy docker, spowodowała trafienie całego ruchu wychodzącego z kontenerów localhost:8080:

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-ports 8080
iptables -t nat -I OUTPUT -p tcp -d 127.0.0.1 --dport 80 -j REDIRECT --to-ports 8080
brandones
źródło
3
Więc ... jakie jest rozwiązanie? :) Mam pierwszą regułę i potrzebuję jej do przekierowania ruchu przychodzącego na 80 do 8080. Jak to zmienić, aby nie wpływać na ruch wychodzący?
mrooney
3

Miałem problem na Ubuntu 18.04. Jednak problem był z DNS. Byłem w sieci firmowej, która ma własny serwer DNS i blokuje inne serwery DNS. Ma to na celu zablokowanie niektórych stron internetowych (pornografia, torrenty itp.)

Aby rozwiązać problem

  1. znajdź swój DNS na komputerze hosta
  2. użyj --dns your_dns zgodnie z sugestią @jobin

    docker run --dns your_dns -it --name cowsay --hostname cowsay debian bash

Adelin
źródło
2

W systemie Windows (8.1) zabiłem interfejs virtualbox (przez taskmgr) i rozwiązałem problem.

Eli
źródło
2

Być może uruchomiłeś swój docker z opcjami dns --dns 172.x.x.x

Miałem ten sam błąd i usunąłem opcje z /etc/default/docker

Linie:

# Use DOCKER_OPTS to modify the daemon startup options.
DOCKER_OPTS="--dns 172.x.x.x"
Thami Bouchnafa
źródło
2

W przypadku Ubuntu 19.04 używającego openconnect 8.3 dla VPN, musiałem dowiązać symboliczne /etc/resolve.conf do tego w systemd (przeciwieństwo odpowiedzi wisbucky'ego)

sudo ln -sf /etc/resolv.conf /run/systemd/resolve/resolv.conf

Kroki do debugowania

  1. Połącz się z firmową siecią VPN
  2. Poszukaj poprawnych ustawień VPN w /etc/resolv.conf lub /run/systemd/resolve/resolv.conf
  3. Niezależnie od tego, który ma prawidłowe ustawienia DNS, połączymy go z innym plikiem (Wskazówka: umieść jeden z poprawnymi ustawieniami po lewej stronie przypisania)

Wersja platformy Docker: wersja Dockera 19.03.0-rc2, kompilacja f97efcc

Jeff Beagley
źródło
2
Dziękuję Ci. W Ubuntu 18.04, po połączeniu się z firmową siecią VPN, tylko plik /etc/resolve.conf był aktualizowany przez DHCP, a / run / systemd / solution / solution / conf pozostawał stały / statyczny. To rozwiązanie pomogło. Teraz kontenery na lokalnej maszynie łączą się z serwerami w VPN (co nie
zdarzyło
1

Jeśli korzystasz z systemu OSX, może być konieczne ponowne uruchomienie komputera po zainstalowaniu platformy Docker. Czasami był to problem.

Will Stern
źródło
1

Początkowo mój kontener docker był w stanie dotrzeć do zewnętrznego internetu (jest to usługa / kontener docker działający na Amazon EC2).

Ponieważ moja aplikacja jest interfejsem API, kontynuowałem tworzenie mojego kontenera (udało mi się pobrać wszystkie potrzebne pakiety), aktualizując moje tabele IP, aby kierować cały ruch z portu 80 do portu, na którym znajdował się mój interfejs API (działający w Docker) nasłuchiwać.

Później, gdy próbowałem odbudować kontener, nie udało się. Po wielu zmaganiach odkryłem, że mój poprzedni krok (ustawienie reguły przekierowania portów IPTable) zepsuł możliwości zewnętrznej sieci dokera.

Rozwiązanie: Zatrzymaj usługę IPTable:

sudo service iptables stop

Uruchom ponownie demona platformy Docker:

sudo service docker restart

Następnie spróbuj odbudować kontener. Mam nadzieję że to pomoże.


Zagryźć

Całkowicie przeoczyłem, że nie musiałem majstrować przy tabelach IP, aby przekazywać ruch przychodzący do 80 do portu, na którym działało API działające w dockerze. Zamiast tego utworzyłem alias portu 80 do portu, na którym działał interfejs API w dockerze:

docker run -d -p 80:<api_port> <image>:<tag> <command to start api>

Achintya Ashok
źródło
1

Dodanie tego tutaj na wypadek, gdyby ktoś napotkał ten problem w kontenerze virtualbox z uruchomionym dockerem. Skonfigurowałem sieć virtualbox na mostkowanie zamiast nat i problem zniknął.

Thorie
źródło
1

dla mnie mój problem polegał na tym, że iptables-services nie zostało zainstalowane, to zadziałało dla mnie (CentOS):

sudo yum install iptables-services
sudo service docker restart
Viet Hoang
źródło
pamiętaj o uruchomieniu i włączeniu usług iptable
Jay
1

Na centos 8 moim problemem było to, że nie zainstalowałem i nie uruchomiłem iptables przed uruchomieniem usługi docker. Upewnij się, że usługa iptables jest uruchomiona przed uruchomieniem usługi Docker.

Rajesh Guptan
źródło
0

Napotkałem też taki problem podczas próby skonfigurowania projektu za pomocą Docker-Compose na Ubuntu.

Docker nie miał w ogóle dostępu do internetu, kiedy próbowałem pingować dowolny adres IP lub nslookować jakiś URL - cały czas się nie udawało.

Bezskutecznie wypróbowałem wszystkie możliwe rozwiązania z opisaną powyżej rozdzielczością DNS.

Spędziłem cały dzień próbując dowiedzieć się, co się dzieje, aż w końcu dowiedziałem się, że przyczyną wszystkich problemów był program antywirusowy, w szczególności jego firewall, który z jakiegoś powodu zablokował Dockerowi uzyskanie adresu IP i portu.

Kiedy go wyłączyłem - wszystko działało dobrze.

Jeśli więc masz zainstalowany program antywirusowy i nic nie pomaga rozwiązać problemu - problemem może być zapora ogniowa programu antywirusowego.

Rocckk
źródło
0

Od kilku dni mam podobny problem. Dla mnie przyczyną była kombinacja systemd, docker i mojego dostawcy hostingu. Korzystam z aktualnego CentOS (7.7.1908).

Mój dostawca hostingu automatycznie generuje plik konfiguracyjny dla systemd-networkd. Począwszy od systemd 219, który jest aktualną wersją CentOS 7, systemd-networkd przejął kontrolę nad parametrami sysctl związanymi z siecią. Docker wydaje się być niekompatybilny z tą wersją i zresetuje flagi przekazywania IP za każdym razem, gdy kontener zostanie uruchomiony.

Moim rozwiązaniem było dodanie IPForward=truew sekcji [Network]mojego pliku konfiguracyjnego wygenerowanego przez dostawcę. Ten plik może znajdować się w kilku miejscach, najprawdopodobniej w/etc/systemd/network .

Proces jest również opisany w oficjalnych dokumentach docker: https://docs.docker.com/v17.09/engine/installation/linux/linux-postinstall/#ip-forwarding-problems

BlackCetha
źródło
Czy mógłbyś podać dokładną lokalizację, w której ustawiłeś ten parametr? Mam dokładnie tę samą lokalizację co Ty, uruchamiam maszynę wirtualną w Google Cloud Platform i nie mogę znaleźć żadnych plików * .network na serwerze. Tylko włączone, /usr/lib/sysctl.d/50-default.confale składnia jest inna.
el.severo
Mój klaster jest zarządzany samodzielnie, a mój dostawca wykonuje tylko podstawowe operacje ładowania początkowego podczas instalacji. Konfiguracja sieci była /etc/systemd/network/10-mainif.networkdla mnie. Inne miejsca, które możesz sprawdzić, to /usr/local/lib/systemd/i /usr/lib/systemd/zgodnie ze stroną podręcznika systemowego.
BlackCetha
0

dla mnie, używając centos 7.4, nie było to kwestia /etc/resolve.conf, iptables, reguł iptables nat ani samego dockera. Problem polega na tym, że na hoście brakuje pakietu bridge-utils, którego docker wymaga do zbudowania mostu za pomocą polecenia brctl. yum install -y bridge-utils i zrestartuj docker, rozwiąż problem.

Jasonw
źródło