it-swarm.com.de

So erhalten Sie die IP-Adresse des Docker-Hosts aus einem Docker-Container

Wie der Titel sagt. Ich muss in der Lage sein, die IP-Adresse der Docker-Hosts und der Portmaps vom Host an den Container abzurufen, und zwar innerhalb des Containers. 

262
xiamx
/sbin/ip route|awk '/default/ { print $3 }'

Wie @MichaelNeale festgestellt hat, ist es nicht sinnvoll, diese Methode in Dockerfile zu verwenden (es sei denn, wir benötigen diese IP nur zur Erstellungszeit), da diese IP während der Erstellungszeit fest codiert wird.

250
spinus

Bei Docker für Mac können Sie ab Version 18.03 Host.docker.internal als IP des Hosts verwenden.

Beachten Sie, wie in der Dokumentation : "Dies ist zu Entwicklungszwecken und funktioniert nicht in einer Produktionsumgebung außerhalb von Docker for Mac." Dies liegt daran, dass in Docker für Mac "keine Docker0-Schnittstelle auf dem Host angezeigt wird. Diese Schnittstelle befindet sich tatsächlich innerhalb der virtuellen Maschine."

Dies ist ein Update von docker.for.mac.localhost, verfügbar seit Version 17.06, und docker.for.mac.Host.internal, verfügbar seit Version 17.12, was möglicherweise noch funktioniert.

Zum Beispiel habe ich Umgebungsvariablen auf meinem Host gesetzt:

MONGO_SERVER=Host.docker.internal

In meiner docker-compose.yml-Datei habe ich Folgendes:

version: '3'

services:
  api:
    build: ./api
    volumes:
      - ./api:/usr/src/app:ro
    ports:
      - "8000"
    environment:
      - MONGO_SERVER
    command: /usr/local/bin/gunicorn -c /usr/src/app/gunicorn_config.py -w 1 -b :8000 wsgi
113
allanberry

Update: Bei Docker für Mac können Sie ab Version 18.03 Host.docker.internal als IP des Hosts verwenden. Siehe allanberrys Antwort . Bei früheren Versionen von Docker für Mac kann die folgende Antwort dennoch nützlich sein:

Bei Docker für Mac ist die Brücke docker0 nicht vorhanden, sodass andere Antworten hier möglicherweise nicht funktionieren. Der gesamte ausgehende Datenverkehr wird jedoch über den übergeordneten Host geleitet. Wenn Sie also versuchen, eine Verbindung zu einer IP-Adresse herzustellen, die er als sich selbst erkennt (und der Docker-Container nicht denkt, dass er sich selbst ist), sollten Sie eine Verbindung herstellen können. Zum Beispiel, wenn Sie dies vom übergeordneten Computer ausführen:

ipconfig getifaddr en0

Dies sollte Ihnen die IP Ihres Mac in seinem aktuellen Netzwerk anzeigen und Ihr Docker-Container sollte auch in der Lage sein, eine Verbindung zu dieser Adresse herzustellen. Dies ist natürlich schmerzhaft, wenn sich diese IP-Adresse ändert. Sie können Ihrem Mac jedoch eine benutzerdefinierte Loopback-IP hinzufügen, die der Container nicht für sich selbst hält, indem Sie auf dem übergeordneten Computer Folgendes tun:

Sudo ifconfig lo0 alias 192.168.46.49

Sie können die Verbindung dann innerhalb des Docker-Containers mit Telnet testen. In meinem Fall wollte ich eine Verbindung zu einem Remote-Xdebug-Server herstellen:

telnet 192.168.46.49 9000

Wenn nun Datenverkehr in Ihren Mac kommt, der für 192.168.46.49 adressiert ist (und der gesamte Datenverkehr, der Ihren Container verlässt, über Ihren Mac geleitet wird), geht Ihr Mac davon aus, dass die IP-Adresse selbst ist. Wenn Sie mit der Verwendung dieser IP-Adresse fertig sind, können Sie den Loopback-Alias ​​wie folgt entfernen:

Sudo ifconfig lo0 -alias 192.168.46.49

Seien Sie vorsichtig, wenn der Docker-Container keinen Datenverkehr an den übergeordneten Host sendet, wenn er der Meinung ist, dass das Ziel des Datenverkehrs sich selbst befindet. Überprüfen Sie daher die Loopback-Schnittstelle im Container, wenn Sie Probleme haben:

Sudo ip addr show lo

In meinem Fall zeigte dies inet 127.0.0.1/8 an, was bedeutet, dass ich keine IP-Adressen im 127.*-Bereich verwenden konnte. Deshalb habe ich im obigen Beispiel 192.168.* verwendet. Stellen Sie sicher, dass die von Ihnen verwendete IP-Adresse keinen Konflikt mit Ihrem eigenen Netzwerk verursacht.

78
Code Commander

Für diejenigen, die Docker in AWS ausführen, sind die Instanz-Metadaten für den Host weiterhin im Container verfügbar.

curl http://169.254.169.254/latest/meta-data/local-ipv4

Zum Beispiel:

$ docker run Alpine /bin/sh -c "apk update ; apk add curl ; curl -s http://169.254.169.254/latest/meta-data/local-ipv4 ; echo"
fetch http://dl-cdn.alpinelinux.org/Alpine/v3.3/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/Alpine/v3.3/community/x86_64/APKINDEX.tar.gz
v3.3.1-119-gb247c0a [http://dl-cdn.alpinelinux.org/Alpine/v3.3/main]
v3.3.1-59-g48b0368 [http://dl-cdn.alpinelinux.org/Alpine/v3.3/community]
OK: 5855 distinct packages available
(1/4) Installing openssl (1.0.2g-r0)
(2/4) Installing ca-certificates (20160104-r2)
(3/4) Installing libssh2 (1.6.0-r1)
(4/4) Installing curl (7.47.0-r0)
Executing busybox-1.24.1-r7.trigger
Executing ca-certificates-20160104-r2.trigger
OK: 7 MiB in 15 packages
172.31.27.238

$ ifconfig eth0 | grep -oP 'inet addr:\K\S+'
172.31.27.238
37
Nate Fox

Die einzige Möglichkeit besteht darin, die Host-Informationen als Umgebung zu übergeben, wenn Sie einen Container erstellen

run --env <key>=<value>
20
Magno Torres

Der --add-Host könnte eine sauberere Lösung sein (aber ohne den Port-Teil kann nur der Host mit dieser Lösung behandelt werden). Führen Sie also in Ihrem docker run -Befehl Folgendes aus:

docker run --add-Host dockerhost:`/sbin/ip route|awk '/default/ { print  $3}'` [my container]

(Von https://stackoverflow.com/a/26864854/127400 )

19
ma-ver-ick

Docker für Mac 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 mit dem speziellen DNS-Namen Host.docker.internal herzustellen, der in die vom Host verwendete interne IP-Adresse aufgelöst wird.

Das Gateway ist auch als gateway.docker.internal . https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds erreichbar.

6
BSCheshir

Wenn Sie die docker-Remote-API (z. B. über -Htcp://0.0.0.0:4243) aktiviert haben und den Hostnamen oder die IP-Adresse des Host-Computers kennen, kann dies mit einer Menge bash erfolgen.

In der bashrc des Benutzers meines Containers:

export hostIP=$(ip r | awk '/default/{print $3}')
export containerID=$(awk -F/ '/docker/{print $NF;exit;}' /proc/self/cgroup)
export proxyPort=$(
  curl -s http://$hostIP:4243/containers/$containerID/json |
  node -pe 'JSON.parse(require("fs").readFileSync("/dev/stdin").toString()).NetworkSettings.Ports["DESIRED_PORT/tcp"][0].HostPort'
)

In der zweiten Zeile wird die Container-ID aus Ihrer lokalen /proc/self/cgroup-Datei abgerufen.

Die dritte Zeile rollt zum Host-Computer (vorausgesetzt, Sie verwenden 4243 als Port des Dockers) und analysiert dann den zurückgegebenen JSON-Knoten mit dem DESIRED_PORT.

5
PCas

Wenn Sie eine echte IP-Adresse (keine Brücke IP) auf Windows haben möchten und Docker 18.03 (oder neuer) haben, gehen Sie folgendermaßen vor:

Führen Sie auf dem Host bash auf dem Container aus, auf dem der Image-Name nginx ist (funktioniert mit Alpine Linux distribution):

 docker run -it nginx /bin/ash

Dann in den Container laufen lassen

/ # nslookup Host.docker.internal

Name:      Host.docker.internal
Address 1: 192.168.65.2

192.168.65.2 ist die IP des Hosts - nicht die Bridge-IP wie in spinus akzeptierte Antwort.

Ich verwende hier Host.docker.internal :

Der Host hat eine sich ändernde IP-Adresse (oder keine, wenn Sie keinen Netzwerkzugriff haben). Ab dem 18.03. Empfehlen wir, eine Verbindung mit dem speziellen DNS-Namen Host.docker.internal herzustellen, der in die vom Host verwendete interne IP-Adresse aufgelöst wird. Dies dient zu Entwicklungszwecken und funktioniert nicht in einer Produktionsumgebung außerhalb von Docker für Windows.

5
yami

Hier ist eine weitere Option für diejenigen, die Docker in AWS ausführen. Diese Option vermeidet die Verwendung von apk zum Hinzufügen des curl-Pakets und spart die kostbaren 7 MB Speicherplatz. Verwenden Sie das eingebaute wget (Teil der monolithischen BusyBox-Binärdatei):

wget -q -O - http://169.254.169.254/latest/meta-data/local-ipv4
2
kenn

In Linux können Sie laufen

Host_IP=`hostname -I | awk '{print $1}'`

In macOS ist Ihr Host-Computer nicht der Docker-Host. Docker installiert sein Host-Betriebssystem in VirtualBox.

Host_IP=`docker run busybox ping -c 1 docker.for.mac.localhost | awk 'FNR==2 {print $4}' | sed s'/.$//'`
2
Aref Aslani

Die Standard-Best-Practice für die meisten Apps, die dies automatisch tun möchten, lautet: Sie tun es nicht. Stattdessen muss die Person, die den Container ausführt, einen externen Hostnamen/eine externe IP-Adresse als Konfiguration eingeben, z. als Umgebungsvariable oder Konfigurationsdatei. Wenn Sie dem Benutzer erlauben, dies zu injizieren, erhalten Sie das tragbarste Design.

Warum sollte das so schwierig sein? Da Container die Anwendung standardmäßig von der Host-Umgebung isolieren. Das Netzwerk ist standardmäßig nur für diesen Container mit einem Namespace versehen, und Details des Hosts sind vor dem Prozess geschützt, der im Container ausgeführt wird und möglicherweise nicht vollständig vertrauenswürdig ist.


Abhängig von Ihrer spezifischen Situation gibt es verschiedene Optionen:

Wenn Ihr Container mit Host-Netzwerk ausgeführt wird, können Sie die Routing-Tabelle auf dem Host direkt einsehen, um die Standardroute anzuzeigen, z.

ip r s 0/0 | awk '{print $3}

Ein Beispiel, das dies mit einem Host-Netzwerk in einem Container zeigt, sieht folgendermaßen aus:

docker run --rm --net Host busybox /bin/sh -c "ip r s 0/0 | awk '{print \$3}'"

Bei einigen Versionen von Docker Desktop wurde ein DNS-Eintrag eingefügt:

getent hosts Host.docker.internal | awk '{print $1}'

Wenn Sie in einer Cloud-Umgebung ausgeführt werden, können Sie den Metadatendienst vom Cloud-Anbieter überprüfen, z. die AWS ein:

curl http://169.254.169.254/latest/meta-data/local-ipv4

Wenn Sie Ihre externe/Internet-Adresse möchten, können Sie einen Remote-Service wie folgt abfragen:

curl ifconfig.co

Jedes davon hat Einschränkungen und funktioniert nur in bestimmten Szenarien. Am portabelsten ist es immer noch, Ihren Container mit der als Konfiguration eingegebenen IP-Adresse auszuführen, z. Hier ist eine Option, die den früheren Befehl ip auf dem Host ausführt und als Umgebungsvariable einfügt:

docker run --rm -e Host_IP=$(ip r s 0/0 | awk '{print $3}') busybox printenv Host_IP
1
BMitch

Ich habe Ubuntu 16.03. Für mich

docker run --add-Host dockerhost:`/sbin/ip route|awk '/default/ { print  $3}'` [image]

funktioniert NICHT (falsche ip generiert)

Meine Arbeitslösung war:

docker run --add-Host dockerhost:`docker network inspect --format='{{range .IPAM.Config}}{{.Gateway}}{{end}}' bridge` [image]
1
ilya_direct

Dies ist eine minimalistische Implementierung in Node.js für Benutzer, die den Host auf AWS EC2-Instanzen ausführen. EC2-Metadateninstanz

const cp = require('child_process');
const ec2 = function (callback) {
    const URL = 'http://169.254.169.254/latest/meta-data/local-ipv4';
    // we make it silent and timeout to 1 sec
    const args = [URL, '-s', '--max-time', '1'];
    const opts = {};
    cp.execFile('curl', args, opts, (error, stdout) => {
        if (error) return callback(new Error('ec2 ip error'));
        else return callback(null, stdout);
    })
        .on('error', (error) => callback(new Error('ec2 ip error')));
}//ec2

und verwendet als

ec2(function(err, ip) {
        if(err) console.log(err)
        else console.log(ip);
    })
1
loretoparisi

So mache ich es. In diesem Fall fügt es einen Hosteintrag in/etc/hosts innerhalb des Docker-Image, das Taurus-Host zeigt, der lokalen IP-Adresse des Computers hinzu:

TAURUS_Host=`ipconfig getifaddr en0`
docker run -it --rm -e MY_ENVIRONMENT='local' --add-Host "taurus-Host:${TAURUS_Host}" ...

Anschließend kann das Skript aus dem Docker-Container den Hostnamen taurus-Host verwenden, um zu meinem lokalen Computer zu gelangen, der den Docker-Container hostet.

0
djangofan

Die von mir verwendete Lösung basiert auf einem "Server", der die externe Adresse des Docker-Hosts zurückgibt, wenn er eine http-Anfrage erhält.

Auf dem "Server":

1) Starten Sie jwilder/nginx-proxy

# docker run -d -p <external server port>:80 -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy

2) Starten Sie den ipify-Container

# docker run -e VIRTUAL_Host=<external server name/address> --detach --name ipify osixia/ipify-api:0.1.0

Wenn nun ein Container eine http-Anforderung an den Server sendet, z.

# curl http://<external server name/address>:<external server port>

die IP-Adresse des Docker Host wird von ipify über den HTTP-Header "X-Forwarded-For" zurückgegeben.

Beispiel (ipify-Server hat den Namen "ipify.example.com" und läuft an Port 80, der Docker-Host hat eine IP 10.20.30.40):

# docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro jwilder/nginx-proxy
# docker run -e VIRTUAL_Host=ipify.example.com --detach --name ipify osixia/ipify-api:0.1.0

Innerhalb des Containers können Sie jetzt anrufen:

# curl http://ipify.example.com
10.20.30.40
0
ramazotto

Vielleicht ist der Container, den ich erstellt habe, auch nützlich https://github.com/qoomon/docker-Host

Sie können einfach Containernamen-DNs verwenden, um auf das Host-System zuzugreifen, z. curl http: // dockerhost: 9200 , so dass keine IP-Adresse benötigt wird.

0
qoomon

Wenn Sie einen Windows-Container in einem Service Fabric-Cluster ausführen, ist die IP-Adresse des Hosts über die Umgebungsvariable Fabric_NodeIPOrFQDN verfügbar. Service Fabric-Umgebungsvariablen

0
Aaron Marten

Auf Ubuntu kann der Befehl hostname mit den folgenden Optionen verwendet werden:

  • -i, --ip-address Adressen für den Hostnamen
  • -I, --all-ip-addresses alle Adressen für den Host

Zum Beispiel:

$ hostname -i
172.17.0.2

Um die Variable zuzuweisen, kann der folgende Einzeiler verwendet werden:

IP=$(hostname -i)
0
kenorb