Come posso ottenere informazioni sul contenitore Docker Linux dall'interno del contenitore stesso?


135

Vorrei docker containersinformarmi della loro configurazione, allo stesso modo in cui è possibile ottenere informazioni sulle istanze EC2 attraverso i metadati.

Posso usare (a condizione che dockersia in ascolto sulla porta 4243)

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

per ottenere alcuni dei suoi dati, ma vorrei sapere se esiste un modo migliore almeno di ottenere l'ID completo del contenitore, perché in HOSTNAMErealtà è ridotto a 12 caratteri e la finestra mobile sembra eseguire una "migliore corrispondenza" su di esso.

Inoltre, come posso ottenere l'IP esterno dell'host docker (oltre all'accesso ai metadati EC2, che è specifico di AWS)


2
ATTENZIONE: dovresti leggere questo lvh.io/posts/… prima di tentare uno dei seguenti approcci che tentano di usare /var/run/docker.sock all'interno del contenitore
harschware

1
In caso di interruzione del collegamento di @ harschware, riassumo qui: Dando accesso al contenitore /var/run/docker.sock, è possibile (banale) uscire dal contenimento fornito dalla finestra mobile e ottenere l'accesso al computer host. Ovviamente questo è potenzialmente pericoloso.
Giovanni

1
Qualcuno sa come ottenere le stesse informazioni in un contenitore finestra mobile di Windows se l'argomento --hostname è stato usato con il comando run in modo che semplicemente eseguendo 'hostname' non ti dia più il containerid?
Timothy John Laird,

Risposte:


68

Ho scoperto che l'id contenitore si trova in / proc / self / cgroup

Quindi puoi ottenere l'id con:

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

15
Ho dovuto modificarlo un po ', questo funziona per me in Docker 1.4.1 cat /proc/self/cgroup | grep "docker" | sed s/\\//\\n/g | tail -1
ICas

5
Per la docker 1.6.2 ho dovuto usare:cat /proc/self/cgroup | grep 'docker' | sed 's/^.*\///' | tail -n1
Jay Taylor il

14
Aaaaand Docker 1.12:cat /proc/1/cgroup | grep 'docker/' | tail -1 | sed 's/^.*\///' | cut -c 1-12
smets.kevin,

24
Mi piace basename "$(cat /proc/1/cpuset)"ebasename "$(head /proc/1/cgroup)"
madeddie,

3
In futuro, se lo spazio dei nomi cgroup e cgroup v2 vengono utilizzati nella finestra mobile, questo metodo potrebbe non funzionare più.
Jing Qiu,

69

A meno che non venga sovrascritto, il nome host sembra essere l'ID contenitore breve in Docker 1.12

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

Esternamente

$ 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

4
Sì, questo ha reso facile estrarre le informazioni in nodejs per me. const os = require('os'); console.log(os.hostname());
pulkitsinghal,

2
Per ottenere il nome host che corrisponde all'ID contenitore in Java, utilizzare InetAddress.getLocalHost().getHostName().
Nathan,

2
A volte è più semplice leggere il valore della variabile d'ambiente $HOSTNAME(ad esempio negli script di shell).
Faheel

34

È possibile comunicare con la finestra mobile dall'interno di un contenitore tramite socket unix tramite l'API Docker Remote:

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

In un contenitore, è possibile scoprire un ID finestra mobile abbreviato esaminando $HOSTNAMEenv var. Secondo il documento, c'è una piccola possibilità di collisione, penso che per un piccolo numero di container, non devi preoccuparti. Non so come ottenere direttamente l'ID completo.

È possibile ispezionare il contenitore in modo simile come indicato nella risposta al banyan :

GET /containers/4abbef615af7/json HTTP/1.1

Risposta:

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

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

In alternativa, è possibile trasferire l'ID finestra mobile nel contenitore in un file. Il file si trova sul "volume montato", quindi viene trasferito nel contenitore:

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

L'ID docker (abbreviato) sarà nel file /mydir/host1.txt nel contenitore.


2
Grazie, ma questo è lo stesso approccio che sto usando comunque, e si interromperà se si imposta il nome host con -h quando si esegue la finestra mobile.
Alessandro

@Alessandro Ho aggiunto informazioni sul parametro -cidfile per l'esecuzione della finestra mobile. Potrebbe essere utile passare l'ID finestra mobile al contenitore anziché utilizzare $ HOSTNAME.
Jiri,

Grande! Sì, è qualcosa che potrei usare! Grazie!
Alessandro

Stranamente, in 1.11.2 sembra envnon elencare HOSTNAME, ma echo $HOSTNAMEfunziona.
Jesse Glick,

Questo non funziona affatto e il tuo URL è rotto e ora reindirizza alla documentazione errata. requests.exceptions.MissingSchema: Invalid URL '/containers/1d26a841bf07/json': No schema supplied. Perhaps you meant http:///containers/1d26a841bf07/json?
Cerin,

24

Questo otterrà l'ID contenitore completo da un contenitore:

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


21

ATTENZIONE: è necessario comprendere i rischi per la sicurezza di questo metodo prima di considerarlo. Riepilogo di John sul rischio:

Dando accesso al contenitore /var/run/docker.sock, è [banalmente facile] uscire dal contenimento fornito dalla finestra mobile e ottenere l'accesso al computer host. Ovviamente questo è potenzialmente pericoloso.


All'interno del contenitore, dockerId è il tuo nome host. Quindi, potresti:

  • installa il pacchetto docker-io nel tuo contenitore con la stessa versione dell'host
  • inizia con --volume /var/run/docker.sock:/var/run/docker.sock --privileged
  • infine, corri: docker inspect $(hostname)dentro al contenitore

Evitare questo. Fallo solo se comprendi i rischi e hai una chiara mitigazione dei rischi.


1
Sospetto che questo non funzionerà se --hostnameè stata utilizzata l'opzione di esecuzione della finestra mobile .
hairyhenderson,

Se --hostnameimpostato, è possibile utilizzare una combinazione di questa risposta e il commento di @Jay Taylor nella risposta accettata: docker inspect $(cat /proc/self/cgroup | grep 'docker' | sed 's/^.*\///' | tail -n1)per ottenere tutte le informazioni sul contenitore in esecuzione.
Michael K.,

potresti mettere un riferimento a docker-io?
Brad P.

Presumo che sia npmjs.com/package/docker-io ma era proprio quello che mi ha detto Google e forse non è quello che intendevi.
Brad P.

15

Per semplificare,

  1. ID contenitore è il nome host all'interno della finestra mobile
  2. Le informazioni sul contenitore sono disponibili all'interno di / proc / self / cgroup

Per ottenere il nome host,

hostname

o

uname -n

o

cat /etc/host

L'output può essere reindirizzato a qualsiasi file e riletto dall'applicazione Ad esempio: # hostname > /usr/src//hostname.txt


10

Ho scoperto che nel 17.09 esiste un modo più semplice per farlo all'interno del contenitore docker:

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

O come è già stato detto, una versione più breve con

$ cat /etc/hostname
4de1c09d3f19

O semplicemente:

$ hostname
4de1c09d3f19

6

Docker imposta il nome host sull'ID contenitore per impostazione predefinita, ma gli utenti possono sostituirlo con --hostname. Invece, ispeziona /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

Ecco un pratico one-liner per estrarre l'ID contenitore:

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

2

È possibile utilizzare questa riga di comando per identificare l'ID contenitore corrente (testato con la finestra mobile 1.9).

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

Quindi, una piccola richiesta all'API Docker (puoi condividere /var/run/docker.sock) per recuperare tutte le informazioni.


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

2

Alcune soluzioni pubblicate hanno smesso di funzionare a causa di cambiamenti nel formato di /proc/self/cgroup. Ecco un singolo comando GNU grep che dovrebbe essere un po 'più robusto per formattare le modifiche:

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

Per riferimento, qui ci sono frammenti di / proc / self / cgroup da contenitori docker interni che sono stati testati con questo comando:

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

1
awk -F'[:/]' '(($4 == "docker") && (lastId != $NF)) { lastId = $NF; print $NF; }' /proc/self/cgroup

0

A parte questo, se hai il pid del container e vuoi ottenere l'id docker di quel container, un buon modo è usare nsenter in combinazione con la magia sed sopra:

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


-19

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

Può ottenere l'ip come segue.

$ docker inspect -format="{{ .NetworkSettings.IPAddress }}" 2a5624c52119
172.17.0.24

5
Questo non è ciò che intendo. Devo essere in grado di ottenere queste informazioni dall'interno del contenitore. Fondamentalmente ho bisogno di un modo per capire l'ID di un contenitore che sto correndo dall'interno.
Alessandro
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.