Como posso obter informações sobre o contêiner do Docker Linux no próprio contêiner?

135

Gostaria de informar minha docker containersconfiguração, da mesma maneira que você pode obter informações sobre instâncias do EC2 por meio de metadados.

Eu posso usar (desde que dockeresteja ouvindo na porta 4243)

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

para obter alguns de seus dados, mas gostaria de saber se existe uma maneira melhor de obter pelo menos o ID completo do contêiner, porque HOSTNAMEna verdade é reduzido para 12 caracteres e o docker parece executar uma "melhor correspondência" nele.

Além disso, como posso obter o IP externo do host do docker (além de acessar os metadados do EC2, específicos da AWS)

Alessandro
fonte
2
CUIDADO: você deve ler este lvh.io/posts/... antes de tentar qualquer uma das abordagens a seguir que a tentativa de usar /var/run/docker.sock dentro do recipiente
harschware
1
No caso de quebra de link do @ harschware, vou resumir aqui: Ao dar acesso ao contêiner /var/run/docker.sock, é possível (trivial) romper a contenção fornecida pelo docker e obter acesso à máquina host. Obviamente, isso é potencialmente perigoso.
João
1
Alguém sabe como obter as mesmas informações em um contêiner do Windows docker se o argumento --hostname foi usado com o comando run, para que simplesmente executar 'hostname' não for mais o ID do contêiner?
Timothy John Laird

Respostas:

68

Descobri que o ID do contêiner pode ser encontrado em / proc / self / cgroup

Assim, você pode obter o ID com:

cat /proc/self/cgroup | grep -o  -e "docker-.*.scope" | head -n 1 | sed "s/docker-\(.*\).scope/\\1/"
Thomas A.
fonte
15
Teve que ajustá-lo um pouco, isso funciona para mim em Docker 1.4.1 cat /proc/self/cgroup | grep "docker" | sed s/\\//\\n/g | tail -1
ICAS
5
Para o docker 1.6.2, eu tive 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 27/07
24
Eu meio que gosto basename "$(cat /proc/1/cpuset)"ebasename "$(head /proc/1/cgroup)"
madeddie 14/11/16
3
No futuro, se o namespace cgroup e o cgroup v2 forem usados ​​na janela de encaixe, esse método poderá não funcionar mais.
Jing Qiu #
69

A menos que substituído, o nome do host parece ser o ID do contêiner curto no 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
fonte
4
Sim, isso facilitou a obtenção das informações em nodejs para mim. const os = require('os'); console.log(os.hostname());
pulkitsinghal
2
Para obter o nome do host que corresponde ao ID do contêiner em Java, use InetAddress.getLocalHost().getHostName().
Nathan
2
Às vezes, é mais simples ler o valor da variável de ambiente $HOSTNAME(por exemplo, em scripts de shell).
Faheel
34

Você pode se comunicar com a janela de encaixe de dentro de um contêiner usando soquete unix via Docker Remote API:

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

Em um contêiner, você pode descobrir um ID de janela de encaixe em curto examinando $HOSTNAMEenv var. Segundo o doc, há uma pequena chance de colisão, acho que, para um pequeno número de contêiner, você não precisa se preocupar com isso. Não sei como obter o ID completo diretamente.

Você pode inspecionar o contêiner da mesma maneira descrita na resposta banyan :

GET /containers/4abbef615af7/json HTTP/1.1

Resposta:

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

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

Como alternativa, você pode transferir o ID da janela de encaixe para o contêiner em um arquivo. O arquivo está localizado no "volume montado" e é transferido para o contêiner:

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

O ID da janela de encaixe (abreviado) estará no arquivo /mydir/host1.txt no contêiner.

Jiri
fonte
2
Obrigado, mas esta é a mesma abordagem que estou usando de qualquer maneira e será interrompida se você definir o nome do host com -h quando executar o docker.
Alessandro
@Alessandro Adicionei informações sobre o parâmetro -cidfile à execução do docker. Isso pode ajudá-lo a passar o ID do docker para o contêiner, em vez de usar $ HOSTNAME.
Jiri
Ótimo! Sim, isso é algo que eu poderia usar! Obrigado!
Alessandro
Estranhamente, no 1.11.2, parece envque não lista HOSTNAME, mas echo $HOSTNAMEfunciona.
precisa
Isso não funciona e seu URL está quebrado e agora é redirecionado para a documentação incorreta. requests.exceptions.MissingSchema: Invalid URL '/containers/1d26a841bf07/json': No schema supplied. Perhaps you meant http:///containers/1d26a841bf07/json?
Cerin
24

Isso obterá o ID completo do contêiner dentro de um contêiner:

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

Um comentário de madeddie parece mais elegante para mim:

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

AVISO: Você deve entender os riscos de segurança desse método antes de considerá-lo. Resumo de John do risco:

Ao dar acesso ao contêiner /var/run/docker.sock, é [trivialmente fácil] romper a contenção fornecida pelo docker e obter acesso à máquina host. Obviamente, isso é potencialmente perigoso.


Dentro do contêiner, o dockerId é o seu nome de host. Então, você poderia:

  • instale o pacote docker-io em seu contêiner com a mesma versão do host
  • comece com --volume /var/run/docker.sock:/var/run/docker.sock --privileged
  • finalmente, execute: docker inspect $(hostname)dentro do contêiner

Evite isso. Somente faça isso se você entender os riscos e tiver uma mitigação clara dos riscos.

Omar Marquez
fonte
1
Eu suspeito que isso não funcionará se a --hostnameopção de execução do docker tiver sido usada.
precisa saber é o seguinte
Se --hostnameestiver definido, você poderá usar uma combinação desta resposta e o comentário de @Jay Taylor na resposta aceita: docker inspect $(cat /proc/self/cgroup | grep 'docker' | sed 's/^.*\///' | tail -n1)para obter todas as informações sobre o contêiner em execução.
Michael K.
você poderia colocar uma referência ao docker-io?
Brad P.
Suponho que seu npmjs.com/package/docker-io, mas foi exatamente isso que o Google me disse e talvez não seja o que você quis dizer.
Brad P.
15

Para simplificar,

  1. ID do contêiner é o seu nome de host na janela de encaixe
  2. As informações do contêiner estão disponíveis em / proc / self / cgroup

Para obter o nome do host,

hostname

ou

uname -n

ou

cat /etc/host

A saída pode ser redirecionada para qualquer arquivo e lida novamente a partir da aplicação. # hostname > /usr/src//hostname.txt

Tejas jain
fonte
10

Descobri que na versão 17.09 existe uma maneira mais simples de fazê-lo no contêiner do docker:

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

Ou, como já foi dito, uma versão mais curta com

$ cat /etc/hostname
4de1c09d3f19

Ou simplesmente:

$ hostname
4de1c09d3f19
Adrian Antunez
fonte
6

O Docker define o nome do host como o ID do contêiner por padrão, mas os usuários podem substituí-lo por --hostname. Em vez disso, inspecione /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

Aqui está uma lista prática para extrair o ID do contêiner:

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

Você pode usar esta linha de comando para identificar o ID do contêiner atual (testado com a janela de encaixe 1.9).

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

Em seguida, faça uma pequena solicitação à API do Docker (você pode compartilhar /var/run/docker.sock) para recuperar todas as informações.

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

Algumas soluções postadas pararam de funcionar devido a alterações no formato de /proc/self/cgroup. Aqui está um único comando GNU grep que deve ser um pouco mais robusto para formatar alterações:

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

Para referência, aqui estão os trechos de / proc / self / cgroup dos contêineres do docker que foram testados com 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
kanaka
fonte
1
awk -F'[:/]' '(($4 == "docker") && (lastId != $NF)) { lastId = $NF; print $NF; }' /proc/self/cgroup
Andrew Wolfe
fonte
0

Além disso, se você tem o pid do contêiner e deseja obter o ID da janela de encaixe desse contêiner, uma boa maneira é usar o nsenter em combinação com a mágica sed acima:

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

anbhat
fonte
-19

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

Pode obter o ip da seguinte maneira.

$ docker inspect -format="{{ .NetworkSettings.IPAddress }}" 2a5624c52119
172.17.0.24
banyan
fonte
5
Não é isso que eu quero dizer. Eu preciso ser capaz de obter essas informações de dentro do contêiner. Basicamente, preciso de uma maneira de entender o ID de um contêiner que estou executando por dentro.
Alessandro