¿Cómo puedo obtener información del contenedor Docker Linux desde el contenedor mismo?

135

Me gustaría informarme docker containersde su configuración, de la misma manera que puede obtener información sobre instancias de EC2 a través de metadatos.

Puedo usar (siempre que dockeresté escuchando en el puerto 4243)

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

para obtener algunos de sus datos, pero me gustaría saber si hay una mejor manera de obtener al menos la identificación completa del contenedor, porque en HOSTNAMErealidad se acorta a 12 caracteres y la ventana acoplable parece realizar una "mejor coincidencia".

Además, ¿cómo puedo obtener la IP externa del host del acoplador (aparte de acceder a los metadatos EC2, que es específico de AWS)

Alessandro
fuente
2
CUIDADO: debe leer este lvh.io/posts/… antes de intentar cualquiera de los siguientes enfoques que intentan usar /var/run/docker.sock dentro del contenedor
harschware
1
En caso de que se rompa el enlace de @harschware, resumiré aquí: al darle acceso al contenedor /var/run/docker.sock, es posible (trivial) salir de la contención proporcionada por la ventana acoplable y obtener acceso a la máquina host. Obviamente esto es potencialmente peligroso.
John
1
¿Alguien sabe cómo obtener la misma información en un contenedor de ventana acoplable de Windows si se utilizó el argumento --hostname con el comando de ejecución para que simplemente ejecutar 'hostname' ya no le proporcione el contenedor?
Timothy John Laird

Respuestas:

68

Descubrí que la identificación del contenedor se puede encontrar en / proc / self / cgroup

Para que pueda obtener la identificación con:

cat /proc/self/cgroup | grep -o  -e "docker-.*.scope" | head -n 1 | sed "s/docker-\(.*\).scope/\\1/"
Thomas A.
fuente
15
Tuve que modificarlo un poco, esto funciona para mí en Docker 1.4.1 cat /proc/self/cgroup | grep "docker" | sed s/\\//\\n/g | tail -1
ICas
55
Para docker 1.6.2 tuve que usar: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 el
24
Me gusta basename "$(cat /proc/1/cpuset)"ybasename "$(head /proc/1/cgroup)"
madeddie
3
En el futuro, si el espacio de nombres cgroup y cgroup v2 se usan en Docker, es posible que este método ya no funcione.
Jing Qiu
69

A menos que se anule, el nombre de host parece ser el ID de contenedor corto en Docker 1.12

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

Externamente

$ 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
fuente
44
Sí, esto me facilitó extraer la información en nodejs. const os = require('os'); console.log(os.hostname());
pulkitsinghal 03 de
2
Para obtener el nombre de host que coincide con el Id. De contenedor en Java, use InetAddress.getLocalHost().getHostName().
Nathan
2
A veces es más sencillo leer el valor de la variable de entorno $HOSTNAME(por ejemplo, en los scripts de shell).
Faheel
34

Puede comunicarse con Docker desde el interior de un contenedor utilizando un socket Unix a través de Docker Remote API:

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

En un contenedor, puede encontrar una ID de acoplador acortada examinando $HOSTNAMEenv var. Según el documento, hay una pequeña posibilidad de colisión, creo que para un pequeño número de contenedores, no tiene que preocuparse por eso. No sé cómo obtener la identificación completa directamente.

Puede inspeccionar el contenedor de manera similar a la descrita en la respuesta de Banyan :

GET /containers/4abbef615af7/json HTTP/1.1

Respuesta:

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

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

Alternativamente, puede transferir la ID de Docker al contenedor en un archivo. El archivo se encuentra en el "volumen montado", por lo que se transfiere al contenedor:

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

La identificación del acoplador (acortada) estará en el archivo /mydir/host1.txt en el contenedor.

Jiri
fuente
2
Gracias, pero este es el mismo enfoque que estoy usando de todos modos, y se romperá si configura el nombre de host con -h cuando ejecuta Docker.
Alessandro
@Alessandro He agregado información sobre el parámetro -cidfile para ejecutar Docker. Puede ayudarlo a pasar el docker id al contenedor en lugar de usar $ HOSTNAME.
Jiri
¡Excelente! ¡Sí, eso es algo que podría usar! ¡Gracias!
Alessandro
Curiosamente, en 1.11.2 parece envque no aparece HOSTNAME, pero echo $HOSTNAMEfunciona.
Jesse Glick
Esto no funciona en absoluto, y su URL está rota y ahora redirige a la documentación incorrecta. requests.exceptions.MissingSchema: Invalid URL '/containers/1d26a841bf07/json': No schema supplied. Perhaps you meant http:///containers/1d26a841bf07/json?
Cerin
24

Esto obtendrá la identificación del contenedor completo desde dentro de un contenedor:

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

Un comentario de madeddie me parece más elegante:

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

ADVERTENCIA: Debe comprender los riesgos de seguridad de este método antes de considerarlo. Resumen del riesgo de John :

Al darle acceso al contenedor /var/run/docker.sock, es [trivialmente fácil] salir de la contención proporcionada por la ventana acoplable y obtener acceso a la máquina host. Obviamente esto es potencialmente peligroso.


Dentro del contenedor, el dockerId es su nombre de host. Entonces, podrías:

  • instale el paquete docker-io en su contenedor con la misma versión que el host
  • comenzar con --volume /var/run/docker.sock:/var/run/docker.sock --privileged
  • finalmente, ejecuta: docker inspect $(hostname)dentro del contenedor

Evita esto. Solo hágalo si comprende los riesgos y tiene una mitigación clara para los riesgos.

Omar Marquez
fuente
1
Sospecho que esto no funcionará si --hostnamese ha utilizado la opción de ejecución de Docker .
hairyhenderson
Si --hostnameestá configurado, puede usar una combinación de esta respuesta y el comentario de @Jay Taylor en la respuesta aceptada: docker inspect $(cat /proc/self/cgroup | grep 'docker' | sed 's/^.*\///' | tail -n1)para obtener toda la información sobre el contenedor en ejecución.
Michael K.
¿podrías poner una referencia a docker-io?
Brad P.
Supongo que es npmjs.com/package/docker-io, pero eso fue justo lo que Google me dijo y quizás no es lo que querías decir.
Brad P.
15

Para hacerlo simple,

  1. ID de contenedor es su nombre de host dentro de la ventana acoplable
  2. La información del contenedor está disponible dentro de / proc / self / cgroup

Para obtener el nombre de host,

hostname

o

uname -n

o

cat /etc/host

La salida se puede redirigir a cualquier archivo y volver a leer desde la aplicación, por ejemplo: # hostname > /usr/src//hostname.txt

Tejas jain
fuente
10

Descubrí que en 17.09 hay una forma más sencilla de hacerlo dentro del contenedor acoplable:

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

O como ya se ha dicho, una versión más corta con

$ cat /etc/hostname
4de1c09d3f19

O simplemente:

$ hostname
4de1c09d3f19
Adrian Antunez
fuente
6

Docker establece el nombre de host en la ID del contenedor de forma predeterminada, pero los usuarios pueden anular esto con --hostname. En cambio, inspeccione /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

Aquí hay un práctico one-liner para extraer la ID del contenedor:

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

Puede usar esta línea de comando para identificar la ID del contenedor actual (probado con Docker 1.9).

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

Luego, una pequeña solicitud a Docker API (puede compartir /var/run/docker.sock) para recuperar toda la información.

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

Algunas soluciones publicadas han dejado de funcionar debido a cambios en el formato de /proc/self/cgroup. Aquí hay un solo comando grep de GNU que debería ser un poco más robusto para formatear los cambios:

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

Como referencia, aquí hay fragmentos de / proc / self / cgroup desde dentro de los contenedores acoplables que se han probado con este 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
canaca
fuente
1
awk -F'[:/]' '(($4 == "docker") && (lastId != $NF)) { lastId = $NF; print $NF; }' /proc/self/cgroup
Andrew Wolfe
fuente
0

Por otro lado, si tiene el pid del contenedor y desea obtener la identificación del acoplador de ese contenedor, una buena manera es usar nsenter en combinación con la magia sed anterior:

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

anbhat
fuente
-19

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

Puede obtener ip de la siguiente manera.

$ docker inspect -format="{{ .NetworkSettings.IPAddress }}" 2a5624c52119
172.17.0.24
secretario
fuente
55
Esto no es lo que quiero decir. Necesito poder obtener esta información desde el interior del contenedor. Básicamente, necesito una forma de entender la ID de un contenedor que estoy ejecutando desde el interior.
Alessandro