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?
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.
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 .
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 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
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 -P
docker 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.
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.
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.
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
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
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.
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
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.
$ sysctl -w net.ipv4.conf.docker0.route_localnet=1
$ 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
CREATE USER 'user'@'%' IDENTIFIED BY 'password';
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).
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.
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.
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.
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
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
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
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.
Mehrere Lösungen kommen in den Sinn:
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.
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.
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.
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
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
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
Ü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
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.