Comment puis-je obtenir des informations sur le conteneur Docker Linux à partir du conteneur lui-même?

135

Je voudrais me rendre docker containerscompte de leur configuration, de la même manière que vous pouvez obtenir des informations sur les instances EC2 via des métadonnées.

Je peux utiliser (à condition d' dockerécouter sur le port 4243)

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

pour obtenir certaines de ses données, mais aimerait savoir s'il existe un meilleur moyen au moins d'obtenir l'ID complet du conteneur, car il HOSTNAMEest en fait raccourci à 12 caractères et le docker semble effectuer une "meilleure correspondance" dessus.

En outre, comment puis-je obtenir l'adresse IP externe de l'hôte docker (autre que d'accéder aux métadonnées EC2, qui sont spécifiques à AWS)

Alessandro
la source
2
ATTENTION: vous devriez lire ce lvh.io/posts/… avant d'essayer l'une des approches ci-dessous qui tentent d'utiliser /var/run/docker.sock à l'intérieur du conteneur
harschware
1
En cas de rupture du lien de @ harschware, je résumerai ici: En donnant au conteneur l'accès à /var/run/docker.sock, il est possible (trivial) de sortir du confinement fourni par docker et d'accéder à la machine hôte. C'est évidemment potentiellement dangereux.
John
1
Est-ce que quelqu'un sait comment obtenir les mêmes informations dans un conteneur de menu fixe Windows si l'argument --hostname a été utilisé avec la commande run de sorte que le simple fait d'exécuter 'hostname' ne vous donne plus le containerid?
Timothy John Laird

Réponses:

68

J'ai découvert que l'identifiant du conteneur se trouve dans / proc / self / cgroup

Vous pouvez donc obtenir l'identifiant avec:

cat /proc/self/cgroup | grep -o  -e "docker-.*.scope" | head -n 1 | sed "s/docker-\(.*\).scope/\\1/"
Thomas A.
la source
15
J'ai dû le peaufiner un peu, cela fonctionne pour moi dans Docker 1.4.1 cat /proc/self/cgroup | grep "docker" | sed s/\\//\\n/g | tail -1
ICas
5
Pour docker 1.6.2 je devais utiliser: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
J'aime un peu basename "$(cat /proc/1/cpuset)"etbasename "$(head /proc/1/cgroup)"
madeddie
3
À l'avenir, si l'espace de noms du groupe de contrôle et le groupe de contrôle v2 sont utilisés dans le menu fixe, cette méthode peut ne plus fonctionner.
Jing Qiu
69

À moins d'être remplacé, le nom d'hôte semble être l'ID de conteneur court dans Docker 1.12

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

Extérieurement

$ 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
la source
4
Oui, cela a facilité l'extraction des informations dans nodejs pour moi. const os = require('os'); console.log(os.hostname());
pulkitsinghal
2
Pour obtenir le nom d'hôte qui correspond à l'ID du conteneur en Java, utilisez InetAddress.getLocalHost().getHostName().
Nathan
2
Parfois, il est plus simple de lire la valeur de la variable d'environnement $HOSTNAME(par exemple dans les scripts shell).
Faheel
34

Vous pouvez communiquer avec docker depuis l'intérieur d'un conteneur en utilisant un socket unix via l'API Docker Remote:

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

Dans un conteneur, vous pouvez trouver un identifiant de docker raccourci en examinant $HOSTNAMEenv var. Selon la doc, il y a un petit risque de collision, je pense que pour un petit nombre de conteneur, vous n'avez pas à vous en soucier. Je ne sais pas comment obtenir directement une identité complète.

Vous pouvez inspecter le conteneur de la même manière que celle décrite dans la réponse de banian :

GET /containers/4abbef615af7/json HTTP/1.1

Réponse:

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

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

Vous pouvez également transférer l'identifiant du docker vers le conteneur dans un fichier. Le fichier est situé sur le "volume monté", il est donc transféré vers le conteneur:

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

L'identifiant du docker (raccourci) sera dans le fichier /mydir/host1.txt dans le conteneur.

Jiri
la source
2
Merci, mais c'est la même approche que j'utilise de toute façon, et cela se cassera si vous définissez le nom d'hôte avec -h lorsque vous exécutez docker.
Alessandro
@Alessandro J'ai ajouté des informations sur le paramètre -cidfile à docker run. Cela peut vous aider à transmettre l'identifiant du docker au conteneur au lieu d'utiliser $ HOSTNAME.
Jiri
Génial! Oui, c'est quelque chose que je pourrais utiliser! Je vous remercie!
Alessandro
Curieusement, dans 1.11.2, il semble envne pas lister HOSTNAME, mais echo $HOSTNAMEfonctionne.
Jesse Glick
Cela ne fonctionne pas du tout, et votre URL est cassée et redirige maintenant vers la mauvaise documentation. requests.exceptions.MissingSchema: Invalid URL '/containers/1d26a841bf07/json': No schema supplied. Perhaps you meant http:///containers/1d26a841bf07/json?
Cerin
24

Cela obtiendra l'ID de conteneur complet à partir d'un conteneur:

cat /proc/self/cgroup | grep "cpu:/" | sed 's/\([0-9]\):cpu:\/docker\///g'
Prisonnier
la source
22

Un commentaire de madeddie me semble le plus élégant:

CID=$(basename $(cat /proc/1/cpuset))
sirex
la source
21

AVERTISSEMENT: vous devez comprendre les risques de sécurité de cette méthode avant de la considérer. Résumé du risque de John :

En donnant au conteneur l'accès à /var/run/docker.sock, il est [trivialement facile] de sortir du confinement fourni par docker et d'accéder à la machine hôte. C'est évidemment potentiellement dangereux.


À l'intérieur du conteneur, le dockerId est votre nom d'hôte. Donc, vous pourriez:

  • installer le package docker-io dans votre conteneur avec la même version que l'hôte
  • commencez avec --volume /var/run/docker.sock:/var/run/docker.sock --privileged
  • enfin, exécutez: docker inspect $(hostname)à l'intérieur du conteneur

Évitez cela. Ne le faites que si vous comprenez les risques et disposez d'une atténuation claire des risques.

Omar Marquez
la source
1
Je soupçonne que cela ne fonctionnera pas si l' --hostnameoption d' exécution du docker a été utilisée.
hairyhenderson
Si --hostnameest défini, vous pouvez utiliser une combinaison de cette réponse et du commentaire de @Jay Taylor dans la réponse acceptée: docker inspect $(cat /proc/self/cgroup | grep 'docker' | sed 's/^.*\///' | tail -n1)pour obtenir toutes les informations sur le conteneur en cours d'exécution.
Michael K.
pourriez-vous mettre une référence à docker-io?
Brad P.
Je suppose que c'est npmjs.com/package/docker-io, mais c'est exactement ce que Google m'a dit et peut-être pas ce que vous vouliez dire.
Brad P.
15

Pour faire simple,

  1. L'ID de conteneur est votre nom d'hôte dans le docker
  2. Les informations sur le conteneur sont disponibles dans / proc / self / cgroup

Pour obtenir le nom d'hôte,

hostname

ou

uname -n

ou

cat /etc/host

La sortie peut être redirigée vers n'importe quel fichier et relue à partir de l'application Par exemple: # hostname > /usr/src//hostname.txt

Tejas jain
la source
10

J'ai trouvé que dans la version 17.09, il existe un moyen le plus simple de le faire dans le conteneur Docker:

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

Ou comme il a déjà été dit, une version plus courte avec

$ cat /etc/hostname
4de1c09d3f19

Ou simplement:

$ hostname
4de1c09d3f19
Adrian Antunez
la source
6

Docker définit le nom d'hôte sur l'ID de conteneur par défaut, mais les utilisateurs peuvent remplacer cela avec --hostname. À la place, inspectez /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

Voici un one-liner pratique pour extraire l'ID du conteneur:

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

Vous pouvez utiliser cette ligne de commande pour identifier l'ID de conteneur actuel (testé avec docker 1.9).

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

Ensuite, une petite requête à l'API Docker (vous pouvez partager /var/run/docker.sock) pour récupérer toutes les informations.

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

Certaines solutions publiées ont cessé de fonctionner en raison de changements dans le format de /proc/self/cgroup. Voici une seule commande GNU grep qui devrait être un peu plus robuste aux changements de format:

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

Pour référence, voici des extraits de / proc / self / cgroup à l'intérieur de conteneurs de docker qui ont été testés avec cette commande:

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
la source
1
awk -F'[:/]' '(($4 == "docker") && (lastId != $NF)) { lastId = $NF; print $NF; }' /proc/self/cgroup
Andrew Wolfe
la source
0

En passant, si vous avez le pid du conteneur et que vous souhaitez obtenir l'identifiant du docker de ce conteneur, un bon moyen est d'utiliser nsenter en combinaison avec la magie sed ci-dessus:

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

anbhat
la source
-19

Utilisez 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",
...

Peut obtenir ip comme suit.

$ docker inspect -format="{{ .NetworkSettings.IPAddress }}" 2a5624c52119
172.17.0.24
banian
la source
5
Ce n'est pas ce que je veux dire. J'ai besoin de pouvoir obtenir ces informations depuis l' intérieur du conteneur. En gros, j'ai besoin d'un moyen de comprendre l'ID d'un conteneur que je gère de l'intérieur.
Alessandro