Uzyskaj dostęp do bazy danych hosta z kontenera Docker

131

Jeśli mam bazę danych mysql uruchomioną na jakimś komputerze hosta, a na tym hoście również działa kontener Docker: Jak uzyskać dostęp do bazy danych mysql z kontenera docker działającego na hoście?

Na przykład, czy istnieje sposób na opublikowanie portu hostów w kontenerze (odwrotność tego, co robi docker run -p)?

Ryan Anderson
źródło
1
Jeśli serwer MySQL nasłuchuje na porcie, czy kontener nie mógłby po prostu połączyć się z hostem na tym porcie, jak każde inne połączenie internetowe?
jwodder

Odpowiedzi:

87

Istnieje kilka długotrwałych dyskusji na temat tego, jak to zrobić w spójny, dobrze zrozumiały i przenośny sposób. Brak pełnego rozwiązania, ale przekieruję Cię do poniższych dyskusji.

W każdym razie wielu z was chciałoby spróbować użyć opcji --add-host, aby docker run dodać adres IP hosta do pliku / etc / host kontenera. Stamtąd łatwo jest połączyć się z hostem na dowolnym wymaganym porcie:

Dodawanie wpisów do pliku hostów kontenera

Możesz dodać inne hosty do pliku / etc / hosts, używając jednej lub więcej flag --add-host. Ten przykład dodaje statyczny adres dla hosta o nazwie docker:

 $ docker run --add-host=docker:10.180.0.1 --rm -it debian
    $$ ping docker
    PING docker (10.180.0.1): 48 data bytes
    56 bytes from 10.180.0.1: icmp_seq=0 ttl=254 time=7.600 ms
    56 bytes from 10.180.0.1: icmp_seq=1 ttl=254 time=30.705 ms
    ^C--- docker ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max/stddev = 7.600/19.152/30.705/11.553 ms

Uwaga: czasami musisz połączyć się z hostem Docker, co oznacza uzyskanie adresu IP hosta. Aby uprościć ten proces, możesz użyć następujących poleceń powłoki:

 $ alias hostip="ip route show 0.0.0.0/0 | grep -Eo 'via \S+' | awk '{ print $2 }'"
 $ docker run  --add-host=docker:$(hostip) --rm -it debian

Dokumentacja:

https://docs.docker.com/engine/reference/commandline/run/

Dyskusje na temat dostępu do hosta z kontenera:

https://github.com/docker/docker/issues/1143

https://github.com/docker/docker/issues/10023

John Petrone
źródło
Czy będzie działać również za odwrotnym proxy NGINX?
kta
89

Z dokumentów 18.03:

Chcę połączyć się z kontenera z usługą na hoście

Host ma zmieniający się adres IP (lub żaden, jeśli nie masz dostępu do sieci). Od 18.03 zalecamy łączenie się ze specjalną nazwą DNS host.docker.internal, która jest tłumaczona na wewnętrzny adres IP używany przez hosta.

Brama jest również dostępna jako gateway.docker.internal.

PRZYKŁAD: Oto, czego używam jako ciąg połączenia MySQL w moim kontenerze, aby uzyskać dostęp do instancji MySQL na moim hoście:

mysql://host.docker.internal:3306/my_awesome_database
Kevin Chen
źródło
31
Tak samo, jak wskazówka: jak dotąd działa to tylko dla komputerów Mac i Win
flp
uratowałeś mi dzień :)
amjad
4
Głosuj za. Nie tylko ze względu na odpowiedź, ale dlatego, że JAK użyć jej na przykładzie.
granadaCoder
Spędziłem na to prawie 2 godziny, wielkie dzięki.
Ashish Bainade
Wciąż brak wsparcia dla Linuksa, jak napisał @flp, dla ciekawskich. Oto kwestia github .
GAltelino
24

Użyj host.docker.internal od Dockera 18.03.

Igor De Oliveira Sá
źródło
2
w jaki sposób ? czy możesz podać przykład, jak go używać?
danfromisrael
Dlaczego nie uruchomisz dokeryzowanego mysql?
Igor De Oliveira Sá
nie działa dla mnie wDocker version 18.03.0-ce, build 0520e24
scythargon
@ IgorDeOliveiraSá wyobraź sobie następujący scenariusz, w środowisku deweloperskim masz bazę danych, która nasłuchuje 127.0.0.1:3306 na środowisku produkcyjnym, masz bazę danych nasłuchującą 127.0.0.1:3306, lokalnie to lokalna baza danych, produkcja to proxy do chmury, musisz albo dockerise mysql lokalnie i do celów produkcyjnych znajdź inne rozwiązanie lub po prostu połącz się z dockerem do portu, będzie działać w obu przypadkach
Drachenfels
1
docker.for.mac.localhost działa u mnie w dniu18.03.1-ce-mac65
cdignam
21

Inne odpowiedzi nie działały dobrze dla mnie. Mój kontener nie mógł rozpoznać adresu IP hosta za pomocą host.docker.internal . Istnieją dwa sposoby

  1. Udostępnianie sieci hosta --net = host:

    docker run -it --net=host  myimage
    
  2. Używam adresu IP dockera, który zwykle to 172.17.0.1 . Możesz to sprawdzić, wywołując polecenie ifconfig i pobierając adres inet interfejsu dockera

    user@ubuntu:~$ ifconfig
    docker0   Link encap:Ethernet  HWaddr 02:42:a4:a2:b2:f1  
      inet addr:172.17.0.1  Bcast:0.0.0.0  Mask:255.255.0.0
      inet6 addr: fe80::42:a4ff:fea2:b2f1/64 Scope:Link
    

Gdy już masz ten adres IP, możesz przekazać go jako argument do uruchomienia dockera, a następnie do aplikacji lub, tak jak ja, zmapować lokalizację jdbc.properties przez wolumin do katalogu na komputerze hosta, abyś mógł zarządzać plikiem zewnętrznie .

  docker run -it -v /host_dir/docker_jdbc_config:${jetty_base}/var/config myimage

UWAGA: Twoja baza danych może nie zezwalać na połączenia zewnętrzne. W przypadku postgresql musisz edytować 2 pliki, jak opisano tutaj i tutaj :

  1. Edytuj postgresql.conf, aby nasłuchiwać na wszystkich adresach. Domyślnie będzie wskazywać na localhost.

    listen_addresses = '*'
    
  2. Edytuj pg_hba.conf, aby zezwolić na połączenia ze wszystkich adresów. Dodaj w ostatnim wierszu:

    host     all             all             0.0.0.0/0               md5
    

WAŻNE: Ostatni krok aktualizacji dostępu do bazy danych nie jest zalecany do użytku produkcyjnego, chyba że jesteś naprawdę pewien, co robisz.

gmode
źródło
--net = host pracował dla mnie w środowisku CI, wielkie dzięki!
Samy