V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
keithszc
V2EX  ›  Docker

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

  •  
  •   keithszc · 2021-04-19 10:28:51 +08:00 · 1867 次点击
    这是一个创建于 1316 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

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

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

    9 条回复    2021-04-19 12:18:13 +08:00
    ch2
        1
    ch2  
       2021-04-19 11:02:56 +08:00
    getpid,如果自己的 pid 是 1 那就是在容器里运行的
    x66
        2
    x66  
       2021-04-19 11:09:57 +08:00
    容器启动进程的 PID 为 1,可以通过这个思路来检测吧
    keithszc
        3
    keithszc  
    OP
       2021-04-19 11:15:54 +08:00
    @ch2 感谢回复,我想知道的是 seata 里面检查文件目录的方式,貌似和 cgroup 有关。
    keithszc
        4
    keithszc  
    OP
       2021-04-19 11:16:05 +08:00
    @x66 感谢回复,我想知道的是 seata 里面检查文件目录的方式,貌似和 cgroup 有关。
    blackcurrant
        5
    blackcurrant  
       2021-04-19 11:20:25 +08:00
    我们如何才能知道自己生活在虚拟世界之中?
    keithszc
        6
    keithszc  
    OP
       2021-04-19 11:34:34 +08:00
    找人看了一眼 java 代码,检查的是容器内的 /proc/1/cgroup 内容,是否包含 /docker 或者 /kubepods 字样
    所以使用 podman 代替 docker 好像会导致这个检测失效,
    jim9606
        7
    jim9606  
       2021-04-19 11:43:55 +08:00
    可以参考 systemd 的检测方法
    https://github.com/systemd/systemd/blob/main/src/basic/virt.c
    detect_container 函数
    hahastudio
        8
    hahastudio  
       2021-04-19 11:48:20 +08:00
    Nitroethane
        9
    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 文件来判断。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5572 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 06:59 · PVG 14:59 · LAX 22:59 · JFK 01:59
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.