Docker, come ottenere informazioni sul contenitore dall’interno del contenitore?

Vorrei rendere i docker containers consapevoli della loro configurazione, allo stesso modo in cui è ansible ottenere informazioni sulle istanze EC2 tramite metadati.

Posso usare (la docker è 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 c’è un modo migliore almeno per ottenere l’ID completo del contenitore, perché HOSTNAME è effettivamente abbreviato a 12 caratteri e la finestra mobile sembra eseguire una “corrispondenza migliore” su di esso.

Inoltre, come posso ottenere l’IP esterno dell’host di docker (diverso dall’accesso ai metadati EC2, che è specifico per AWS)

Ho scoperto che l’id del contenitore può essere trovato 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/" 

È ansible comunicare con la finestra mobile dall’interno di un contenitore utilizzando il socket unix tramite l’API Docker Remote:

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

In un contenitore, è ansible trovare un id docker con un breve elenco esaminando $HOSTNAME env var. Secondo doc, c’è una piccola possibilità di collisione, penso che per un piccolo numero di container, non devi preoccuparti di questo. Non so come ottenere l’ID completo direttamente.

È ansible ispezionare il contenitore in modo simile a quanto 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, è ansible trasferire l’id docker nel contenitore in un file. Il file si trova su “volume montato”, quindi viene trasferito al 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.

Salvo sovrascrittura, il nome host sembra essere l’id contenitore breve in Docker 1.12

 [email protected]:/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 

Ciò otterrà l’ID contenitore completo da un contenitore:

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

AVVISO: è necessario comprendere i rischi per la sicurezza di questo metodo prima di considerarlo. Riassunto del rischio di John :

Consentendo al contenitore di accedere a /var/run/docker.sock , è [banalmente facile] rompere il contenimento fornito dalla finestra mobile e accedere 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
  • avviarlo con --volume /var/run/docker.sock:/var/run/docker.sock --privileged
  • infine, esegui: docker inspect $(hostname) all’interno del contenitore

Evita questo. Fallo solo se comprendi i rischi e hai una chiara attenuazione per i rischi.

Ho scoperto che nel 17.09 c’è un modo più semplice di 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 

Per renderlo semplice,

  1. ID contenitore è il nome host all’interno della finestra mobile
  2. Le informazioni sul contenitore sono disponibili in / 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

Docker imposta il nome host sull’ID contenitore per impostazione predefinita, ma gli utenti possono sovrascriverlo 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 del contenitore:

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

È ansible 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.

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

Per inciso, se hai il pid del contenitore e vuoi ottenere l’id docker di quel contenitore, 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/"

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 la formattazione delle modifiche:

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

Per riferimento, qui ci sono gli snippits di / proc / self / cgroup dai container docker 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 

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