有什么方法可以确定一个进程(脚本)是否在lxc容器中运行(~ Docker runtime)?我知道一些程序能够检测它们是否在虚拟机中运行,lxc/docker是否也有类似的功能?


当前回答

我已经将JJC的答案翻译成ruby

def in_docker
  File.open('/proc/1/cgroup', 'rt') do |f|
    contents = f.read
    return contents =~ /docker/i || contents =~ /kubepod/i
  end
rescue StandardError => e
  p 'Local development'
  p e
  false
end

其他回答

在bash脚本中检查docker/lxc的一个简单方法是:

#!/bin/bash
if grep -sq 'docker\|lxc' /proc/1/cgroup; then
   echo "I am running on Docker."
fi

最可靠的方法是检查/proc/1/cgroup.它会告诉你init进程的控制组,当你不在容器中时,它会是/ for所有层次结构。当您在容器内时,您将看到锚点的名称。对于LXC/Docker容器,它将分别类似于/ LXC/ <containerid>或/Docker /<containerid>。

我的回答只适用于Node.js进程,但可能与一些无意中遇到这个问题并寻找Node.js特定答案的访问者相关。

我也遇到了同样的问题,我在/proc/self/cgroup上创建了一个npm包,专门用于检测一个Node.js进程是否在Docker容器中运行。

容器化的npm模块将在Node.js中帮助你。它目前还没有在Io.js中测试,但也可以在那里工作。

这是一个老问题,但确实是个好问题。:)

我写了一些自动化脚本,我们在baremetal, VM和docker容器上运行,基于脚本执行的平台进行逻辑分支。在我的情况下,我有创建容器和docker镜像的特权,所以这个解决方案只在你控制整个堆栈时才会起作用:

Dockerfile片段:

FROM ubuntu:18.04

ENV PLATFORM="docker"

RUN apt update; \
...

然后,脚本可以在每个平台上检查$PLATFORM的值,以获得所需的结果:

#!/bin/bash

# Check for executor specification in environment
case $PLATFORM in
  docker)
    # If running in Docker, do this stuff
    echo "Running containerized, proceeding..."
    ;;
  virtual)
    # If running in a VM, do different stuff
    echo "Running on a VM, loading VM stuff..."
    modprobe some-kernel-module
    ;;
  *)
    echo "Unknown executor specified! Exiting..."
    exit 1
    ;;
esac

为了保持简洁,我在上面的代码中省略了裸金属。

在Python中检查以上所有的解决方案:

import os

def in_container():
    proc_1 = r'/proc/1/sched'

    if os.path.exists(proc_1):
        with open(proc_1, 'r') as fp:
            out = fp.read()
    else:
        out = ''

    checks = [
        'docker' in out,
        '/lxc/' in out,
        out.split(' ')[0] not in ('systemd', 'init',),
        os.path.exists('./dockerenv'),
        os.path.exists('/.dockerinit'),
        os.getenv('container') is not None
    ]
    return any(checks)


if __name__ == '__main__':
    print(in_container())

概念证明:

$ docker run --rm -it --mount type=bind,source=${PWD}/incontainer.py,target=/tmp/script.py python:3 python /tmp/script.py
True