Jak połączyć się z kontenerem Dockera spoza hosta (ta sama sieć) [Windows]

88

Stworzyłem mój pierwszy kontener docker, działa na nim serwer przy użyciu Go, ale nie mogę uzyskać do niego dostępu spoza komputera hosta. Właśnie zacząłem z dockerem, więc trochę się tu zagubiłem.

Mam więc bardzo prosty kod Go, który uruchamia serwer, zbudowałem obraz dockera, który instaluje Go i buduje kod w podstawowym obrazie Linuksa. Uruchamiam serwer na porcie 8080, więc udostępniam ten port hostowi obsługującemu kontener w następujący sposób:

docker run -p 8080:8080 dockertest

To działa i mam dostęp do serwera przez adres IP maszyny dockera (ten, który pojawia się na terminalu Docker Quickstart po uruchomieniu), problem polega na tym, że nie mogę uzyskać dostępu do witryny, którą hostuję z zewnątrz hosta, więc jeśli spróbuję aby otworzyć ten sam adres IP w moim telefonie, pojawia się po prostu błąd: ta strona internetowa jest niedostępna (ERR_CONNECTION_TIMED_OUT).

Próbowałem również określić adres IP w następujący sposób:

docker run -p 192.168.0.157:8080:8080 dockertest

Ale kiedy to robię, nie mogę uzyskać dostępu do witryny za pośrednictwem adresu IP maszyny dokującej ani adresu IP określonego w powyższym wierszu poleceń. Nie jestem również pewien, który adres IP mam wpisać w tym poleceniu. Użyłem adresu IP mojego komputera, próbowałem też 127.0.0.1 (localhost), ale to dało ten sam wynik: nie mogłem uzyskać dostępu do witryny za pośrednictwem żadnego IP w ogóle.

Przeszukałem ten problem w Google i znalazłem wiele pytań StackOverflow, ale żadne z nich nie pomogło mi rozwiązać mojego problemu, większość z nich była zorientowana na Linuksa lub Maca, więc rozwiązanie nie dotyczyło mojej sytuacji.

Mogę również uruchomić kod Go na moim komputerze i uzyskać dostęp do witryny internetowej z innego urządzenia w tej samej sieci za pośrednictwem adresu IP mojego komputera. Nie rozumiem, dlaczego nie mogę uzyskać do niego dostępu, gdy uruchamiam go na maszynie dokującej, przyszło mi do głowy, że może to mieć coś wspólnego z przekazywaniem IP lub czymś, ale jestem kompletnym noobem w sieci, ja Jestem głównie programistą WWW i nie mam prawie żadnego doświadczenia w natywnym.

czerwona sól
źródło
czy użyłeś EXPOSE 8080 w swoim pliku Dockerfile w połączeniu z opcją -p? Sprawdź również, czy port 8080 na pudełku, w którym działa kontener, nie jest blokowany przez reguły bezpieczeństwa.
keda
@keda Tak, plik Dockerfile zawiera EXPOSE 8080. Uruchamiam kontener lokalnie na moim komputerze za pomocą terminala Docker Quickstart. Próbowałem też wyłączyć zaporę systemu Windows, ale to też nie zadziałało, nie wiem, czy jest jakieś ustawienie Brakuje
redsalt

Odpowiedzi:

90

TL; DR Sprawdź tryb sieciowy swojego hosta VirtualBox - powinno tak być, bridgedjeśli chcesz, aby maszyna wirtualna (i hostowany przez nią kontener Docker) była dostępna w sieci lokalnej.


Wygląda na to, że nie wiesz, z którym hostem się połączyć, aby uzyskać dostęp do aplikacji przez HTTP. Tak naprawdę nie sprecyzowałeś, jaka jest twoja konfiguracja - zamierzam zgadnąć, na podstawie faktu, że masz w swoich tagach „Windows” i „VirtualBox”.

Zgaduję, że masz Dockera działającego na jakimś smaku Linuksa działającego w VirtualBox na hoście Windows. Oznaczę adresy IP następująco:

D = adres IP kontenera Docker

L = adres IP hosta Linux działającego w VirtualBox

W = adres IP hosta Windows

Gdy uruchomisz aplikację Go na hoście Windows, możesz połączyć się z nią z http://W:8080/dowolnego miejsca w sieci lokalnej. Działa to, ponieważ aplikacja Go wiąże port 8080 na komputerze z systemem Windows i każdy, kto spróbuje uzyskać dostęp do portu 8080 pod adresem IP, Wzostanie połączony.

I tutaj sytuacja staje się bardziej skomplikowana:

VirtualBox, podczas konfigurowania maszyny wirtualnej (VM), może skonfigurować sieć w jednym z kilku różnych trybów. Nie pamiętam, jakie są różne opcje, ale ta, którą chcesz, jest bridged. W tym trybie VirtualBox łączy maszynę wirtualną z siecią lokalną, tak jakby była maszyną samodzielną w sieci, tak jak każda inna maszyna podłączona do sieci. Wbridged trybie maszyna wirtualna pojawia się w sieci jak każda inna maszyna. Inne tryby ustawiają rzeczy inaczej i urządzenie nie będzie widoczne w Twojej sieci.

Tak więc, zakładając, że poprawnie skonfigurujesz sieć dla hosta systemu Linux ( bridged), host systemu Linux będzie miał adres IP w sieci lokalnej (np. 192.168.0.x) i będziesz mieć dostęp do kontenera Docker pod adresem http://L:8080/.

Jeśli host Linux jest ustawiona na tryb inny niż pewnym bridged, to może być w stanie uzyskać dostęp z hosta systemu Windows, ale to będzie zależeć od trybu dokładnie to, co jest w.

EDYCJA - na podstawie poniższych komentarzy wygląda na to, że sytuacja, którą opisałem powyżej, jest poprawna.

Cofnijmy się trochę: oto jak działa Docker na moim komputerze (Ubuntu Linux).

Wyobraź sobie, że uruchomienie tego samego polecenia mieć: docker run -p 8080:8080 dockertest. To powoduje uruchomienie nowego kontenera na podstawie dockertestobrazu i przekazanie (połączenie) portu 8080 na hoście Linux (mój komputer) do portu 8080 w kontenerze. Docker konfiguruje własną sieć wewnętrzną (z własnym zestawem adresów IP), aby umożliwić demonowi Dockera komunikację i umożliwić komunikację kontenerów ze sobą. Zasadniczo to, co z tym robisz, -p 8080:8080to połączenie wewnętrznej sieci Dockera z siecią „zewnętrzną” - tj. karta sieciowa hosta - na określonym porcie.

Ze mną do tej pory? OK, teraz cofnijmy się o krok i spójrzmy na twój system. Na Twoim komputerze działa system Windows - Docker nie działa (obecnie) w systemie Windows, więc narzędzie, którego używasz, skonfigurowało hosta systemu Linux na maszynie wirtualnej VirtualBox. Kiedy robisz to docker runw swoim środowisku, dzieje się dokładnie to samo - port 8080 na hoście Linux jest podłączony do portu 8080 w kontenerze. Duża różnica polega na tym, że twój host Windows nie jest hostem Linuksa, na którym działa kontener, więc jest tu kolejna warstwa i komunikacja w tej warstwie, w której napotykasz problemy.

Potrzebujesz jednej z dwóch rzeczy:

  1. aby połączyć port 8080 na VM VirtualBox z portem 8080 na hoście Windows, tak jak podłączasz kontener Docker do portu hosta.

  2. aby połączyć maszynę wirtualną VirtualBox bezpośrednio z siecią lokalną za pomocą bridged trybie sieciowym, który opisałem powyżej.

Jeśli wybierzesz pierwszą opcję, będziesz mógł uzyskać dostęp do kontenera, w http://W:8080którym Wznajduje się adres IP lub nazwa hosta systemu Windows. Jeśli wybierzesz drugą opcję, dostęp do kontenera będzie można uzyskać pod adresemhttp://L:8080 którym Lznajduje się adres IP lub nazwa hosta maszyny wirtualnej z systemem Linux.

To wszystko wyjaśnienie wyższego poziomu - teraz musisz dowiedzieć się, jak zmienić konfigurację maszyny wirtualnej VirtualBox. I tutaj nie mogę ci naprawdę pomóc - nie wiem, jakiego narzędzia używasz do zrobienia tego wszystkiego na komputerze z systemem Windows i wcale nie jestem zaznajomiony z używaniem Dockera w systemie Windows.

Jeśli możesz dostać się do okna konfiguracji VirtualBox, możesz wprowadzić zmiany opisane poniżej. Istnieje również klient wiersza poleceń, który modyfikuje maszyny wirtualne, ale nie jestem z tym zaznajomiony.

W przypadku bridgedtrybu (a to naprawdę jest najprostszy wybór), wyłącz maszynę wirtualną, kliknij przycisk „Ustawienia” u góry i zmień tryb sieci na bridged, a następnie uruchom ponownie maszynę wirtualną i gotowe. Maszyna wirtualna powinna odebrać adres IP w sieci lokalnej za pośrednictwem protokołu DHCP i powinna być widoczna dla innych komputerów w sieci pod tym adresem IP.

Kryten
źródło
1
Mogę znaleźć tylko 2 adresy IP, ten, który Docker pokazuje, kiedy otwieram terminal Quickstart (192.168.99.100) i ten, który ma mój komputer (192.168.0.157), używając docker run -p 8080:8080 dockertestMogę uzyskać dostęp do mojej witryny za pomocąhttp://192.168.99.100:8080 , ale tylko z mojego komputera z systemem Windows (the hosta), a nie z mojego telefonu. Jeśli używam, docker run -p 192.168.0.157:8080:8080 dockertestnie mogę uzyskać dostępu do witryny z dowolnym adresem IP z dowolnego miejsca. Nie jestem pewien, jak skonfigurować sieć, próbowałem użyć, --net=bridgeale to też nie zadziałało. Czy mam otworzyć VirtualBox? Nie mogę tego zrobić za pomocą terminala Dockera?
redsalt
Problem nie dotyczy Dockera, więc nie, Docker nie może ci pomóc. Zamierzam dodać kilka zmian, aby zilustrować, co myślę, że się dzieje.
Kryten
Ok dziękuję! Teraz rozumiem, że byłem zdezorientowany całą częścią maszyny wirtualnej Linux. Miałem wrażenie, że Docker używa Virtual Box do wewnętrznych rzeczy, których nie powinienem dotykać. Właściwie było to bardzo łatwe, po prostu musiałem przesiąść się bridgedna Virtual Box i teraz działa cuda, dziękuję bardzo.
redsalt
Czy nie ma sposobu, aby okna i kontenery Dockera znajdowały się w tej samej sieci, abyśmy mogli uzyskiwać bezpośredni dostęp do kontenerów bez przekierowania portów?
Vituel
Natknąłem się na to, szukając uruchomionego serwera Jupyter w dockerze i próbując uzyskać do niego dostęp przez sieć LAN. Czy tak czy owak mogę dowiedzieć się jakie jest L po przełączeniu trybu na zmostkowany?
PaulDong,
121
  1. Otwórz Oracle VM VirtualBox Manager
  2. Wybierz maszynę wirtualną używaną przez platformę Docker
  3. Kliknij Ustawienia -> Sieć
  4. Karta 1 powinna (domyślnie?) Być „Dołączona do: NAT”
  5. Kliknij Zaawansowane -> Przekierowanie portów
  6. Dodaj regułę: protokół TCP, port hosta 8080, port gościa 8080 (pozostaw adresy IP hosta i IP gościa puste)
  7. Gość to Twój kontener docker, a Host to Twoja maszyna

Powinieneś teraz móc przeglądać swój kontener za pośrednictwem localhost: 8080 i your-internal-ip: 8080.

Davey Chu
źródło
10
Potwierdzony, miły i łatwy.
Dirk
2
najlepsza odpowiedź, bez obszernego opisu, takiego jak wybrany
Amir Qayyum Khan
2
dla użytkowników vagrant dodaj to w vagrantfile: config.vm.network "forwarded_port", gość: 8080, host: 8080, protokół: "tcp"
Vince Verhoeven
3
Siema! To zadziałało jak urok! Dzięki!!!! Spędzam godziny, próbując to rozgryźć.
Joseph Freeman,
2
To fantastyczne rozwiązanie dla każdego, kto używa Dockera przez VBox!
Mirodinho
7

Po wypróbowaniu kilku rzeczy zadziałało to dla mnie:

  • użyj flagi Docker --publish = 0.0.0.0: 8080: 8080
  • ustaw tryb sieci wirtualnej skrzynki na NAT i nie używaj przekierowania portów

Z adresami innymi niż 0.0.0.0ja nie udało mi się.

mnieber
źródło
4

TLDR: Jeśli masz włączoną Zaporę systemu Windows, upewnij się, że istnieje wyjątek dla „vpnkit” w sieciach prywatnych.

W moim konkretnym przypadku odkryłem, że Zapora systemu Windows blokuje moje połączenie, gdy próbowałem odwiedzić opublikowany port mojego kontenera z innego komputera w mojej sieci lokalnej, ponieważ wyłączenie go sprawiło, że wszystko działało.

Jednak nie chciałem całkowicie wyłączać zapory tylko po to, aby uzyskać dostęp do usługi mojego kontenera. To nasunęło pytanie, która „aplikacja” nasłuchuje w imieniu usługi mojego kontenera. Po znalezieniu innego wątku SO, który nauczył mnie używać netstat -a -bdo wykrywania aplikacji znajdujących się za gniazdami nasłuchowymi na moim komputerze, dowiedziałem się, że tak było vpnkit.exe, który miał już wpis w ustawieniach Zapory systemu Windows: ale „sieci prywatne” były na nim wyłączone i po włączeniu mogłem odwiedzać usługę mojego kontenera z innego komputera bez konieczności całkowitego wyłączania zapory.

Atul Varma
źródło
Sir, uratowałeś mnie od wielu godzin frustracji. Dzięki.
Behdad
2

Jest to najczęstszy problem napotykany przez użytkowników systemu Windows podczas uruchamiania kontenerów Docker. IMO to jest "pytanie za milion dolarów na Docker"; @ „Rocco Smit” słusznie wskazał, że „ruch przychodzący był domyślnie wyłączony w zaporze ogniowej mojego komputera głównego”; w moim przypadku moje oprogramowanie McAfee Anti Virus. Dodałem dodatkowe porty, aby umożliwić ruch przychodzący z innych komputerów w tej samej sieci Wi-Fi LAN w ustawieniach zapory sieciowej McAfee; wtedy to była magia. Przez ponad tydzień zmagałem się z przeglądaniem całego Internetu, dokumentacji SO, Dockera, samouczków po samouczkach związanych z obsługą sieci Docker i wielu ilustracji „nieobsługiwany w systemie Windows” dla „macvlan”, „ipvlan”, „użytkownik zdefiniowany most ”, a nawet ten sam wątek SO kilka razy. Zacząłem nawet przeglądać Google z „Czy ktoś używa Dockera w produkcji?” (Tak, wiem, że Linux jest bardziej popularny w przypadku obciążeń Prod w porównaniu z serwerami Windows), ponieważ nie mogłem uzyskać dostępu (z mojego telefonu komórkowego w tej samej domowej sieci Wi-Fi) an nginx aplikacja wdrożona w kontenerze Docker w systemie Windows. W końcu, cóż to jest, jeśli nie możesz uzyskać dostępu do aplikacji (wdrożonej w kontenerze Dockera) z innych komputerów / urządzeń przynajmniej w tej samej sieci LAN; Ostatecznie w moim przypadku problem dotyczył tylko zapory sieciowej blokującej ruch przychodzący; jeśli nie możesz uzyskać dostępu do aplikacji (wdrożonej w kontenerze Dockera) z innych komputerów / urządzeń przynajmniej w tej samej sieci LAN; Ostatecznie w moim przypadku problem dotyczył tylko zapory sieciowej blokującej ruch przychodzący; jeśli nie możesz uzyskać dostępu do aplikacji (wdrożonej w kontenerze Dockera) z innych komputerów / urządzeń przynajmniej w tej samej sieci LAN; Ostatecznie w moim przypadku problem dotyczył tylko zapory sieciowej blokującej ruch przychodzący;

banarasi
źródło
0

Zauważyłem, że wraz z ustawieniem wartości portu -p, Docker dla Windows używa vpnkit, a ruch przychodzący został domyślnie wyłączony na zaporze mojego komputera hosta. Po włączeniu reguł TCP dla ruchu przychodzącego dla vpnkit mogłem uzyskać dostęp do moich kontenerów z innych maszyn w sieci lokalnej.

Rocco Smit
źródło