如何从容器本身中获取Docker Linux容器信息?


135

我想docker containers了解它们的配置,就像通过元数据获取有关EC2实例的信息一样。

我可以使用(假设docker正在监听port 4243

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

来获取它的一些数据,但想知道是否至少有一种更好的方法来获取容器的完整ID,因为HOSTNAME它实际上缩短为12个字符,而docker似乎对其执行了“最佳匹配”。

另外,如何获取docker主机的外部IP(除了访问EC2元数据(特定于AWS)之外)


2
注意:您应先阅读lvh.io/posts/…,然后再尝试以下尝试在容器内使用/var/run/docker.sock的任何方法
harschware

1
万一@harschware的链接断开,我将在这里进行总结:通过授予容器对的访问权限/var/run/docker.sock,有可能(琐碎的)突破docker提供的限制并获得对主机的访问权限。显然,这是潜在的危险。
约翰(John John)

1
如果将--hostname参数与run命令一起使用,以便仅运行'hostname'不再为您提供containerid,是否有人知道如何在Windows docker容器中获取相同的信息?
蒂莫西·约翰·莱尔德

Answers:


68

我发现可以在/ proc / self / cgroup中找到容器ID

因此,您可以通过以下方式获取ID:

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

15
不得不cat /proc/self/cgroup | grep "docker" | sed s/\\//\\n/g | tail -1
稍作

5
对于docker 1.6.2,我必须使用: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

24
我有点像basename "$(cat /proc/1/cpuset)",并basename "$(head /proc/1/cgroup)"
madeddie

3
将来,如果在docker中使用cgroup名称空间和cgroup v2,则此方法可能不再起作用。
京秋

69

除非被覆盖,否则主机名似乎是Docker 1.12中的短容器ID。

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

在外部

$ 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
是的,这很容易为我提取nodejs中的信息。const os = require('os'); console.log(os.hostname());
pulkitsinghal

2
要获取与Java中的Container ID匹配的主机名,请使用InetAddress.getLocalHost().getHostName()
弥敦道

2
有时,读取环境变量的值更简单$HOSTNAME(例如在shell脚本中)。
Faheel

34

您可以通过Docker Remote API使用Unix套接字从容器内部与Docker通信:

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

在容器中,您可以通过检查$HOSTNAMEenv var 来找出缩短的docker id 。根据文档,发生碰撞的机会很小,我认为对于少量的容器,您不必担心。我不知道如何直接获取完整ID。

您可以按照榕树答案中概述的方式检查容器:

GET /containers/4abbef615af7/json HTTP/1.1

响应:

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

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

或者,您可以将docker id传输到文件中的容器。该文件位于“已安装卷”上,因此已传输到容器:

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

泊坞窗ID(已缩短)将位于容器中的文件/mydir/host1.txt中。


2
谢谢,但是无论如何,这是我正在使用的相同方法,如果在运行docker时将主机名设置为-h,将会中断。
亚历山德罗(Alessandro)2014年

@Alessandro我已将有关-cidfile参数的信息添加到docker run中。它可以帮助您将docker id传递给容器,而不是使用$ HOSTNAME。
吉里(Jiri)2014年

大!是的,这是我可以使用的东西!谢谢!
亚历山德罗(Alessandro)2014年

奇怪的是,在1.11.2中,它似乎env没有列出HOSTNAME,但是echo $HOSTNAME有效。
Jesse Glick

这根本不起作用,您的URL已损坏,现在重定向到错误的文档。requests.exceptions.MissingSchema: Invalid URL '/containers/1d26a841bf07/json': No schema supplied. Perhaps you meant http:///containers/1d26a841bf07/json?
塞林

24

这将从容器中获取完整的容器ID:

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


21

警告:在考虑此方法之前,您应该了解此方法的安全风险约翰对风险的总结:

通过给容器访问/var/run/docker.sock,可以轻松地摆脱docker提供的限制并获得对主机的访问权限。显然,这是潜在的危险。


在容器内,dockerId是您的主机名。因此,您可以:

  • docker-io软件包安装在与主机版本相同的容器中
  • 从开始 --volume /var/run/docker.sock:/var/run/docker.sock --privileged
  • 最后,运行:docker inspect $(hostname)在容器内

避免这种情况。仅在您了解风险并明确缓解风险后才这样做。


1
我怀疑如果使用了docker run --hostname选项,这将无法正常工作。
hairyhenderson

如果--hostname设置为if,则可以结合使用此答案和@Jay Taylor在接受的答案中的注释docker inspect $(cat /proc/self/cgroup | grep 'docker' | sed 's/^.*\///' | tail -n1)来获取有关正在运行的容器的所有信息。
Michael K.

您能参考一下docker-io吗?
布拉德·

我假设其为npmjs.com/package/docker-io,但这只是Google告诉我的,也许不是您的意思。
布拉德·

15

为了简单起见,

  1. 容器ID是您在Docker中的主机名
  2. 容器信息位于/ proc / self / cgroup中

要获取主机名,

hostname

要么

uname -n

要么

cat /etc/host

可以将输出重定向到任何文件并从应用程序中读取,例如: # hostname > /usr/src//hostname.txt


10

我发现在17.09中,有一种最简单的方法可以在docker容器中进行操作:

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

或者像已经讲过的那样,

$ cat /etc/hostname
4de1c09d3f19

或者简单地:

$ hostname
4de1c09d3f19

6

Docker默认将主机名设置为容器ID,但是用户可以使用来覆盖它--hostname。相反,请检查/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

这是提取容器ID的便捷方法:

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

2

您可以使用此命令行来标识当前容器ID(已在docker 1.9上测试)。

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

然后,向Docker API发出一些请求(您可以共享/var/run/docker.sock)以检索所有信息。


1
awk -F“-| /”。'/ 1:/ {print $ 3}'/ proc / self / cgroup
使用

2

由于格式更改,某些已发布的解决方案已停止工作/proc/self/cgroup。这是一个GNU grep命令,对格式化更改应该更健壮一些:

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

作为参考,以下是已使用此命令测试过的docker容器内部的/ proc / self / cgroup片段:

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


0

顺便说一句,如果您具有容器的pid并想要获取该容器的docker id,一个好方法是将nsenter与上述sed魔术结合使用:

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


-19

使用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",
...

可以得到ip如下。

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

5
这不是我的意思。我需要能够从容器内部获取此信息。基本上,我需要一种方法来从内部了解我正在运行的容器的ID。
亚历山德罗(Alessandro)2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.