如何从容器本身中获取docker linux容器信息?

f3temu5u  于 2021-08-20  发布在  Java
关注(0)|答案(15)|浏览(316)

我想做我的 docker containers 了解ec2示例的配置,同样可以通过元数据获得有关ec2示例的信息。
我可以使用(提供的) docker 正在监听端口 4243 )

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

获取它的一些数据,但想知道是否有更好的方法至少可以获取容器的完整id,因为 HOSTNAME 实际上缩短为12个字符,docker似乎在上面表现出“最佳匹配”。
另外,如何获取docker主机的外部ip(除了访问特定于aws的ec2元数据之外)

vm0i2vca

vm0i2vca1#

我发现容器id可以在/proc/self/cgroup中找到
因此,您可以通过以下方式获取id:

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

kokeuurv2#

除非重写,否则主机名似乎是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
6rqinv9w

6rqinv9w3#

您可以通过docker remote api使用unix套接字从容器内部与docker通信:
https://docs.docker.com/engine/reference/api/docker_remote_api/
在一个容器中,您可以通过检查来找出一个短的docker id $HOSTNAME 根据doc的说法,碰撞的可能性很小,我认为对于少量的容器,您不必担心。我不知道如何直接获得完整的身份证。
您可以按照榕树答案中所述的类似方式检查容器:

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

docker id(缩写)将位于容器中的文件/mydir/host1.txt中。

pinkon5k

pinkon5k4#

madeddie的一句评论在我看来非常优雅:

CID=$(basename $(cat /proc/1/cpuset))
dauxcl2d

dauxcl2d5#

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

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

cotxawn76#

警告:在考虑该方法之前,您应该了解该方法的安全风险。john对风险的总结:
通过允许容器访问 /var/run/docker.sock ,它[非常容易]突破docker提供的限制并访问主机。显然,这有潜在的危险。
在容器中,dockerid是您的主机名。因此,你可以:
在与主机版本相同的容器中安装docker io包
--volume /var/run/docker.sock:/var/run/docker.sock --privileged 最后,运行: docker inspect $(hostname) 容器内
避免这种情况。只有在您了解风险并有明确的风险缓解措施的情况下,才可以这样做。

cbjzeqam

cbjzeqam7#

简单地说,
容器id是docker中的主机名
容器信息在/proc/self/cgroup中可用
要获取主机名,

hostname

uname -n

cat /etc/host

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

3pvhb19x

3pvhb19x8#

我发现在17.09中,在docker容器中有一种最简单的方法:

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

或者像已经被告知的那样,一个简短的版本

$ cat /etc/hostname
4de1c09d3f19

或者简单地说:

$ hostname
4de1c09d3f19
bmp9r5qi

bmp9r5qi9#

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
bvhaajcl

bvhaajcl10#

您可以使用此命令行标识当前容器id(使用docker 1.9测试)。

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

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

xa9qqrwz

xa9qqrwz11#

一些已发布的解决方案由于格式的更改而停止工作 /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
fkvaft9z

fkvaft9z12#

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

iklwldmw13#

我认为上述所有内容的“问题”在于,它取决于docker本身或其实现的某种实现约定,以及该约定如何与cgroups和/proc交互,而不是通过作为oci规范一部分的已提交、公共、api、协议或约定。
因此,这些解决方案是“脆弱的”,当实现发生变化或约定被用户配置覆盖时,很可能在最不期望的情况下崩溃。
启动容器示例的组件应将容器和映像ID注入r/t环境中,除非出于其他原因,允许其中运行的代码使用该信息来唯一标识自己以进行日志记录/跟踪等。。。
只有我的0.02美元,ymmv。。。

h9a6wy2h

h9a6wy2h14#

另一方面,如果您有容器的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/"

23c0lvtd

23c0lvtd15#

使用 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

相关问题