Mam kontener dokerów z jedynkami. W ramach procesu kompilacji muszę uzyskać dostęp do serwera WWW, który jest uruchomiony lokalnie na komputerze-hoście. Czy istnieje sposób, aby serwer sieciowy hosta (który można skonfigurować do działania na porcie) mógł być narażony na kontener Jenkins?
EDYCJA: Uruchamiam dokera natywnie na komputerze z systemem Linux.
AKTUALIZACJA:
Oprócz odpowiedzi @larsk poniżej, aby uzyskać adres IP hosta IP z hosta, wykonuję następujące czynności:
ip addr show docker0 | grep -Po 'inet \K[\d.]+'
docker
docker-container
Tri Nguyen
źródło
źródło
curl: (7) Failed to connect to 172.17.1.78 port 7000: No route to host
Odpowiedzi:
Podczas uruchamiania Dockera natywnie w systemie Linux, można uzyskać dostęp do usług hosta za pomocą adresu IP
docker0
interfejsu. Z wnętrza kontenera będzie to domyślna trasa.Na przykład w moim systemie:
I w pojemniku:
Wyodrębnienie tego adresu IP jest dość łatwe przy użyciu prostego skryptu powłoki:
Konieczne może być zmodyfikowanie
iptables
reguł na hoście, aby zezwolić na połączenia z kontenerów Docker. Coś takiego może załatwić sprawę:Umożliwiłoby to dostęp do dowolnych portów na hoście z kontenerów Docker. Uwaga:
Reguły iptables są uporządkowane, a ta reguła może, ale nie musi, postępować właściwie, w zależności od tego, jakie inne reguły ją poprzedzają.
będziesz mieć dostęp do usług hosta, które albo (a) nasłuchują
INADDR_ANY
(aka 0.0.0.0), albo jawnie nasłuchują nadocker0
interfejsie.źródło
docker.for.mac.localhost
zamiastlocalhost
lub127.0.0.1
. Oto dokument .Dla macOS i Windows
Docker przeciwko 18.03 i nowszym (od 21 marca 2018)
Użyj wewnętrznego adresu IP lub połącz się ze specjalną nazwą DNS,
host.docker.internal
która rozwiąże z wewnętrznym adresem IP używanym przez hosta.Wsparcie dla systemu Linux w oczekiwaniu na https://github.com/docker/for-linux/issues/264
MacOS z wcześniejszymi wersjami Dockera
Docker dla komputerów Mac w wersji od 17.12 do 18.02
To samo co powyżej, ale użyj
docker.for.mac.host.internal
zamiast tego.Docker dla komputerów Mac w wersji od 17.06 do 17.11
To samo co powyżej, ale użyj
docker.for.mac.localhost
zamiast tego.Docker na komputery Mac 17.05 i starsze
Aby uzyskać dostęp do komputera hosta z kontenera dokowanego, musisz dołączyć alias IP do interfejsu sieciowego. Możesz powiązać dowolny adres IP, po prostu upewnij się, że nie używasz go do niczego innego.
sudo ifconfig lo0 alias 123.123.123.123/24
Następnie upewnij się, że serwer nasłuchuje adresu IP wspomnianego powyżej lub
0.0.0.0
. Jeśli nasłuchuje na localhost127.0.0.1
, nie zaakceptuje połączenia.Następnie po prostu skieruj kontener dokujący na ten adres IP, aby uzyskać dostęp do komputera hosta!
Aby przetestować, możesz uruchomić coś takiego jak
curl -X GET 123.123.123.123:3000
wewnątrz kontenera.Alias zostanie zresetowany przy każdym ponownym uruchomieniu, więc w razie potrzeby utwórz skrypt startowy.
Rozwiązanie i więcej dokumentacji tutaj: https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds
źródło
docker.for.mac.localhost
która zostanie rozpoznana na wewnętrznym adresie IP używanym przez hosta! ... Przetestowałem to i faktycznie działa! :)ip route show | awk '/default/ {print $3}'
jeden adres IPdocker.for.mac.localhost
jest inny, a inny.host.docker.internal
docs.docker.com/docker-for-mac/networking/…host.docker.internal
w kontenerze dokowanym i konfiguracja127.0.0.1 host.docker.internal
w pliku hosts .Użyj
--net="host"
w swoimdocker run
poleceniu, a następnielocalhost
w kontenerze dokera wskaże hosta dokera.źródło
network_mode: "host"
Rozwiązanie z docker-compose: Aby uzyskać dostęp do usługi opartej na hoście, możesz użyć
network_mode
parametru https://docs.docker.com/compose/compose-file/#network_modeEDIT 2020-04-27: zalecany do stosowania tylko w lokalnym środowisku programistycznym.
źródło
Obecnie najłatwiejszym sposobem na to w systemie Mac i Windows jest użycie hosta
host.docker.internal
, który rozwiązuje adres IP komputera hosta. Niestety nie działa jeszcze w systemie Linux (od kwietnia 2018 r.).źródło
Stworzyłem kontener dokerów do robienia dokładnie tego https://github.com/qoomon/docker-host
Następnie możesz po prostu użyć nazwy kontenera dns, aby uzyskać dostęp do systemu hosta, np
curl http://dockerhost:9200
źródło
Odkryliśmy, że prostszym rozwiązaniem wszystkich tych śmieci sieciowych jest po prostu użycie gniazda domeny dla usługi. Jeśli mimo to próbujesz połączyć się z hostem, po prostu zamontuj gniazdo jako wolumin i jesteś na dobrej drodze. W przypadku postgresql było to tak proste, jak:
Następnie właśnie skonfigurowaliśmy nasze połączenie z bazą danych, aby używało gniazda zamiast sieci. Dosłownie takie łatwe.
źródło
Zbadałem różne rozwiązania i uważam to za najmniej hackujące rozwiązanie:
extra_hosts
dyrektywie.Jedynym minusem jest to, że jeśli robi to wiele sieci lub projektów, musisz upewnić się, że ich zakres adresów IP nie powoduje konfliktu.
Oto przykład Docker Compose:
Następnie możesz uzyskać dostęp do portów na hoście z kontenera, używając nazwy hosta „dockerhost”.
źródło
W przypadku systemów Linux możesz - począwszy od wersji głównej
20.04
- teraz komunikować się również z hostem za pośrednictwemhost.docker.internal
. To nie zadziała automatycznie , ale musisz podać następującą flagę uruchamiania:Widzieć
źródło
Możesz uzyskać dostęp do lokalnego serwera WWW, który działa na twoim hoście na dwa sposoby.
Podejście 1 z publicznym adresem IP
Użyj publicznego adresu IP komputera hosta, aby uzyskać dostęp do serwera WWW w kontenerze dokowanym Jenkins.
Podejdź do 2 z siecią hosta
Użyj „--net host”, aby dodać kontener dokujący Jenkins do stosu sieciowego hosta. Kontenery rozmieszczone na stosie hosta mają pełny dostęp do interfejsu hosta. Możesz uzyskać dostęp do lokalnego serwera WWW w kontenerze dokowanym z prywatnym adresem IP komputera-hosta.
Uruchom kontener z siecią hosta
Eg: docker run --net host -it ubuntu
i uruchom,ifconfig
aby wyświetlić listę wszystkich dostępnych adresów IP sieci, które są dostępne z kontenera dokera.Np .: Uruchomiłem serwer nginx na moim lokalnym komputerze hosta i jestem w stanie uzyskać dostęp do adresów URL stron internetowych nginx z kontenera dokera Ubuntu.
docker run --net host -it ubuntu
Dostęp do serwera internetowego Nginx (działającego na lokalnym komputerze hosta) z kontenera dokującego Ubuntu z prywatnym adresem IP sieci.
źródło
W przypadku
docker-compose
użycia sieci mostowej do utworzenia sieci prywatnej między kontenerami przyjęte rozwiązaniedocker0
nie działa, ponieważ interfejs wyjściowy z kontenerów nie jest,docker0
ale jest to losowo generowany identyfikator interfejsu, taki jak:Niestety losowy identyfikator nie jest przewidywalny i będzie się zmieniał za każdym razem, gdy komponowanie musi odtworzyć sieć (np. Przy ponownym uruchomieniu hosta). Moim rozwiązaniem jest utworzenie sieci prywatnej w znanej podsieci i skonfigurowanie
iptables
akceptacji tego zakresu:Utwórz fragment pliku:
Możesz zmienić podsieć, jeśli wymaga tego twoje środowisko. Dowolnie wybrałem
192.168.32.0/20
za pomocą,docker network inspect
aby zobaczyć, co było tworzone domyślnie.Skonfiguruj
iptables
na hoście, aby zezwalał na prywatną podsieć jako źródło:To najprostsza możliwa
iptables
reguła. Możesz dodać inne ograniczenia, na przykład według portu docelowego. Nie zapomnij zachować reguł iptables, gdy będziesz zadowolony, że działają.Zaletą tego podejścia jest powtarzalność, a zatem automatyzacja. Korzystam z
template
modułu ansible, aby wdrożyć mój plik tworzenia z podstawieniem zmiennych, a następnie używam modułówiptables
ishell
, aby odpowiednio skonfigurować i zachować reguły zapory.źródło
iptables -A INPUT -i docker0 -j ACCEPT
, ale to mi nie pomogło, podczas gdyiptables -I INPUT 1 -s 192.168.32.0/20 -j ACCEPT
sugerowane tutaj rozwiązało mój problem.To stare pytanie i zawierało wiele odpowiedzi, ale żadne z nich nie pasowało wystarczająco dobrze do mojego kontekstu. W moim przypadku kontenery są bardzo ubogie i nie zawierają narzędzi sieciowych niezbędnych do wyodrębnienia adresu IP hosta z kontenera.
Ponadto,
--net="host"
podejście to jest bardzo surowym podejściem, które nie ma zastosowania, gdy chce się mieć dobrze izolowaną konfigurację sieci z kilkoma kontenerami.Zatem moim podejściem jest wyodrębnienie adresu hosta po stronie hosta, a następnie przekazanie go do kontenera z
--add-host
parametrem:lub zapisz adres IP hosta w zmiennej środowiskowej i użyj tej zmiennej później:
Następnie
docker-host
jest dodawany do pliku hosts kontenera i można go używać w ciągach połączeń z bazą danych lub adresach URL API.źródło
Gdy masz dwa obrazy dokerów „już” utworzone i chcesz umieścić dwa kontenery, aby komunikować się ze sobą.
W tym celu możesz wygodnie uruchomić każdy kontener z własną nazwą - i użyć flagi --link, aby umożliwić komunikację między nimi. Nie dostajesz tego jednak podczas kompilacji dokera.
Kiedy jesteś w scenariuszu takim jak ja i to jest twoje
To się psuje, kiedy próbujesz
i utkniesz na „curl / wget”, nie zwracając „trasy do hosta”.
Powodem są zabezpieczenia ustawione przez dokera, które domyślnie zabraniają komunikacji z kontenera do hosta lub innych kontenerów działających na hoście. To było dla mnie dość zaskakujące, muszę przyznać, że można oczekiwać, że echosfery dokerów działających na lokalnej maszynie po prostu bezbłędnie będą mogły się ze sobą połączyć bez zbytniej przeszkody.
Wyjaśnienie tego zostało szczegółowo opisane w następującej dokumentacji.
http://www.dedoimedo.com/computers/docker-networking.html
Dostępne są dwa szybkie obejścia, które pomagają w poruszaniu się, obniżając bezpieczeństwo sieci.
Mam nadzieję, że te informacje ci pomogą.
źródło
--link
jest teraz przestarzałyDla mnie (Windows 10, Docker Engine v19.03.8) była to kombinacja https://stackoverflow.com/a/43541732/7924573 i https://stackoverflow.com/a/50866007/7924573 .
np .: LOGGER_URL = " http: //host.docker.internal: 8085 / log "
version: '3.7' services: server: build: . ports: - "5000:5000" network_mode: bridge
lub alternatywnie: użyj,--net="bridge"
jeśli nie używasz komponentu dokującego (podobny do https://stackoverflow.com/a/48806927/7924573 )Jak wskazano w poprzednich odpowiedziach: należy tego używać tylko w lokalnym środowisku programistycznym .
Aby uzyskać więcej informacji, przeczytaj: https://docs.docker.com/compose/compose-file/#network_mode i https://docs.docker.com/docker-for-windows/networking/#use-cases-and-workarounds
źródło