我想让我docker containers了解他们的配置,就像通过元数据获取有关EC2实例的信息一样.
我可以使用(提供的docker是监听端口4243)
curl http://172.17.42.1:4243/containers/$HOSTNAME/json
Run Code Online (Sandbox Code Playgroud)
得到它的一些数据,但想知道是否有更好的方法至少获得容器的完整ID,因为HOSTNAME实际上缩短为12个字符,并且docker似乎在它上执行"最佳匹配".
另外,如何获取docker主机的外部IP(除了访问特定于AWS的EC2元数据)
小智 66
我发现容器ID可以在/ proc/self/cgroup中找到
所以你可以获得id:
cat /proc/self/cgroup | grep -o -e "docker-.*.scope" | head -n 1 | sed "s/docker-\(.*\).scope/\\1/"
Run Code Online (Sandbox Code Playgroud)
ard*_*igh 54
除非被覆盖,否则主机名似乎是Docker 1.12中的短容器ID
root@d2258e6dec11:/project# cat /etc/hostname
d2258e6dec11
Run Code Online (Sandbox Code Playgroud)
外部
$ 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
Run Code Online (Sandbox Code Playgroud)
Jir*_*iri 33
您可以使用unix socket通过Docker Remote API从容器内部与docker通信:
https://docs.docker.com/engine/reference/api/docker_remote_api/
在容器中,您可以通过检查$HOSTNAMEenv var 找到缩短的docker id .根据doc,碰撞的可能性很小,我认为对于少量的容器,你不必担心它.我不知道如何直接获得完整的id.
您可以按照榕树回答中概述的方式检查容器:
GET /containers/4abbef615af7/json HTTP/1.1
Run Code Online (Sandbox Code Playgroud)
响应:
HTTP/1.1 200 OK
Content-Type: application/json
{
"Id": "4abbef615af7...... ",
"Created": "2013.....",
...
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以将docker id传输到文件中的容器.该文件位于"已安装的卷"上,因此它被转移到容器:
docker run -t -i -cidfile /mydir/host1.txt -v /mydir:/mydir ubuntu /bin/bash
Run Code Online (Sandbox Code Playgroud)
docker id(缩短)将位于容器中的文件/mydir/host1.txt中.
Pri*_*ner 21
这将从容器中获取完整的容器ID:
cat /proc/self/cgroup | grep "cpu:/" | sed 's/\([0-9]\):cpu:\/docker\///g'
Run Code Online (Sandbox Code Playgroud)
小智 20
警告:在考虑此方法之前,您应该了解此方法的安全风险.约翰对风险的总结:
通过让容器访问
/var/run/docker.sock,可以轻松地打开docker提供的包含并获得对主机的访问权限.显然这有潜在危险.
在容器内,dockerId是您的主机名.所以,你可以:
--volume
/var/run/docker.sock:/var/run/docker.sock --privileged docker inspect $(hostname)容器内部避免这样做.只有了解风险并明确减轻风险,才能做到这一点.
sir*_*rex 13
Madeddie的评论对我来说似乎最优雅:
CID=$(basename $(cat /proc/1/cpuset))
Run Code Online (Sandbox Code Playgroud)
Tej*_*ain 12
为了简单起见,
要获得主机名,
hostname
Run Code Online (Sandbox Code Playgroud)
要么
uname -n
Run Code Online (Sandbox Code Playgroud)
要么
cat /etc/host
Run Code Online (Sandbox Code Playgroud)
输出可以重定向到任何文件并从应用程序读回例如: # hostname > /usr/src//hostname.txt
我发现在17.09中有一种最简单的方法可以在docker容器中执行它:
$ cat /proc/self/cgroup | head -n 1 | cut -d '/' -f3
4de1c09d3f1979147cd5672571b69abec03d606afcc7bdc54ddb2b69dec3861c
Run Code Online (Sandbox Code Playgroud)
或者就像它已被告知,更短的版本
$ cat /etc/hostname
4de1c09d3f19
Run Code Online (Sandbox Code Playgroud)
或者干脆:
$ hostname
4de1c09d3f19
Run Code Online (Sandbox Code Playgroud)
小智 8
到目前为止,我认为有 3 个地方可能可行,每个地方都有优点和缺点:
echo $HOSTNAME或者hostnamecat /proc/self/cgroupcat /proc/self/mountinfo$HOSTNAME很简单,但是是片面的,而且也会被K8s覆盖为pod名称。
/proc/self/cgroup似乎与cgroupV1一起使用,但不会托管在cgroupV2中。
/proc/self/mountinfo仍将具有cgroupV2的容器 ID ,但是,不同的容器运行时挂载点将具有不同的值。
678 655 254:1 /docker/containers/7a0144cee1256c539fab790199527b7051aff1b603ebcf7ed3fd436440ef3b3a/resolv.conf /etc/resolv.conf rw,relatime - ext4 /dev/vda1 rw
Run Code Online (Sandbox Code Playgroud)
ContainerD(最近的 K8s 默认引擎)中,它看起来像:1733 1729 0:35 /kubepods/besteffort/pod3272f253-be44-4a82-a541-9083e68cf99f/7a0144cee1256c539fab790199527b7051aff1b603ebcf7ed3fd436440ef3b3a /sys/fs/cgroup/blkio ro,nosuid,nodev,noexec,relatime master:17 - cgroup cgroup rw,blkio
Run Code Online (Sandbox Code Playgroud)
另外,以上所有的最大问题是它们都是实现,没有抽象,并且它们都可能随着时间的推移而改变。
人们正在努力使其成为标准,我认为值得关注:
https://github.com/opencontainers/runtime-spec/issues/1105
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
Run Code Online (Sandbox Code Playgroud)
这是一个方便的单行程序来提取容器ID:
$ grep "memory:/" < /proc/self/cgroup | sed 's|.*/||'
7be92808767a667f35c8505cbf40d14e931ef6db5b0210329cf193b15ba9d605
Run Code Online (Sandbox Code Playgroud)
由于/proc/self/cgroup. 下面是一个 GNU grep 命令,它对于格式更改应该更加稳健:
grep -o -P -m1 'docker.*\K[0-9a-f]{64,}' /proc/self/cgroup
Run Code Online (Sandbox Code Playgroud)
作为参考,以下是来自 docker 容器内部的 /proc/self/cgroup 的片段,这些片段已经使用此命令进行了测试:
Linux 4.4:
11:pids:/system.slice/docker-cde7c2bab394630a42d73dc610b9c57415dced996106665d427f6d0566594411.scope
...
1:name=systemd:/system.slice/docker-cde7c2bab394630a42d73dc610b9c57415dced996106665d427f6d0566594411.scope
Run Code Online (Sandbox Code Playgroud)
Linux 4.8 - 4.13:
11:hugetlb:/docker/afe96d48db6d2c19585572f986fc310c92421a3dac28310e847566fb82166013
...
1:name=systemd:/docker/afe96d48db6d2c19585572f986fc310c92421a3dac28310e847566fb82166013
Run Code Online (Sandbox Code Playgroud)