【发布时间】:2021-01-09 23:39:24
【问题描述】:
我正在运行一些应用程序,其中应用程序必须知道它在 PODMAN 内运行而无需任何额外的环境变量,但容器内的 podman 配置必须提供详细信息而无需任何用户交互。
截至目前,我在容器内使用 cat /proc/self/cgroup| grep -i 'machine.slice/libpod-*' 开始使用 podman 检查进程是否在 pod 内。
有没有更好的处理方法?
【问题讨论】:
标签: podman
我正在运行一些应用程序,其中应用程序必须知道它在 PODMAN 内运行而无需任何额外的环境变量,但容器内的 podman 配置必须提供详细信息而无需任何用户交互。
截至目前,我在容器内使用 cat /proc/self/cgroup| grep -i 'machine.slice/libpod-*' 开始使用 podman 检查进程是否在 pod 内。
有没有更好的处理方法?
【问题讨论】:
标签: podman
从纯理论的角度来看,使用/proc/self/cgroup 的方法是一个坏主意,因为不能保证容器引擎不会在新的 cgroup 命名空间中生成容器,因此容器化进程只会看到其当前的 cgroup如/ 如下例所示(unshare -C 模拟容器引擎在启动容器时取消共享 cgroup 命名空间):
$ podman run -it --privileged archlinux/base
[root@da0277b524db /]# unshare -C
-sh-5.0# cat /proc/self/cgroup
12:freezer:/
11:perf_event:/
10:pids:/
9:blkio:/
8:hugetlb:/
7:rdma:/
6:cpu,cpuacct:/
5:cpuset:/
4:net_cls,net_prio:/
3:memory:/
2:devices:/
1:name=systemd:/
0::/
从实际的角度来看,容器引擎似乎关心与这个技巧的兼容性,例如Moby uses the host cgroup namespace by default,而且 Podman 似乎也使用了主机 cgroup 命名空间,所以这个流行的脏检查应该成功,但它仍然是对无意的隔离漏洞的利用,它自从 cgroup 命名空间不存在以来就存在了。
什么是替代品?
具体说 Podman 时,似乎容器引擎在container spec creation 期间插入了一个特殊的环境变量,表示容器化进程是使用特定的容器引擎启动的。因此,即使您在没有任何其他变量的情况下启动容器,您也可能会在其位置找到 container 变量:
$ podman run -it alpine
/ # env | grep container
container=podman
虽然这种方法也不是万无一失的(因为没有什么能阻止容器创建者覆盖这个变量),我觉得它比/proc/self/cgroup 的技巧好多,因为提供了这些东西由容器引擎有意,并且不太可能被覆盖无意,因为此变量不遵循一般命名约定并且不使用ALL_CAPS 样式。
【讨论】: