it-swarm.com.de

Wie verbinde ich mich innerhalb eines Docker-Containers mit dem localhost des Computers?

Ich habe also einen Nginx in einem Docker-Container, ich habe ein Mysql auf localhost, ich möchte eine Verbindung zu MySql von meinem Nginx aus herstellen. MySql läuft auf localhost und macht keinen Port für die Außenwelt verfügbar. Daher ist es an localhost gebunden, nicht an die IP-Adresse des Computers.

Gibt es eine Möglichkeit, eine Verbindung zu diesem MySql oder einem anderen Programm auf localhost in diesem Docker-Container herzustellen?

826
Phil

Bearbeiten: Wenn Sie Docker-für-Mac oder Docker-für-Windows verwenden 18.03 +, verbinde dich einfach mit dem Host Host.docker.internal mit deinem MySQL-Dienst.

Ab Docker 18.09.3 funktioniert dies unter Docker-for-Linux nicht. Ein Fix wurde im März eingereicht der 8., 2019 und wird hoffentlich auf die Codebasis zusammengeführt. Bis dahin besteht eine Problemumgehung darin, einen Container zu verwenden, wie in qoomons Antwort beschrieben.


TLDR

Verwenden Sie --network="Host" In Ihrem Befehl docker run, Dann zeigt 127.0.0.1 In Ihrem Docker-Container auf Ihren Docker-Host.

Hinweis: Dieser Modus funktioniert nur unter Docker für Linux gemäß Dokumentation .


Hinweis zu den Netzwerkmodi für Docker-Container

Docker bietet verschiedene Netzwerkmodi beim Ausführen von Containern. Abhängig vom gewählten Modus würden Sie eine andere Verbindung zu Ihrer MySQL-Datenbank herstellen, die auf dem Docker-Host ausgeführt wird.

docker run --network = "bridge" (Standard)

Docker erstellt standardmäßig eine Bridge mit dem Namen docker0. Sowohl der Docker-Host als auch die Docker-Container haben eine IP-Adresse auf dieser Bridge.

geben Sie auf dem Docker-Host Sudo ip addr show docker0 ein. Die Ausgabe sieht dann folgendermaßen aus:

[[email protected]:~] $ Sudo ip addr show docker0
4: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 56:84:7a:fe:97:99 brd ff:ff:ff:ff:ff:ff
    inet 172.17.42.1/16 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::5484:7aff:fefe:9799/64 scope link
       valid_lft forever preferred_lft forever

Mein Docker-Host hat hier also die IP-Adresse 172.17.42.1 Auf der Netzwerkschnittstelle docker0.

Jetzt starte einen neuen Container und erhalte eine Shell: docker run --rm -it ubuntu:trusty bash Und innerhalb des Containertyps ip addr show eth0, Um herauszufinden, wie seine Hauptnetzwerkschnittstelle eingerichtet ist:

[email protected]:/# ip addr show eth0
863: eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 66:32:13:f0:f1:e3 brd ff:ff:ff:ff:ff:ff
    inet 172.17.1.192/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::6432:13ff:fef0:f1e3/64 scope link
       valid_lft forever preferred_lft forever

Hier hat mein Container die IP-Adresse 172.17.1.192. Schauen Sie sich nun die Routing-Tabelle an:

[email protected]:/# route
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         172.17.42.1     0.0.0.0         UG    0      0        0 eth0
172.17.0.0      *               255.255.0.0     U     0      0        0 eth0

Daher ist die IP-Adresse des Docker-Hosts 172.17.42.1 Als Standardroute festgelegt und von Ihrem Container aus zugänglich.

[email protected]:/# ping 172.17.42.1
PING 172.17.42.1 (172.17.42.1) 56(84) bytes of data.
64 bytes from 172.17.42.1: icmp_seq=1 ttl=64 time=0.070 ms
64 bytes from 172.17.42.1: icmp_seq=2 ttl=64 time=0.201 ms
64 bytes from 172.17.42.1: icmp_seq=3 ttl=64 time=0.116 ms

docker run --network = "Host"

Alternativ können Sie einen Docker-Container mit Netzwerkeinstellungen auf Host ausführen. Ein solcher Container teilt den Netzwerkstapel mit dem Docker-Host und aus der Sicht des Containers bezieht sich localhost (oder 127.0.0.1) Auf den Docker-Host.

Beachten Sie, dass alle in Ihrem Docker-Container geöffneten Ports auf dem Docker-Host geöffnet werden. Und das ohne die Option -p Oder -Pdocker run .

IP-Konfiguration auf meinem Docker-Host:

[[email protected]:~] $ ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe98:dcaa/64 scope link
       valid_lft forever preferred_lft forever

und von einem Docker-Container im Host Modus:

[[email protected]:~] $ docker run --rm -it --network=Host ubuntu:trusty ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 08:00:27:98:dc:aa brd ff:ff:ff:ff:ff:ff
    inet 10.0.2.15/24 brd 10.0.2.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:fe98:dcaa/64 scope link
       valid_lft forever preferred_lft forever

Wie Sie sehen, teilen sich der Docker-Host und der Docker-Container genau dieselbe Netzwerkschnittstelle und haben als solche dieselbe IP-Adresse.


Herstellen einer Verbindung zu MySQL aus Containern

brückenmodus

Um von Containern im Bridge-Modus auf MySQL zuzugreifen, das auf dem Docker-Host ausgeführt wird, müssen Sie sicherstellen, dass der MySQL-Dienst auf Verbindungen mit der IP-Adresse 172.17.42.1 Wartet.

Stellen Sie dazu sicher, dass Sie entweder bind-address = 172.17.42.1 Oder bind-address = 0.0.0.0 In Ihrer MySQL-Konfigurationsdatei (my.cnf) haben.

Wenn Sie eine Umgebungsvariable mit der IP-Adresse des Gateways festlegen müssen, können Sie den folgenden Code in einem Container ausführen:

export DOCKER_Host_IP=$(route -n | awk '/UG[ \t]/{print $2}')

verwenden Sie dann in Ihrer Anwendung die Umgebungsvariable DOCKER_Host_IP, um die Verbindung zu MySQL herzustellen.

Hinweis: Wenn Sie bind-address = 0.0.0.0 Verwenden, wartet Ihr MySQL-Server auf Verbindungen an allen Netzwerkschnittstellen. Das bedeutet, dass Ihr MySQL-Server über das Internet erreichbar ist. Stellen Sie sicher, dass Sie die Firewall-Regeln entsprechend einrichten.

Hinweis 2: Wenn Sie bind-address = 172.17.42.1 Verwenden, wartet Ihr MySQL-Server nicht auf Verbindungen, die zu 127.0.0.1 Hergestellt wurden. Prozesse, die auf dem Docker-Host ausgeführt werden und eine Verbindung zu MySQL herstellen möchten, müssen die IP-Adresse 172.17.42.1 Verwenden.

Host-Modus

Um von Containern im Host-Modus auf MySQL zuzugreifen, das auf dem Docker-Host ausgeführt wird, können Sie bind-address = 127.0.0.1 In Ihrer MySQL-Konfiguration belassen. Sie müssen lediglich eine Verbindung zu 127.0.0.1 aus Ihren Behältern:

[[email protected]:~] $ docker run --rm -it --network=Host mysql mysql -h 127.0.0.1 -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 36
Server version: 5.5.41-0ubuntu0.14.04.1 (Ubuntu)

Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql>

Anmerkung: Verwenden Sie mysql -h 127.0.0.1 und nicht mysql -h localhost; Andernfalls würde der MySQL-Client versuchen, eine Verbindung über einen Unix-Socket herzustellen.

1507
Thomasleveil

Für Mac OS und Windows

Docker v 18.03 und höher (seit 21. März 2018)

Verwenden Sie Ihre interne IP-Adresse oder stellen Sie eine Verbindung mit dem speziellen DNS-Namen Host.docker.internal her, der in die vom Host verwendete interne IP-Adresse aufgelöst wird.

Linux-Unterstützung ausstehend https://github.com/docker/for-linux/issues/264

MacOS mit früheren Versionen von Docker

Docker für Mac v 17.12 bis v 18.02

Wie oben, aber stattdessen docker.for.mac.Host.internal verwenden.

Docker für Mac v 17.06 bis v 17.11

Wie oben, aber stattdessen docker.for.mac.localhost verwenden.

Docker für Mac 17.05 und darunter

Um vom Docker-Container aus auf den Host-Computer zuzugreifen, müssen Sie einen IP-Alias ​​an Ihre Netzwerkschnittstelle anhängen. Sie können die gewünschte IP-Adresse binden, stellen Sie jedoch sicher, dass Sie sie nicht für andere Zwecke verwenden.

Sudo ifconfig lo0 alias 123.123.123.123/24 

Stellen Sie dann sicher, dass Ihr Server die oben erwähnte IP-Adresse oder 0.0.0.0 abhört. Wenn er localhost 127.0.0.1 hört, akzeptiert er die Verbindung nicht.

Dann richten Sie Ihren Docker-Container einfach auf diese IP und Sie können auf die Host-Maschine zugreifen!

Zum Testen können Sie etwas wie curl -X GET 123.123.123.123:3000 im Container ausführen.

Der Alias ​​wird bei jedem Neustart zurückgesetzt. Erstellen Sie gegebenenfalls ein Startskript.

Lösung und weitere Dokumentation hier: https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds

247
Janne Annala

Ich mache einen Hack, der den obigen Posts ähnlich ist, um die lokale IP einem Aliasnamen (DNS) im Container zuzuordnen. Das Hauptproblem besteht darin, mit einem einfachen Skript dynamisch zu arbeiten, das sowohl in Linux als auch in OSX die Host-IP-Adresse verwendet. Ich habe dieses Skript gemacht, das in beiden Umgebungen funktioniert (sogar in Linux-Distribution mit "$LANG" != "en_*" konfiguriert):

ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1

Wenn Sie Docker Compose verwenden, ist die vollständige Konfiguration also:

Startup-Skript (docker-run.sh):

export DOCKERHOST=$(ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1)
docker-compose -f docker-compose.yml up

docker-compose.yml:

myapp:
  build: .
  ports:
    - "80:80"
  extra_hosts:
    - "dockerhost:$DOCKERHOST"

Ändern Sie dann http://localhost in http://dockerhost in Ihrem Code.

Eine ausführlichere Anleitung zum Anpassen des DOCKERHOST-Skripts finden Sie in diesem Beitrag mit einer Erläuterung seiner Funktionsweise.

57
Mariano Ruiz

Dies funktionierte für mich auf einem NGINX/PHP-FPM-Stack, ohne Code oder Netzwerke zu berühren, von denen die App nur erwartet, dass sie eine Verbindung zu localhost herstellen kann.

Hängen Sie mysqld.sock Vom Host in den Container ein.

Suchen Sie den Speicherort der Datei mysql.sock auf dem Host, auf dem mysql ausgeführt wird:
netstat -ln | awk '/mysql(.*)?\.sock/ { print $9 }'

Hängen Sie diese Datei dort ein, wo sie im Andockfenster erwartet wird:
docker run -v /hostpath/to/mysqld.sock:/containerpath/to/mysqld.sock

Mögliche Standorte von mysqld.sock:

/tmp/mysqld.sock
/var/run/mysqld/mysqld.sock 
/var/lib/mysql/mysql.sock
/Applications/MAMP/tmp/mysql/mysql.sock # if running via MAMP
37
user833482

Lösung für Linux (Kernel> = 3.6). 

Ok, Ihr localhost-Server verfügt über die standardmäßige Docker-Schnittstelle docker0 mit der IP-Adresse 172.17.0.1. Ihr Container wurde mit den Standard-Netzwerkeinstellungen --net = "bridge" gestartet. 

  1. Route_localnet für Docker0-Schnittstelle aktivieren:
    $ sysctl -w net.ipv4.conf.docker0.route_localnet=1
  2. Fügen Sie diese Regeln zu iptables hinzu:
    $ iptables -t nat -I PREROUTING -i docker0 -d 172.17.0.1 -p tcp --dport 3306 -j DNAT --to 127.0.0.1:3306
    $ iptables -t filter -I INPUT -i docker0 -d 127.0.0.1 -p tcp --dport 3306 -j ACCEPT
  3. Erstellen Sie einen MySQL-Benutzer mit Zugriff von "%", der bedeutet - von jedem beliebigen Benutzer, ausgenommen localhost:
    CREATE USER 'user'@'%' IDENTIFIED BY 'password';
  4. Ändern Sie in Ihrem Skript die Adresse des MySQL-Servers in 172.17.0.1


Aus der Kernel-Dokumentation :

route_localnet - BOOLEAN: Schleifenadressen werden beim Routing nicht als Martian-Quelle oder -Ziel betrachtet. Dies ermöglicht die Verwendung von 127/8 für lokales Routing (default FALSE).

11
Ray D

Lösung für Windows 10

Docker Community Edition 17.06.0-ce-win18 2017-06-28 (stabil)

Sie können den DNS-Namen des Hosts docker.for.win.localhost verwenden, um die interne IP-Adresse aufzulösen. (Warnung in einigen Quellen erwähnt windows, es sollte jedoch win sein)

Überblick
Ich musste etwas Ähnliches tun, nämlich eine Verbindung von meinem Docker-Container zu meinem localhost, auf dem Azure Storage Emulator und CosmosDB Emulator ausgeführt wurden.

Der Azure Storage Emulator hört standardmäßig auf 127.0.0.1. Während Sie die IP-Adresse auch ändern können, habe ich nach einer Lösung gesucht, die mit den Standardeinstellungen funktioniert.

Dies funktioniert auch für die Verbindung von meinem Docker-Container zu SQL Server und IIS, die beide lokal auf meinem Host mit Standardporteinstellungen ausgeführt werden.

10
Ralph Willgoss

Wenn Sie den Bridge-Netzwerktreiber verwenden, müssen Sie MySQL speziell an die IP-Adresse der Hyper-V-Netzwerkschnittstelle binden. 

Dies erfolgt über die Konfigurationsdatei unter dem normalerweise versteckten Ordner C:\ProgramData\MySQL. 

Das Binden an 0.0.0.0 funktioniert nicht. Die benötigte Adresse wird auch in der Docker-Konfiguration angezeigt und war in meinem Fall 10.0.75.1.

8
Casey

Edit: Ich habe das Konzept auf GitHub prototypisiert. Check out:https://github.com/sivabudh/system-in-a-box


Erstens ist meine Antwort auf zwei Gruppen von Leuten ausgerichtet: diejenigen, die einen Mac verwenden, und diejenigen, die Linux verwenden.

Der Netzwerkmodus Host funktioniert auf einem Mac nicht. Sie müssen einen IP-Alias ​​verwenden, siehe: https://stackoverflow.com/a/43541681/2713729

Was ist ein Host-Netzwerkmodus? Siehe: https://docs.docker.com/engine/reference/run/#/network-settings

Zweitens: Für diejenigen von Ihnen, die Linux verwenden (meine direkte Erfahrung hatte ich mit Ubuntu 14.04 LTS und ich werde in Kürze auf 16.04 LTS upgraden), yes, können Sie den Dienst in einem Docker-Container herstellen lassen localhost Dienste, die auf dem Docker Host ausgeführt werden (z. B. Ihr Laptop).

Wie?

Der Schlüssel ist, wenn Sie den Docker-Container ausführen, müssen Sie ihn im Host -Modus ausführen. Der Befehl sieht so aus:

docker run --network="Host" -id <Docker image ID>

Wenn Sie eine ifconfig (Sie müssen Ihren Container apt-get install net-tools für den Aufruf von ifconfig aufrufen) in Ihrem Container ausführen, werden Sie feststellen, dass die Netzwerkschnittstellen mit denen auf Docker Host (z. B. Ihrem Laptop) identisch sind. 

Es ist wichtig zu wissen, dass ich ein Mac-Benutzer bin, aber ich lasse Ubuntu unter Parallels laufen, daher ist die Verwendung eines Macs kein Nachteil. ;-)

Und so verbinden Sie den NGINX-Container mit dem MySQL, das auf einer localhost ausgeführt wird.

7
sivabudh

bis Host.docker.internal für jede Plattform funktioniert, können Sie meinen Container als NAT - Gateway ohne manuelles Setup verwenden. https://github.com/qoomon/docker-Host

5
qoomon

Einfachste Lösung für Mac OSX

Verwenden Sie einfach die IP-Adresse Ihres Mac. Führen Sie auf dem Mac Folgendes aus, um die IP-Adresse abzurufen und innerhalb des Containers zu verwenden:

$ ifconfig | grep 'inet 192'| awk '{ print $2}'

Solange der Server, der lokal auf Ihrem Mac oder in einem anderen Docker-Container ausgeführt wird, 0.0.0.0 überwacht, kann der Docker-Container diese Adresse erreichen.

Wenn Sie nur auf einen anderen Docker-Container zugreifen möchten, der 0.0.0.0 überwacht, können Sie 172.17.0.1 verwenden

4
dansalmo

Hier ist meine Lösung: Es funktioniert für meinen Fall

  • setzen Sie den lokalen MySQL-Server per Kommentar #bind-address = 127.0.0.1 in /etc/mysql/mysql.conf.d auf öffentlichen Zugriff

  • starte mysql server neu Sudo /etc/init.d/mysql restart

  • führen Sie den folgenden Befehl aus, um den Root-Zugriff eines beliebigen Hosts zu öffnen mysql -uroot -proot GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION; FLUSH PRIVILEGES;

  • erstellen Sie das sh-Skript: run_docker.sh

 #! bin/bash 
 
 HOSTIP = `ip -4 addr show scope global dev eth0 | grep inet | awk '{print\$ 2}' | cut -d/-f 1` 
 
 
 docker run -it -d --name web-app\
 --add-Host = local: $ {HOSTIP}\
 -P 8080: 8080\
 -E DATABASE_Host = $ {HOSTIP}\
 -E DATABASE_PORT = 3306\
 -E DATABASE_NAME = Demo\
 -e DATABASE_USER = root\
 -e DATABASE_PASSWORD = root\
 sopheamak/springboot_docker_mysql 
 
 
  • laufen Sie mit Docker-Composer

     Version: '2.1' 
     
    
    dienstleistungen:
    tomcatwar: extra_hosts: - "local: 10.1.2.232" image: sopheamak/springboot_docker_mysql
    Ports: - 8080: 8080 Umgebung: - DATABASE_Host = local - DATABASE_USER = root - DATABASE_PASSWORD = root - DATABASE_NAME = Demo - DATABASE_PORT = 3306
4
sopheamak

Dies ist keine Antwort auf die eigentliche Frage. So habe ich ein ähnliches Problem gelöst. Die Lösung kommt komplett von: Docker Container Networking definieren, damit Container kommunizieren können . Vielen Dank an Nic Raboy

Lassen Sie dies hier für andere, die möglicherweise REST Aufrufe zwischen einem Container und einem anderen ausführen möchten. Beantwortet die Frage: Was soll anstelle von localhost in einer Docker-Umgebung verwendet werden?

Holen Sie sich, wie Ihr Netzwerk aussieht docker network ls

Erstelle ein neues Netzwerk docker network create -d my-net

Starte den ersten Container docker run -d -p 5000:5000 --network="my-net" --name "first_container" <MyImage1:v0.1>

Überprüfen Sie die Netzwerkeinstellungen für den ersten Container docker inspect first_container. "Netzwerke": sollte "my-net" haben

Starte den zweiten Container docker run -d -p 6000:6000 --network="my-net" --name "second_container" <MyImage2:v0.1>

Überprüfen Sie die Netzwerkeinstellungen für den zweiten Container docker inspect second_container. "Netzwerke": sollte "my-net" haben

ssh in deinen zweiten Container docker exec -it second_container sh oder docker exec -it second_container bash.

Innerhalb des zweiten Containers können Sie den ersten Container mit ping first_container anpingen. Auch Ihre Code-Aufrufe wie http://localhost:5000 können durch http://first_container:5000 ersetzt werden.

3

Mehrere Lösungen kommen in den Sinn:

  1. Verschieben Sie Ihre Abhängigkeiten zuerst in Container
  2. Machen Sie Ihre anderen Dienste von außen zugänglich und stellen Sie mit dieser externen IP eine Verbindung zu ihnen her
  3. Führen Sie Ihre Container ohne Netzwerkisolation aus
  4. Vermeiden Sie es, eine Verbindung über das Netzwerk herzustellen, und verwenden Sie stattdessen einen als Volume bereitgestellten Socket

Der Grund dafür ist, dass Container standardmäßig mit einem eigenen Netzwerk-Namespace ausgeführt werden. Das bedeutet, dass localhost (oder 127.0.0.1, das auf die Loopback-Schnittstelle verweist) pro Container eindeutig ist. Wenn Sie eine Verbindung herstellen, wird eine Verbindung mit dem Container selbst hergestellt und keine Dienste, die außerhalb von Docker oder innerhalb eines anderen Docker-Containers ausgeführt werden.

Option 1 : Wenn Ihre Abhängigkeit in einen Container verschoben werden kann, würde ich dies zuerst tun. Es macht Ihren Anwendungsstapel portabel, da andere versuchen, Ihren Container in ihrer eigenen Umgebung auszuführen. Sie können den Port auch weiterhin auf Ihrem Host veröffentlichen, sodass andere Dienste, die nicht migriert wurden, darauf zugreifen können. Sie können den Port sogar auf der localhost-Schnittstelle Ihres Docker-Hosts veröffentlichen, um einen externen Zugriff mit einer Syntax wie der folgenden zu vermeiden: -p 127.0.0.1:3306:3306 für den veröffentlichten Port.

Option 2 : Es gibt verschiedene Möglichkeiten, die Host-IP-Adresse aus dem Container heraus zu ermitteln, aber jede hat eine begrenzte Anzahl von Szenarien, in denen sie funktionieren (zB Docker für Mac erforderlich). Am portabelsten ist es, Ihre Host-IP-Adresse mit einer Umgebungsvariablen oder einer Konfigurationsdatei in den Container einzuspeisen, z.

docker run --rm -e "Host_IP=$(ip r s 0/0 | awk '{print $3}')" ...

Dies setzt voraus, dass Ihr Dienst diese externe Schnittstelle überwacht, was ein Sicherheitsrisiko darstellen könnte. Für andere Methoden zum Abrufen der Host-IP-Adresse aus dem Container: siehe diesen Beitrag .

Option 3 : Ohne Netzwerkisolation ausgeführt, d. H. Mit --net Host ausgeführt, bedeutet, dass Ihre Anwendung im Host-Netzwerknamespace ausgeführt wird. Dies ist weniger isolierend für den Container und bedeutet, dass Sie nicht über ein gemeinsam genutztes Docking-Netzwerk mit DNS auf andere Container zugreifen können (stattdessen müssen Sie veröffentlichte Ports verwenden, um auf andere containerisierte Anwendungen zuzugreifen). Für Anwendungen, die auf andere Dienste auf dem Host zugreifen müssen, die nur 127.0.0.1 auf dem Host abhören, kann dies die einfachste Option sein.

Option 4 : Verschiedene Dienste ermöglichen auch den Zugriff über einen dateisystembasierten Socket. Dieser Socket kann als gebundenes Volume in den Container eingebunden werden, sodass Sie auf den Host-Dienst zugreifen können, ohne das Netzwerk zu verlassen. Für den Zugriff auf die Docker-Engine sehen Sie häufig Beispiele für das Einbinden von /var/run/docker.sock in den Container (wobei dieser Container als Root auf den Host zugreifen kann). Mit mysql können Sie etwas wie -v /var/run/mysqld/mysqld.sock:/var/run/mysqld/mysql.sock ausprobieren und dann eine Verbindung zu localhost herstellen, in das mysql mithilfe des Sockets konvertiert.

3
BMitch

Ich stimme der Antwort von Thomasleveil nicht zu.

Wenn MySQL an 172.17.42.1 gebunden wird, wird verhindert, dass andere Programme die Datenbank auf dem Host verwenden, um sie zu erreichen. Dies funktioniert nur, wenn alle Datenbankbenutzer angedockt sind.

Wenn Sie mysql an 0.0.0.0 binden, wird die Datenbank für die Außenwelt geöffnet, was nicht nur eine sehr schlechte Sache ist, sondern auch im Gegensatz zu dem, was der ursprüngliche Autor der Frage tun möchte. Er sagt ausdrücklich "Das MySql läuft auf localhost und macht keinen Port für die Außenwelt zugänglich, daher ist es an localhost gebunden"

Um den Kommentar von ivant zu beantworten

"Warum bindet man mysql nicht auch an docker0?"

Das ist nicht möglich. In der Dokumentation zu mysql/mariadb heißt es explizit, dass es nicht möglich ist, an mehrere Schnittstellen zu binden. Sie können nur an 0, 1 oder alle Schnittstellen binden.

Als Fazit habe ich KEINEN Weg gefunden, die (nur localhost) Datenbank auf dem Host von einem Docker-Container zu erreichen. Das scheint definitiv ein sehr gewöhnliches Muster zu sein, aber ich weiß nicht, wie es geht.

2
orzel

Die CG-Gruppen und Namespaces spielen eine wichtige Rolle im Container-Ökosystem.

Der Namespace bietet eine Isolationsebene. Jeder Container wird in einem separaten Namespace ausgeführt und sein Zugriff ist auf diesen Namespace beschränkt. Die Cgroups steuern die Ressourcennutzung jedes Containers, wohingegen der Namespace steuert, was ein Prozess auf die jeweilige Ressource sehen und auf sie zugreifen kann. 

Hier ist das grundlegende Verständnis des Lösungsansatzes, dem Sie folgen könnten:

Netzwerk-Namespace verwenden

Wenn ein Container aus einem Image hervorgeht, wird eine Netzwerkschnittstelle definiert und erstellt. Dadurch erhält der Container eine eindeutige IP-Adresse und Schnittstelle.

$ docker run -it Alpine ifconfig

Durch die Änderung des Namespaces in Host bleiben Cotainers Networks nicht von seiner Schnittstelle isoliert. Der Prozess hat Zugriff auf die Netzwerkschnittstelle von Host-Computern.

$ docker run -it --net=Host Alpine ifconfig

Wenn der Prozess Ports überwacht, werden sie auf der Hostschnittstelle überwacht und dem Container zugeordnet.

PID-Namespace verwenden Durch Ändern des Pid-Namespace kann ein Container mit anderen Prozessen außerhalb seines normalen Bereichs interagieren.

Dieser Container wird in einem eigenen Namespace ausgeführt.

$ docker run -it Alpine ps aux

Durch die Änderung des Namespaces in den Host kann der Container auch alle anderen Prozesse sehen, die auf dem System ausgeführt werden.

$ docker run -it --pid=Host Alpine ps aux

Namespace freigeben

Dies ist eine schlechte Vorgehensweise, um dies in der Produktion zu tun, da Sie das Containersicherheitsmodell ausbrechen, das Schwachstellen auslösen kann, und einen einfachen Zugang zum Lauscher ermöglichen. Dies ist nur für das Debugging von Tools und das Erkennen der Lücken in der Containersicherheit.

Der erste Container ist der Nginx-Server. Dadurch wird ein neuer Netzwerk- und Prozess-Namespace erstellt. Dieser Container bindet sich an Port 80 der neu erstellten Netzwerkschnittstelle. 

$ docker run -d --name http nginx:Alpine

Ein anderer Container kann diesen Namespace jetzt wiederverwenden.

$ docker run --net=container:http mohan08p/curl curl -s localhost

Dieser Container kann auch die Schnittstelle mit den Prozessen in einem gemeinsam genutzten Container sehen.

$ docker run --pid=container:http Alpine ps aux

Auf diese Weise können Sie Containern mehr Berechtigungen zuweisen, ohne die Anwendung ändern oder neu starten zu müssen. Auf ähnliche Weise können Sie sich mit mysql on Host verbinden, Ihre Anwendung ausführen und debuggen. Aber es ist nicht zu empfehlen, auf diesem Weg zu gehen. Ich hoffe es hilft. 

2
mohan08p

Sie können die Host-IP mit dem Alpine-Image abrufen

docker run --rm Alpine ip route | awk 'NR==1 {print $3}'

Dies ist konsistenter, da Sie zum Ausführen des Befehls immer Alpine verwenden.

Ähnlich wie bei Marianos Antwort können Sie den gleichen Befehl verwenden, um eine Umgebungsvariable festzulegen

DOCKER_Host=$(docker run --rm Alpine ip route | awk 'NR==1 {print $3}') docker-compose up
2
hasnat

Für Windows-Computer: -

Führen Sie den folgenden Befehl aus, um den Dockerport während der Erstellung nach dem Zufallsprinzip anzuzeigen

$docker run -d --name MyWebServer -P mediawiki

 enter image description here

 enter image description here

In der obigen Containerliste können Sie den als 32768 zugewiesenen Port sehen. Versuchen Sie, darauf zuzugreifen 

localhost:32768 

Sie können die Mediawiki-Seite sehen

1
Lokesh S

Überprüfen Sie ganz einfach und schnell Ihre Host-IP mit ifconfig (Linux) oder ipconfig (Windows) und erstellen Sie eine

docker-compose.yml

version: '3' # specify docker-compose version

services:
  nginx:
    build: ./ # specify the directory of the Dockerfile
    ports:
      - "8080:80" # specify port mapping
    extra_hosts:
      - "dockerhost:<yourIP>"

Auf diese Weise kann Ihr Container auf Ihren Host zugreifen. Denken Sie beim Zugriff auf Ihre Datenbank daran, den zuvor angegebenen Namen zu verwenden, in diesem Fall "dockerhost" und den Port Ihres Hosts, auf dem die Datenbank ausgeführt wird

1
Felipe Toledo

Bis fix nicht mit dem Zweig master zusammengeführt wird, um die Host-IP zu erhalten, führen Sie einfach Folgendes aus dem Container aus:

ip -4 route list match 0/0 | cut -d' ' -f3

(wie von @Mahoneyhier vorgeschlagen).

0
patryk.beza

Bei der Verwendung von Docker Toolbox unter Windows 10 Home hat keine der Antworten funktioniert, aber 10.0.2.2 did, da VirtualBox verwendet wird, die den Host für VM an dieser Adresse verfügbar macht.

0
Elad