首页 > 解决方案 > 如何使用 cgroup v2 从容器中获取 docker 容器 ID

问题描述

由于 Docker 自引擎版本 20.10 起支持 cgroup v2,它将自动在启用了 cgroups v2 的发行版上使用它。从容器内获取唯一容器 ID 的已知解决方案不再有效。

/ # cat /proc/self/cgroup
0::/

/ # cat /proc/1/cpuset
/

使用 alpine:latest 在 Debian 11 上使用 docker v20.10.8 进行了尝试。

cgroup v1 的工作解决方案: 如何从容器本身获取 Docker Linux 容器信息?

如 docker 参考中所述,对于 cgroup v2,容器 ID 在文件系统中的以下位置仍然可见,但无法从容器本身访问这些位置。

/sys/fs/cgroup/memory/docker/<longid>/ on cgroup v1, cgroupfs driver
/sys/fs/cgroup/memory/system.slice/docker-<longid>.scope/ on cgroup v1, systemd driver
/sys/fs/cgroup/docker/<longid/> on cgroup v2, cgroupfs driver
/sys/fs/cgroup/system.slice/docker-<longid>.scope/ on cgroup v2, systemd driver

https://docs.docker.com/config/containers/runmetrics/#find-the-cgroup-for-a-given-container

编辑 1/2021-09-01:

一种解决方法是使用选项运行容器--cgroupns host。但这需要控制容器的创建。

$ docker run -it --cgroupns host alpine cat /proc/self/cgroup
0::/system.slice/docker-09ec67119d38768dbf7994d81c325e2267214428a3c2e581c81557e3650863d8.scope

$ docker run -it alpine cat /proc/self/cgroup
0::/

问题:

有什么方法可以从内部获取唯一的容器 ID?(无需依赖容器主机名或不必使用 docker api 来获取 id)

标签: linuxdockercgroups

解决方案


这似乎不需要查询 cgroup 也不需要使用主机名的值,主机名有时没有设置为容器 id 的值,例如在带有 docker 执行器的 gitlab 运行器中。

OVERLAY_ID=`cat /proc/self/mountinfo | grep -i overlay | sed -n "s/.\+upperdir\\=\\(.\+\\)\\/diff.\+/\1/p"`
CONTAINER_ID=`docker inspect -f $'{{.ID}}\t{{.Name}}\t{{.GraphDriver.Data.MergedDir}}' $(docker ps -aq) | grep $OVERLAY_ID | sed -n "s/\t\+.\+//p"`
echo $CONTAINER_ID

感谢@soxfmr,我如何确定哪个容器拥有哪个覆盖目录?


推荐阅读