docker 内进程如何检测自身是否在容器内运行?

2021-04-19 10:28:51 +08:00
 keithszc

https://github.com/seata/seata/issues/3621

从这个问题想到的,问题本身并不关键。

关于回答内的这一句话 “所以如果这两个目录( DOCKER_PATH 、KUBEPODS_PATH )都不存在的话,就会认为当前运行环境是非容器的”

我想知道的是,这两个目录具体是啥目录,原理是什么?而且貌似还有办法把这个检测方法绕过去?

1894 次点击
所在节点    Docker
9 条回复
ch2
2021-04-19 11:02:56 +08:00
getpid,如果自己的 pid 是 1 那就是在容器里运行的
x66
2021-04-19 11:09:57 +08:00
容器启动进程的 PID 为 1,可以通过这个思路来检测吧
keithszc
2021-04-19 11:15:54 +08:00
@ch2 感谢回复,我想知道的是 seata 里面检查文件目录的方式,貌似和 cgroup 有关。
keithszc
2021-04-19 11:16:05 +08:00
@x66 感谢回复,我想知道的是 seata 里面检查文件目录的方式,貌似和 cgroup 有关。
blackcurrant
2021-04-19 11:20:25 +08:00
我们如何才能知道自己生活在虚拟世界之中?
keithszc
2021-04-19 11:34:34 +08:00
找人看了一眼 java 代码,检查的是容器内的 /proc/1/cgroup 内容,是否包含 /docker 或者 /kubepods 字样
所以使用 podman 代替 docker 好像会导致这个检测失效,
jim9606
2021-04-19 11:43:55 +08:00
可以参考 systemd 的检测方法
https://github.com/systemd/systemd/blob/main/src/basic/virt.c
detect_container 函数
hahastudio
2021-04-19 11:48:20 +08:00
Nitroethane
2021-04-19 12:18:13 +08:00
对于没有在 docker 中的 PID 为 1 的进程来说,它的 cgroup 目录都是 /。而对于 docker 中的进程来说,它的 cgroup 目录会包含 /docker 子字符串。下面是我的 Linux 上的结果。
docker 中 PID 为 1 的进程:
$ cat /proc/1/cgroup
12:hugetlb:/system.slice/docker-e0539beecb2db33df4af004f03877dda0ae7b880775bf1d7cf36e62013c468bf.scope
11:cpuset:/system.slice/docker-e0539beecb2db33df4af004f03877dda0ae7b880775bf1d7cf36e62013c468bf.scope
10:perf_event:/system.slice/docker-e0539beecb2db33df4af004f03877dda0ae7b880775bf1d7cf36e62013c468bf.scope
9:freezer:/system.slice/docker-e0539beecb2db33df4af004f03877dda0ae7b880775bf1d7cf36e62013c468bf.scope
8:memory:/system.slice/docker-e0539beecb2db33df4af004f03877dda0ae7b880775bf1d7cf36e62013c468bf.scope
7:rdma:/
6:blkio:/system.slice/docker-e0539beecb2db33df4af004f03877dda0ae7b880775bf1d7cf36e62013c468bf.scope
5:pids:/system.slice/docker-e0539beecb2db33df4af004f03877dda0ae7b880775bf1d7cf36e62013c468bf.scope
4:net_cls,net_prio:/system.slice/docker-e0539beecb2db33df4af004f03877dda0ae7b880775bf1d7cf36e62013c468bf.scope
3:cpu,cpuacct:/system.slice/docker-e0539beecb2db33df4af004f03877dda0ae7b880775bf1d7cf36e62013c468bf.scope
2:devices:/system.slice/docker-e0539beecb2db33df4af004f03877dda0ae7b880775bf1d7cf36e62013c468bf.scope
1:name=systemd:/system.slice/docker-e0539beecb2db33df4af004f03877dda0ae7b880775bf1d7cf36e62013c468bf.scope
0::/system.slice/docker-e0539beecb2db33df4af004f03877dda0ae7b880775bf1d7cf36e62013c468bf.scope


宿主机中 PID 为 1 的进程:
$ cat /proc/1/cgroup
12:hugetlb:/
11:cpuset:/
10:perf_event:/
9:freezer:/
8:memory:/init.scope
7:rdma:/
6:blkio:/init.scope
5:pids:/init.scope
4:net_cls,net_prio:/
3:cpu,cpuacct:/init.scope
2:devices:/init.scope
1:name=systemd:/init.scope
0::/init.scope



还可通过检测是否存在 /.dockerenv 文件来判断。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/771574

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX