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.