Wie kann ich Docker Linux-Containerinformationen aus dem Container selbst abrufen?

134

Ich möchte mich docker containersauf ihre Konfiguration aufmerksam machen , genauso wie Sie Informationen über EC2-Instanzen über Metadaten erhalten können.

Ich kann verwenden (vorausgesetzt, dockerlauscht am Port 4243)

curl http://172.17.42.1:4243/containers/$HOSTNAME/json

um einige seiner Daten zu erhalten, möchte aber wissen, ob es einen besseren Weg gibt, zumindest die vollständige ID des Containers zu erhalten, da dieser HOSTNAMEtatsächlich auf 12 Zeichen verkürzt ist und Docker eine "beste Übereinstimmung" damit zu erzielen scheint.

Wie kann ich auch die externe IP des Docker-Hosts abrufen (außer auf die für AWS spezifischen EC2-Metadaten zuzugreifen)?

Alessandro
quelle
2
ACHTUNG: Sie sollten diese lvh.io/posts/… lesen, bevor Sie einen der folgenden Ansätze versuchen, /var/run/docker.sock im Container zu verwenden
harschware
1
Für den Fall, dass der Link von @ harschware unterbrochen wird, fasse ich Folgendes zusammen: Indem Sie dem Container Zugriff auf gewähren, /var/run/docker.sockist es möglich (trivial), aus dem vom Docker bereitgestellten Containment auszubrechen und Zugriff auf den Host-Computer zu erhalten. Offensichtlich ist dies möglicherweise gefährlich.
John
1
Weiß jemand, wie man die gleichen Informationen in einem Windows Docker-Container erhält, wenn das Argument --hostname mit dem Befehl run verwendet wurde, sodass Sie beim einfachen Ausführen von 'hostname' nicht mehr die containerid erhalten?
Timothy John Laird

Antworten:

68

Ich habe herausgefunden, dass sich die Container-ID in / proc / self / cgroup befindet

So können Sie die ID erhalten mit:

cat /proc/self/cgroup | grep -o  -e "docker-.*.scope" | head -n 1 | sed "s/docker-\(.*\).scope/\\1/"
Thomas A.
quelle
15
Musste es ein bisschen optimieren, das funktioniert für mich in Docker 1.4.1 cat /proc/self/cgroup | grep "docker" | sed s/\\//\\n/g | tail -1
ICas
5
Für Docker 1.6.2 musste ich verwenden:cat /proc/self/cgroup | grep 'docker' | sed 's/^.*\///' | tail -n1
Jay Taylor
14
Aaaaand Docker 1.12:cat /proc/1/cgroup | grep 'docker/' | tail -1 | sed 's/^.*\///' | cut -c 1-12
smets.kevin
24
Ich mag basename "$(cat /proc/1/cpuset)"undbasename "$(head /proc/1/cgroup)"
madeddie
3
Wenn in Zukunft cgroup-Namespace und cgroup v2 in Docker verwendet werden, funktioniert diese Methode möglicherweise nicht mehr.
Jing Qiu
69

Sofern nicht überschrieben, scheint der Hostname die kurze Container-ID in Docker 1.12 zu sein

root@d2258e6dec11:/project# cat /etc/hostname
d2258e6dec11

Äußerlich

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED                 STATUS                      PORTS               NAMES
d2258e6dec11        300518d26271        "bash"              5 minutes ago       

$ docker -v
Docker version 1.12.0, build 8eab29e, experimental
ardochhigh
quelle
4
Ja, das hat es mir leicht gemacht, die Informationen in nodejs abzurufen. const os = require('os'); console.log(os.hostname());
pulkitsinghal
2
Verwenden Sie, um den Hostnamen zu erhalten, der mit der Container-ID in Java übereinstimmt InetAddress.getLocalHost().getHostName().
Nathan
2
Manchmal ist es einfacher, den Wert der Umgebungsvariablen zu lesen $HOSTNAME(z. B. in Shell-Skripten).
Faheel
34

Sie können mit Docker aus einem Container heraus über einen Unix-Socket über die Docker Remote-API kommunizieren:

https://docs.docker.com/engine/reference/api/docker_remote_api/

In einem Container können Sie eine kurzgeschlossene Docker-ID ermitteln, indem Sie $HOSTNAMEenv var untersuchen. Laut doc besteht eine geringe Kollisionsgefahr. Ich denke, dass Sie sich bei einer kleinen Anzahl von Containern keine Sorgen machen müssen. Ich weiß nicht, wie ich die vollständige ID direkt erhalten soll.

Sie können den Behälter auf ähnliche Weise untersuchen, wie in der Antwort von Banyan beschrieben :

GET /containers/4abbef615af7/json HTTP/1.1

Antwort:

HTTP/1.1 200 OK
Content-Type: application/json

{
         "Id": "4abbef615af7......  ",
         "Created": "2013.....",
         ...
}

Alternativ können Sie die Docker-ID in einer Datei in den Container übertragen. Die Datei befindet sich auf "gemountetem Volume" und wird in den Container übertragen:

docker run -t -i -cidfile /mydir/host1.txt -v /mydir:/mydir ubuntu /bin/bash

Die Docker-ID (gekürzt) befindet sich in der Datei /mydir/host1.txt im Container.

Jiri
quelle
2
Vielen Dank, aber dies ist der gleiche Ansatz, den ich ohnehin verwende. Er wird unterbrochen, wenn Sie den Hostnamen beim Ausführen von Docker mit -h festlegen.
Alessandro
@Alessandro Ich habe Informationen zum Parameter -cidfile zum Docker-Lauf hinzugefügt. Es kann Ihnen helfen, die Docker-ID an den Container zu übergeben, anstatt $ HOSTNAME zu verwenden.
Jiri
Toll! Ja, das könnte ich gebrauchen! Danke dir!
Alessandro
Seltsamerweise scheint enves in 1.11.2 nicht aufzulisten HOSTNAME, aber es echo $HOSTNAMEfunktioniert.
Jesse Glick
Dies funktioniert überhaupt nicht und Ihre URL ist fehlerhaft und leitet jetzt zur falschen Dokumentation weiter. requests.exceptions.MissingSchema: Invalid URL '/containers/1d26a841bf07/json': No schema supplied. Perhaps you meant http:///containers/1d26a841bf07/json?
Cerin
24

Dadurch wird die vollständige Container-ID aus einem Container abgerufen:

cat /proc/self/cgroup | grep "cpu:/" | sed 's/\([0-9]\):cpu:\/docker\///g'
Häftling
quelle
22

Ein Kommentar von madeddie sieht für mich am elegantesten aus:

CID=$(basename $(cat /proc/1/cpuset))
Sirex
quelle
21

WARNUNG: Sie sollten die Sicherheitsrisiken dieser Methode verstehen , bevor Sie sie in Betracht ziehen. Johns Zusammenfassung des Risikos:

Indem Sie dem Container Zugriff gewähren, /var/run/docker.sockist es [trivial einfach], aus dem vom Docker bereitgestellten Containment auszubrechen und Zugriff auf den Host-Computer zu erhalten. Offensichtlich ist dies möglicherweise gefährlich.


Innerhalb des Containers ist die Docker-ID Ihr Hostname. Sie könnten also:

  • Installieren Sie das Docker-Io-Paket in Ihrem Container mit derselben Version wie der Host
  • Beginnen Sie mit --volume /var/run/docker.sock:/var/run/docker.sock --privileged
  • Zum Schluss laufen: docker inspect $(hostname)im Container

Vermeiden Sie dies. Tun Sie dies nur, wenn Sie die Risiken verstehen und die Risiken klar mindern.

Omar Marquez
quelle
1
Ich vermute, dass dies nicht funktioniert, wenn die Docker-Ausführungsoption --hostnameverwendet wurde.
Hairyhenderson
Wenn --hostnamefestgelegt, können Sie eine Kombination aus dieser Antwort und dem Kommentar von @Jay Taylor in der akzeptierten Antwort verwenden: docker inspect $(cat /proc/self/cgroup | grep 'docker' | sed 's/^.*\///' | tail -n1)um alle Informationen über den laufenden Container abzurufen .
Michael K.
Könnten Sie einen Verweis auf Docker-Io setzen?
Brad P.
Ich nehme an, es ist npmjs.com/package/docker-io, aber genau das hat mir Google gesagt und vielleicht auch nicht das, was Sie gemeint haben.
Brad P.
15

Um es einfach zu machen,

  1. Die Container-ID ist Ihr Hostname im Docker
  2. Containerinformationen sind in / proc / self / cgroup verfügbar

Um den Hostnamen zu erhalten,

hostname

oder

uname -n

oder

cat /etc/host

Die Ausgabe kann in eine beliebige Datei umgeleitet und von der Anwendung zurückgelesen werden. ZB: # hostname > /usr/src//hostname.txt

Tejas Jain
quelle
10

Ich habe festgestellt, dass es in 17.09 einen einfachsten Weg gibt, dies innerhalb des Docker-Containers zu tun:

$ cat /proc/self/cgroup | head -n 1 | cut -d '/' -f3
4de1c09d3f1979147cd5672571b69abec03d606afcc7bdc54ddb2b69dec3861c

Oder wie schon gesagt wurde, eine kürzere Version mit

$ cat /etc/hostname
4de1c09d3f19

Oder einfach:

$ hostname
4de1c09d3f19
Adrian Antunez
quelle
6

Docker setzt den Hostnamen standardmäßig auf die Container-ID, aber Benutzer können dies mit überschreiben --hostname. Überprüfen Sie stattdessen /proc:

$ more /proc/self/cgroup
14:name=systemd:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
13:pids:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
12:hugetlb:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
11:net_prio:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
10:perf_event:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
9:net_cls:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
8:freezer:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
7:devices:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
6:memory:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
5:blkio:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
4:cpuacct:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
3:cpu:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
2:cpuset:/docker/7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
1:name=openrc:/docker

Hier ist ein praktischer Einzeiler zum Extrahieren der Container-ID:

$ grep "memory:/" < /proc/self/cgroup | sed 's|.*/||'
7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
Wilfred Hughes
quelle
2

Mit dieser Befehlszeile können Sie die aktuelle Container-ID identifizieren (getestet mit Docker 1.9).

awk -F"-|/." '/1:/ {print $3}' /proc/self/cgroup

Anschließend eine kleine Anfrage an die Docker-API (Sie können /var/run/docker.sock freigeben), um alle Informationen abzurufen.

Baptiste Donaux
quelle
1
awk -F "- | /." '/ 1: / {print $ 3}' / proc / self / cgroup
usil
2

Einige veröffentlichte Lösungen funktionieren aufgrund von Änderungen im Format von nicht mehr /proc/self/cgroup. Hier ist ein einzelner GNU-grep-Befehl, der gegenüber Formatänderungen etwas robuster sein sollte:

grep -o -P -m1 'docker.*\K[0-9a-f]{64,}' /proc/self/cgroup

Als Referenz finden Sie hier Ausschnitte aus / proc / self / cgroup aus Docker-Containern, die mit diesem Befehl getestet wurden:

Linux 4.4:

11:pids:/system.slice/docker-cde7c2bab394630a42d73dc610b9c57415dced996106665d427f6d0566594411.scope
...
1:name=systemd:/system.slice/docker-cde7c2bab394630a42d73dc610b9c57415dced996106665d427f6d0566594411.scope

Linux 4.8 - 4.13:

11:hugetlb:/docker/afe96d48db6d2c19585572f986fc310c92421a3dac28310e847566fb82166013
...
1:name=systemd:/docker/afe96d48db6d2c19585572f986fc310c92421a3dac28310e847566fb82166013
Kanaka
quelle
1
awk -F'[:/]' '(($4 == "docker") && (lastId != $NF)) { lastId = $NF; print $NF; }' /proc/self/cgroup
Andrew Wolfe
quelle
0

Abgesehen davon, wenn Sie die PID des Containers haben und die Docker-ID dieses Containers erhalten möchten, ist es eine gute Möglichkeit, nsenter in Kombination mit der oben genannten sed magic zu verwenden:

nsenter -n -m -t pid -- cat /proc/1/cgroup | grep -o -e "docker-.*.scope" | head -n 1 | sed "s/docker-\(.*\).scope/\\1/"

anbhat
quelle
-19

Verwenden Sie docker inspect.

$ docker ps # get conteiner id
$ docker inspect 4abbef615af7
[{
    "ID": "4abbef615af780f24991ccdca946cd50d2422e75f53fb15f578e14167c365989",
    "Created": "2014-01-08T07:13:32.765612597Z",
    "Path": "/bin/bash",
    "Args": [
        "-c",
        "/start web"
    ],
    "Config": {
        "Hostname": "4abbef615af7",
...

Kann IP wie folgt bekommen.

$ docker inspect -format="{{ .NetworkSettings.IPAddress }}" 2a5624c52119
172.17.0.24
Banyan
quelle
5
Das meine ich nicht. Ich muss in der Lage , diese Informationen zu erhalten , von innen des Behälters. Muss ich im Grunde einen Weg finden, um die ID eines Containers zu verstehen, den ich von innen laufen lasse?
Alessandro