Ich habe also ein Nginx, das in einem Docker-Container ausgeführt wird. Ich habe ein MySQL, das auf localhost ausgeführt wird. Ich möchte über mein Nginx eine Verbindung zum MySQL herstellen. MySql wird auf localhost ausgeführt und setzt einen Port nicht der Außenwelt aus. Daher ist es an localhost gebunden, nicht an die IP-Adresse des Computers.
Gibt es eine Möglichkeit, über diesen Docker-Container eine Verbindung zu dieser MySQL oder einem anderen Programm auf localhost herzustellen?
Diese Frage unterscheidet sich von "So erhalten Sie die IP-Adresse des Docker-Hosts aus einem Docker-Container heraus", da die IP-Adresse des Docker-Hosts die öffentliche oder die private IP im Netzwerk sein kann, die möglicherweise oder möglicherweise nicht innerhalb des Docker-Containers erreichbar sein (ich meine öffentliche IP, wenn sie bei AWS gehostet wird oder so). Selbst wenn Sie die IP-Adresse des Docker-Hosts haben, bedeutet dies nicht, dass Sie innerhalb des Containers eine Verbindung zum Docker-Host herstellen können, da die IP-Adresse Ihres Docker-Netzwerks möglicherweise Overlay, Host, Bridge, Macvlan usw. ist, was die Erreichbarkeit von einschränkt diese IP-Adresse.
network: host
Sie nicht von einem Container zum Host zurückkehren. Nur Host für Container. Dies ist die Hauptideologie hinter Containern. Sie sind sowohl aus Stabilitäts- als auch aus Sicherheitsgründen isoliert.Antworten:
Bearbeiten: Wenn Sie Docker-for-Mac oder Docker-for-Windows 18.03+ verwenden, stellen Sie einfach über den Host eine Verbindung zu Ihrem MySQL-Dienst her
host.docker.internal
(anstelle der127.0.0.1
in Ihrer Verbindungszeichenfolge).Ab Docker 18.09.3 funktioniert dies unter Docker-for-Linux nicht mehr. Ein Fix wurde am 8. März 2019 eingereicht und wird hoffentlich in die Codebasis integriert. Bis dahin besteht eine Problemumgehung darin, einen Container zu verwenden, wie in der Antwort von qoomon beschrieben .
2020-01: Einige Fortschritte wurden erzielt . Wenn alles gut geht, sollte dies in Docker 20.04 landen
TLDR
Verwenden Sie
--network="host"
in Ihremdocker run
Befehl, dann zeigt127.0.0.1
in Ihrem Docker-Container auf Ihren Docker-Host.Hinweis: Dieser Modus funktioniert laut Dokumentation nur unter Docker für Linux .
Hinweis zu den Docker-Container-Netzwerkmodi
Docker bietet verschiedene Netzwerkmodi beim Ausführen von Containern. Abhängig vom gewählten Modus stellen Sie eine unterschiedliche Verbindung zu Ihrer MySQL-Datenbank her, die auf dem Docker-Host ausgeführt wird.
Docker ausführen --network = "Brücke" (Standard)
Docker erstellt eine
docker0
standardmäßig benannte Brücke . Sowohl der Docker-Host als auch die Docker-Container haben eine IP-Adresse auf dieser Bridge.Geben
sudo ip addr show docker0
Sie auf dem Docker-Host Folgendes ein: Die Ausgabe sieht folgendermaßen aus:Hier hat mein Docker-Host also die IP-Adresse
172.17.42.1
auf demdocker0
Netzwerkschnittstelle.Starten Sie nun einen neuen Container und rufen Sie eine Shell auf:
docker run --rm -it ubuntu:trusty bash
und innerhalb des Containertyps,ip addr show eth0
um herauszufinden, wie die Hauptnetzwerkschnittstelle eingerichtet ist:Hier hat mein Container die IP-Adresse
172.17.1.192
. Schauen Sie sich nun die Routing-Tabelle an:Daher wird die IP-Adresse des Docker-Hosts
172.17.42.1
als Standardroute festgelegt und kann von Ihrem Container aus aufgerufen werden.Docker ausführen --network = "Host"
Alternativ können Sie einen Docker-Container mit den Netzwerkeinstellungen
host
ausführen . Ein solcher Container teilt den Netzwerkstapel mit dem Docker-Host und aus der Sicht des Containerslocalhost
(oder127.0.0.1
verweist ) auf den Docker-Host.Beachten Sie, dass jeder in Ihrem Docker-Container geöffnete Port auf dem Docker-Host geöffnet wird. Und das ohne das
-p
oder-P
docker run
Option .IP-Konfiguration auf meinem Docker-Host:
und aus einem Docker-Container im Host- Modus:
Wie Sie sehen können, haben sowohl der Docker-Host als auch der Docker-Container genau dieselbe Netzwerkschnittstelle und als solche dieselbe IP-Adresse.
Herstellen einer Verbindung zu MySQL über Container
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
172.17.42.1
IP-Adresse wartet.Stellen Sie dazu sicher, dass Sie entweder
bind-address = 172.17.42.1
oderbind-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:
Verwenden Sie dann in Ihrer Anwendung die
DOCKER_HOST_IP
Umgebungsvariable, um die Verbindung zu MySQL herzustellen.Hinweis: Wenn Sie
bind-address = 0.0.0.0
Ihren MySQL-Server verwenden, wartet er auf Verbindungen auf 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
Ihren MySQL-Server verwenden, werden keine Verbindungen zu hergestellt127.0.0.1
. Prozesse, die auf dem Docker-Host ausgeführt werden und eine Verbindung zu MySQL herstellen möchten, müssen die172.17.42.1
IP-Adresse 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
Ihre MySQL-Konfiguration beibehalten. Sie müssen lediglich eine Verbindung127.0.0.1
von Ihren Containern aus herstellen:Hinweis: Verwenden Sie
mysql -h 127.0.0.1
und nichtmysql -h localhost
; Andernfalls würde der MySQL-Client versuchen, eine Verbindung über einen Unix-Socket herzustellen.quelle
telnet 172.17.0.1 3306
-v /var/run/mysqld/mysqld.sock:/tmp/mysql.sock
.Für MacOS und Windows
Docker v 18.03 und höher (seit dem 21. März 2018)
Verwenden Sie Ihre interne IP-Adresse oder stellen Sie eine Verbindung zum speziellen DNS-Namen her
host.docker.internal
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
docker.for.mac.host.internal
stattdessen verwenden.Docker für Mac v 17.06 bis v 17.11
Wie oben, aber
docker.for.mac.localhost
stattdessen verwenden.Docker für Mac 17.05 und niedriger
Um vom Docker-Container aus auf den Host-Computer zuzugreifen, müssen Sie einen IP-Alias an Ihre Netzwerkschnittstelle anhängen. Sie können jede 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 genannte IP abhört oder
0.0.0.0
. Wenn localhost abgehört127.0.0.1
wird, wird die Verbindung nicht akzeptiert.Zeigen Sie dann einfach mit Ihrem Docker-Container auf diese IP und Sie können auf den Host-Computer zugreifen!
Zum Testen können Sie so etwas wie
curl -X GET 123.123.123.123:3000
im Container ausführen .Der Alias wird bei jedem Neustart zurückgesetzt. Erstellen Sie daher bei Bedarf ein Startskript.
Lösung und weitere Dokumentation hier: https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds
quelle
mysql -uroot -hdocker.for.mac.localhost
docker run -e HOSTNAME= docker.for.mac.host.internal
, wird der Container erstellt, aber nichts passiert. Ich muss dann crtl + C drücken. Mit--net=host -e HOSTNAME=localhost
zumindest in den Behälter läuft und beschwert sich, dass er nicht den Service , den ich Notwendigkeit finden (MySQL db).Ich mache einen Hack ähnlich den obigen Posts, um die lokale IP einem Aliasnamen (DNS) im Container zuzuordnen. Das Hauptproblem besteht darin, mit einem einfachen Skript, das sowohl unter Linux als auch unter OSX funktioniert, dynamisch die Host-IP-Adresse zu erhalten . Ich habe dieses Skript erstellt, das in beiden Umgebungen funktioniert (auch in der Linux-Distribution mit
"$LANG" != "en_*"
konfigurierter Konfiguration):Wenn Sie Docker Compose verwenden, lautet die vollständige Konfiguration wie folgt:
Startskript (docker-run.sh) :
docker-compose.yml :
Ändern Sie dann
http://localhost
aufhttp://dockerhost
in Ihrem Code.Eine ausführlichere Anleitung zum Anpassen des
DOCKERHOST
Skripts finden Sie in diesem Beitrag mit einer Erläuterung der Funktionsweise.quelle
DOCKERHOST
Wert hier anstelle von "localhost" oder 0.0.0.0 in dem Dienst verwenden, zu dem Ihr Docker-Container eine lokale Verbindung herstellen muss.export DOCKERHOST=$(docker network inspect --format='{{range .IPAM.Config}}{{.Gateway}}{{end}}' <NETWORK-NAME> | awk -F "/" 'NR==1{print $1}')
Dabei könnte <NETWORK-NAME> eine Bridge oder der Name des Netzwerks sein, wie von Docker-Compose definiert (normalerweise Pfadname - Netzwerkname ).dockerhost
als Host für die Datenbankverbindung (normalerweise ersetzen Sie ihnlocalhost
in der Konfigurationsdatei).Dies funktionierte für mich auf einem NGINX / PHP-FPM-Stack, ohne Code oder Netzwerk zu berühren, mit dem die App nur eine Verbindung herstellen möchte
localhost
Montieren
mysqld.sock
vom Host in den Container.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 Docker erwartet wird:
docker run -v /hostpath/to/mysqld.sock:/containerpath/to/mysqld.sock
Mögliche Standorte von mysqld.sock:
quelle
Bis
host.docker.internal
es für jede Plattform funktioniert, können Sie meinen Container ohne manuelles Setup als NAT-Gateway verwenden:https://github.com/qoomon/docker-host
quelle
Lösung für Linux (Kernel> = 3.6).
Ok, Ihr localhost-Server verfügt über die Standard-Docker-Schnittstelle docker0 mit der IP-Adresse 172.17.0.1 . Ihr Container wurde mit den Standardeinstellungen für das Netzwerk gestartet --net = "bridge" .
$ 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 Kerneldokumentation :
quelle
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 verwenden
docker.for.win.localhost
, um die interne IP-Adresse zu ermitteln. (Warnung einige Quellen erwähnt,windows
aber es sollte seinwin
)Übersicht
Ich musste etwas Ähnliches tun, nämlich eine Verbindung von meinem Docker-Container zu meinem lokalen Host herstellen, auf dem das
Azure Storage Emulator
und ausgeführt wurdeCosmosDB Emulator
.Das
Azure Storage Emulator
hört standardmäßig auf 127.0.0.1 zu , während Sie die IP- Adresse auch ändern können, suchte ich nach einer Lösung, die mit Standardeinstellungen funktioniert.Dies funktioniert auch für die Verbindung von meinem Docker-Container zu
SQL Server
undIIS
, die beide lokal auf meinem Host mit Standard-Porteinstellungen ausgeführt werden.quelle
Sehr einfach und schnell, überprüfen Sie Ihre Host-IP mit ifconfig (Linux) oder ipconfig (Windows) und erstellen Sie dann eine
docker-compose.yml
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
quelle
Bei Verwendung von Docker Toolbox unter Windows 10 Home hat keine der Antworten für mich funktioniert, 10.0.2.2 jedoch, da VirtualBox verwendet wird, das den Host für die VM unter dieser Adresse verfügbar macht.
quelle
Ethernet adapter vEthernet (DockerNAT)
Wenn Sie unter Windows den Bridge-Netzwerktreiber verwenden, möchten Sie MySQL speziell an die IP-Adresse der Hyper-V-Netzwerkschnittstelle binden.
Dies erfolgt über die Konfigurationsdatei im normalerweise ausgeblendeten Ordner C: \ ProgramData \ MySQL.
Die Bindung 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.
quelle
Bearbeiten: Am Ende habe ich das Konzept auf GitHub prototypisiert. Überprüfen Sie heraus: https://github.com/sivabudh/system-in-a-box
Erstens richtet sich meine Antwort an zwei Personengruppen: diejenigen, die einen Mac verwenden, und diejenigen, die Linux verwenden.
Der Host- Netzwerkmodus 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 unter Ihnen, die Linux verwenden (meine direkte Erfahrung war mit Ubuntu 14.04 LTS und ich aktualisiere bald auf 16.04 LTS in der Produktion), ja , Sie können den Dienst, der in einem Docker-Container ausgeführt wird, mit verbinden
localhost
Diensten die auf dem ausgeführt werden Docker-Host (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 folgendermaßen aus:
docker run --network="host" -id <Docker image ID>
Wenn Sie eine
ifconfig
(Sie müssenapt-get install net-tools
Ihren Container benötigen,ifconfig
um aufrufbar zu sein) in Ihrem Container ausführen, werden Sie feststellen, dass die Netzwerkschnittstellen mit denen auf dem Docker-Host (z. B. Ihrem Laptop) identisch sind.Es ist wichtig zu beachten, dass ich ein Mac-Benutzer bin, aber Ubuntu unter Parallels ausführe, sodass die Verwendung eines Mac kein Nachteil ist. ;-);
Und so verbinden Sie den NGINX-Container mit MySQL, das auf einem ausgeführt wird
localhost
.quelle
--network="host"
, wie stellt man zum Beispiel eine Verbindung zum Host-MySQL her?localhost
. Überprüfen Sie meinen GitHub-Quellcode: github.com/sivabudh/system-in-a-box/blob/master/dj_host_docker/… . Suchen Sie nach'HOST'
, Sie sehen 127.0.0.1, um eine Verbindung zu Postgresql herzustellen.Einfachste Lösung für Mac OSX
Verwenden Sie einfach die IP-Adresse Ihres Mac. Führen Sie dies auf dem Mac aus, um die IP-Adresse abzurufen und aus dem Container heraus zu verwenden:
Solange der Server, der lokal auf Ihrem Mac oder in einem anderen Docker-Container ausgeführt wird, 0.0.0.0 abhört, kann der Docker-Container diese Adresse erreichen.
Wenn Sie nur auf einen anderen Docker-Container zugreifen möchten, der 0.0.0.0 abhört, können Sie 172.17.0.1 verwenden
quelle
docker.for.mac.host.internal
jetzt den Hostnamen verfügbar.Dies ist keine Antwort auf die eigentliche Frage. So habe ich ein ähnliches Problem gelöst. Die Lösung kommt vollständig von: Definieren Sie Docker Container Networking, 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?
Erfahren Sie, wie Ihr Netzwerk aussieht
docker network ls
Erstellen Sie ein neues Netzwerk
docker network create -d my-net
Starten Sie 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' habenStarten Sie 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' habenssh in deinen zweiten container
docker exec -it second_container sh
oderdocker exec -it second_container bash
.Innerhalb des zweiten Containers können Sie den ersten Container an pingen
ping first_container
. Auch Ihre Code-Aufrufe wiehttp://localhost:5000
können durch ersetzt werdenhttp://first_container:5000
quelle
Für Windows,
Ich habe die Datenbank-URL in der Frühjahrskonfiguration geändert:
spring.datasource.url=jdbc:postgresql://host.docker.internal:5432/apidb
Erstellen Sie dann das Image und führen Sie es aus. Es hat bei mir funktioniert.
quelle
Ich bin mit der Antwort von Thomasleveil nicht einverstanden.
Wenn Sie MySQL an 172.17.42.1 binden, wird verhindert, dass andere Programme die Datenbank auf dem Host verwenden, um darauf zuzugreifen. Dies funktioniert nur, wenn alle Ihre Datenbankbenutzer dockerisiert sind.
Wenn Sie MySQL an 0.0.0.0 binden, wird die Datenbank für die Außenwelt geöffnet. Dies ist nicht nur eine sehr schlechte Sache, sondern widerspricht auch dem, was der ursprüngliche Frageautor tun möchte. Er sagt ausdrücklich: "MySql läuft auf localhost und setzt einen Port nicht der Außenwelt aus, daher ist es an localhost gebunden."
Um den Kommentar von ivant zu beantworten
Das ist nicht möglich. In der mysql / mariadb-Dokumentation heißt es ausdrücklich, 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 KEINE Möglichkeit gefunden, die Datenbank (nur localhost) auf dem Host von einem Docker-Container aus zu erreichen. Das scheint definitiv ein sehr sehr verbreitetes Muster zu sein, aber ich weiß nicht, wie ich es machen soll.
quelle
172.17.42.1
Adresse eine Verbindung zum MySQL-Server herstellen . Aber sonst ist Ihre Notiz richtig. Außerdem habe ich meine Antwort mit demhost
Netzwerkmodus bearbeitet , der es ermöglicht, den MySQL-Server an sich zu binden,127.0.0.1
während Container eine Verbindung zu ihm herstellen können0.0.0.0
und dann eine Firewall einzurichten , damit auf die Datenbank nicht über das Internet zugegriffen werden kann.Hier ist meine Lösung: Es funktioniert für meinen Fall
#bind-address = 127.0.0.1
Stellen Sie den lokalen MySQL-Server per Kommentar in /etc/mysql/mysql.conf.d auf öffentlichen Zugriff einStarten Sie den MySQL-Server neu
sudo /etc/init.d/mysql restart
Führen Sie den folgenden Befehl aus, um den Benutzerstammzugriff auf einen beliebigen Host zu öffnen
mysql -uroot -proot GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'root' WITH GRANT OPTION; FLUSH PRIVILEGES;
Erstellen Sie ein sh-Skript: run_docker.sh
mit Docker-Composer ausführen
quelle
Es kommen mehrere Lösungen in den Sinn:
Der Grund, warum dies nicht sofort funktioniert, ist, dass Container standardmäßig mit ihrem eigenen Netzwerk-Namespace ausgeführt werden. Dies 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 zum Container selbst hergestellt und nicht zu Diensten, die außerhalb des Dockers 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. Dadurch wird Ihr Anwendungsstapel portabel, da andere versuchen, Ihren Container in ihrer eigenen Umgebung auszuführen. Sie können den Port weiterhin auf Ihrem Host veröffentlichen, wo andere Dienste, die nicht migriert wurden, ihn weiterhin erreichen können. Sie können den Port sogar auf der localhost-Schnittstelle Ihres Docker-Hosts veröffentlichen, um zu vermeiden, dass er extern mit einer Syntax wie der folgenden
-p 127.0.0.1:3306:3306
für den veröffentlichten Port zugänglich ist .Option 2 : Es gibt verschiedene Möglichkeiten, die Host-IP-Adresse innerhalb des Containers zu erkennen, aber es gibt jeweils eine begrenzte Anzahl von Szenarien, in denen sie funktionieren (z. B. Docker für Mac erforderlich). Die portabelste Option besteht darin, Ihre Host-IP mit einer Umgebungsvariablen oder einer Konfigurationsdatei in den Container einzufügen, z.
Dies setzt voraus, dass Ihr Dienst diese externe Schnittstelle überwacht, was ein Sicherheitsrisiko darstellen kann. Weitere Methoden zum Abrufen der Host-IP-Adresse aus dem Container finden Sie in diesem Beitrag .
Option 3 : Ohne Netzwerkisolation ausgeführt, dh mit ausgeführt
--net host
, bedeutet, dass Ihre Anwendung im Namespace des Hostnetzwerks ausgeführt wird. Dies ist weniger isoliert für den Container und bedeutet, dass Sie nicht über ein freigegebenes Docker-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 nur127.0.0.1
auf dem Host lauschen , kann dies die einfachste Option sein.Option 4 : Verschiedene Dienste ermöglichen auch den Zugriff über einen dateisystembasierten Socket. Dieser Socket kann als bindmontiertes Volume in den Container eingebunden werden, sodass Sie auf den Hostdienst zugreifen können, ohne über das Netzwerk zu gehen. Für den Zugriff auf die Docker-Engine werden häufig Beispiele für das Mounten
/var/run/docker.sock
in den Container angezeigt (wodurch dieser Container-Root-Zugriff auf den Host gewährt wird). Mit MySQL können Sie so etwas ausprobieren-v /var/run/mysqld/mysqld.sock:/var/run/mysqld/mysql.sock
und dann eine Verbindung herstellen, zulocalhost
der MySQL über den Socket konvertiert.quelle
Sie können die Host-IP mit Alpine Image erhalten
Dies wäre konsistenter, da Sie den Befehl immer mit alpine ausführen.
Ähnlich wie bei Marianos Antwort können Sie denselben Befehl verwenden, um eine Umgebungsvariable festzulegen
quelle
Unter Linux, wo Sie die Schnittstelle nicht ändern können, an die der localhost-Dienst gebunden ist
Es gibt zwei Probleme, die wir lösen müssen
Das erste Problem kann mit dem Docker-Host-Image von qoomon gelöst werden , wie aus anderen Antworten hervorgeht.
Sie müssen diesen Container demselben Brückennetzwerk wie Ihr anderer Container hinzufügen, damit Sie darauf zugreifen können. Öffnen Sie ein Terminal in Ihrem Container und stellen Sie sicher, dass Sie pingen können
dockerhost
.Nun ist das Problem schwieriger, den Dienst für Docker zugänglich zu machen.
Wir können Telnet verwenden, um zu überprüfen, ob wir auf einen Port auf dem Host zugreifen können (möglicherweise müssen Sie diesen installieren).
Das Problem ist, dass unser Container nur auf Dienste zugreifen kann, die an alle Schnittstellen gebunden sind, z. B. SSH:
Auf Dienste, die nur an localhost gebunden sind, kann jedoch nicht zugegriffen werden:
Die richtige Lösung wäre hier, den Dienst an das Docker-Bridge-Netzwerk zu binden. Bei dieser Antwort wird jedoch davon ausgegangen, dass Sie dies nicht ändern können. Also werden wir stattdessen verwenden
iptables
.Zuerst müssen wir den Namen des Brückennetzwerks finden, mit dem Docker arbeitet
ifconfig
. Wenn Sie eine unbenannte Brücke verwenden, ist dies nur der Falldocker0
. Wenn Sie jedoch ein benanntes Netzwerk verwenden, wirdbr-
stattdessen eine Bridge verwendet, die mit dem Docker beginnt . Meins istbr-5cd80298d6f4
.Sobald wir den Namen dieser Brücke haben, müssen wir das Routing von dieser Brücke zu localhost zulassen. Dies ist aus Sicherheitsgründen standardmäßig deaktiviert:
Nun, um unsere
iptables
Regel aufzustellen . Da unser Container nur auf Ports im Docker-Bridge-Netzwerk zugreifen kann, geben wir vor, dass unser Service tatsächlich an einen Port in diesem Netzwerk gebunden ist.Dazu leiten wir alle Anfragen an
<docker_bridge>:port
weiterlocalhost:port
Zum Beispiel für meinen Dienst an Port 1025
Sie sollten jetzt über den Container auf Ihren Dienst zugreifen können:
quelle
sysctl -w net.ipv4.conf.docker0.route_localnet=1
undiptables -t nat -A PREROUTING -p tcp -i docker0 --dport 1025 -j DNAT --to-destination 127.0.0.1:1025
Sie müssen das Gateway kennen ! Meine Lösung mit dem lokalen Server bestand darin, ihn unter
0.0.0.0:8000
verfügbar zu machen, dann Docker mit Subnetz auszuführen und Container wie folgt auszuführen :Jetzt können Sie über auf Ihren Loopback zugreifen
http://172.35.0.1:8000
quelle
Versuche dies:
Bekommen
192.168.1.202
, verwendetifconfig
Das hat bei mir funktioniert. Ich hoffe das hilft!
quelle
Die CGroups und Namespaces spielen eine wichtige Rolle im Container-Ökosystem.
Der Namespace bietet eine Isolationsschicht. 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, während der Namespace steuert, was ein Prozess sehen und auf die jeweilige Ressource zugreifen kann.
Hier ist das grundlegende Verständnis des Lösungsansatzes, dem Sie folgen könnten:
Verwenden Sie den Netzwerk-Namespace
Wenn ein Container aus dem Image heraus erscheint, wird eine Netzwerkschnittstelle definiert und erstellt. Dies gibt dem Container eine eindeutige IP-Adresse und Schnittstelle.
Durch Ändern des Namespace in Host bleiben die Cotainer-Netzwerke nicht von der Schnittstelle isoliert. Der Prozess hat Zugriff auf die Netzwerkschnittstelle des Host-Computers.
Wenn der Prozess Ports überwacht, werden diese auf der Host-Schnittstelle abgehört und dem Container zugeordnet.
PID-Namespace verwenden Durch Ändern des PID-Namespace kann ein Container mit anderen Prozessen interagieren, die über seinen normalen Bereich hinausgehen.
Dieser Container wird in einem eigenen Namespace ausgeführt.
Durch Ändern des Namespace in den Host kann der Container auch alle anderen auf dem System ausgeführten Prozesse anzeigen.
Namespace teilen
Dies ist eine schlechte Vorgehensweise in der Produktion, da Sie aus dem Containersicherheitsmodell ausbrechen, das sich möglicherweise für Sicherheitslücken und einen einfachen Zugriff auf Lauscher öffnet. Dies dient nur zum Debuggen von Tools und zum Verstehen der Lücken in der Containersicherheit.
Der erste Container ist der Nginx-Server. Dadurch wird ein neuer Netzwerk- und Prozessnamespace erstellt. Dieser Container bindet sich an Port 80 der neu erstellten Netzwerkschnittstelle.
Ein anderer Container kann diesen Namespace jetzt wiederverwenden.
Dieser Container kann auch die Schnittstelle zu den Prozessen in einem gemeinsam genutzten Container sehen.
Auf diese Weise können Sie Containern mehr Berechtigungen erteilen, ohne die Anwendung zu ändern oder neu zu starten. Auf ähnliche Weise können Sie auf dem Host eine Verbindung zu MySQL herstellen, Ihre Anwendung ausführen und debuggen. Es wird jedoch nicht empfohlen, diesen Weg zu gehen. Ich hoffe es hilft.
quelle
Für Windows-Computer: -
Führen Sie den folgenden Befehl aus, um den Docker-Port während der Erstellungszeit zufällig verfügbar zu machen
In der obigen Containerliste sehen Sie den als 32768 zugewiesenen Port. Versuchen Sie, darauf zuzugreifen
Sie können die Mediawiki-Seite sehen
quelle
Bis Fix nicht in
master
Branch zusammengeführt wird, wird die Host-IP nur aus dem Container heraus ausgeführt:(wie von @Mahoney hier vorgeschlagen ).
quelle
Ich habe es gelöst, indem ich in MySQL einen Benutzer für die IP des Containers erstellt habe:
Dann auf Container:
jdbc:mysql://<b>172.17.0.1</b>:3306/database_name
quelle
Ich übergebe die Host-IP als Umgebungsvariable an den Container. Der Container greift dann über diese Variable auf den Host zu.
quelle