Greifen Sie über einen Docker-Container auf die Host-Datenbank zu


130

Wenn auf einem Hostcomputer eine MySQL-Datenbank ausgeführt wird und auf diesem Host auch ein Docker-Container ausgeführt wird: Wie würde ich über den Docker-Container, der auf dem Host ausgeführt wird, auf die MySQL-Datenbank zugreifen?

Gibt es zum Beispiel eine Möglichkeit, einen Host-Port im Container zu veröffentlichen (umgekehrt zu dem, was Docker-Run -p macht)?


1
Wenn der MySQL-Server einen Port überwacht, kann der Container dann nicht einfach wie jede andere Internetverbindung eine Verbindung zum Host an diesem Port herstellen?
Jwodder

Antworten:


87

Es gibt mehrere langjährige Diskussionen darüber, wie dies auf konsistente, gut verstandene und tragbare Weise geschehen kann. Keine vollständige Lösung, aber ich werde Sie mit den folgenden Diskussionen verknüpfen.

In jedem Fall möchten Sie viele versuchen, die Option --add-host zum Andocken auszuführen, um die IP-Adresse des Hosts in die Datei / etc / host des Containers einzufügen. Von dort aus ist es trivial, über einen beliebigen Port eine Verbindung zum Host herzustellen:

Hinzufügen von Einträgen zu einer Container-Hosts-Datei

Sie können andere Hosts zur Datei / etc / hosts eines Containers hinzufügen, indem Sie ein oder mehrere --add-host-Flags verwenden. In diesem Beispiel wird eine statische Adresse für einen Host namens Docker hinzugefügt:

 $ 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

Hinweis: Manchmal müssen Sie eine Verbindung zum Docker-Host herstellen, dh Sie müssen die IP-Adresse des Hosts abrufen. Sie können die folgenden Shell-Befehle verwenden, um diesen Vorgang zu vereinfachen:

 $ 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

Dokumentation:

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

Diskussionen zum Zugriff auf den Host vom Container aus:

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

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


Funktioniert es auch hinter einem NGINX-Reverse-Proxy?
kta

88

Aus den 18.03 Dokumenten:

Ich möchte eine Verbindung von einem Container zu einem Dienst auf dem Host herstellen

Der Host hat eine sich ändernde IP-Adresse (oder keine, wenn Sie keinen Netzwerkzugriff haben). Ab dem 18.03. Empfehlen wir, eine Verbindung zum speziellen DNS-Namen herzustellenhost.docker.internal herzustellen, der in die vom Host verwendete interne IP-Adresse aufgelöst wird.

Das Gateway ist auch erreichbar als gateway.docker.internal.

BEISPIEL: Folgendes verwende ich für meine MySQL-Verbindungszeichenfolge in meinem Container, um auf die MySQL-Instanz auf meinem Host zuzugreifen:

mysql://host.docker.internal:3306/my_awesome_database

31
Nur als Hinweis: Dies funktioniert bisher nur für Mac und Win
flp

Du hast meinen Tag gerettet :)
Amjad

4
Upvote. Nicht nur wegen der Antwort, sondern weil Sie es mit einem Beispiel verwenden sollten.
GranadaCoder

Ich habe fast 2 Stunden dafür aufgewendet, vielen Dank.
Ashish Bainade

Immer noch keine Linux-Unterstützung, wie @flp schrieb, für Neugierige. Hier ist das Github-Problem .
GAltelino


24

Verwenden Sie host.docker.internal ab Docker 18.03 .


2
Wie ? Können Sie ein Beispiel für die Verwendung geben?
Danfromisrael

Warum führen Sie kein Docker-MySQL aus?
Igor De Oliveira Sá

funktioniert nicht für mich beiDocker version 18.03.0-ce, build 0520e24
scythargon

@ IgorDeOliveiraSá Stellen Sie sich folgendes Szenario vor: In einer Entwicklungsumgebung haben Sie eine Datenbank, die 127.0.0.1:3306 in der Produktionsumgebung abhört. Sie haben eine Datenbank, die 127.0.0.1:3306 abhört. Lokal ist es eine lokale Datenbank. Die Produktion ist ein Proxy für die Cloud dockerise mysql lokal und und für die Produktion finden Sie eine andere Lösung, oder Sie können einfach von Docker zu Port verbinden, es wird in beiden Fällen funktionieren
Drachenfels

1
docker.for.mac.localhost arbeitet für mich am18.03.1-ce-mac65
cdignam

21

Andere Antworten haben bei mir nicht gut funktioniert. Mein Container konnte die Host-IP nicht mit host.docker.internal auflösen . Es gibt zwei Möglichkeiten

  1. Host-Netzwerk gemeinsam nutzen --net = Host:

    docker run -it --net=host  myimage
    
  2. Verwenden der Docker-IP-Adresse, die normalerweise 172.17.0.1 lautet . Sie können dies überprüfen, indem Sie den Befehl ifconfig aufrufen und inet addr der Docker-Schnittstelle abrufen

    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
    

Sobald Sie diese IP-Adresse haben, können Sie sie als Argument an Docker Run und dann an Application übergeben oder wie ich den Speicherort von jdbc.properties über Volume dem Verzeichnis auf dem Hostcomputer zuordnen, damit Sie die Datei extern verwalten können .

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

HINWEIS: Ihre Datenbank lässt möglicherweise keine externen Verbindungen zu. Im Falle von postgresql müssen Sie 2 Dateien bearbeiten, wie hier und hier beschrieben :

  1. Bearbeiten Sie die Datei postgresql.conf, um alle Adressen abzuhören. Standardmäßig zeigt es auf localhost.

    listen_addresses = '*'
    
  2. Bearbeiten Sie die Datei pg_hba.conf, um Verbindungen von allen Adressen zuzulassen. In der letzten Zeile hinzufügen:

    host     all             all             0.0.0.0/0               md5
    

WICHTIG: Der letzte Schritt zum Aktualisieren des Datenbankzugriffs wird für die Verwendung in der Produktion nicht empfohlen, es sei denn, Sie sind sich wirklich sicher, was Sie tun.


--net = Host hat für mich in einer CI-Umgebung gearbeitet, vielen Dank!
Samy
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.