有什么方法可以确定一个进程(脚本)是否在lxc容器中运行(~ Docker runtime)?我知道一些程序能够检测它们是否在虚拟机中运行,lxc/docker是否也有类似的功能?
当前回答
在bash脚本中检查docker/lxc的一个简单方法是:
#!/bin/bash
if grep -sq 'docker\|lxc' /proc/1/cgroup; then
echo "I am running on Docker."
fi
其他回答
在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
方便的Python函数检查是否运行在Docker:
def in_docker():
""" Returns: True if running in a Docker container, else False """
with open('/proc/1/cgroup', 'rt') as ifh:
return 'docker' in ifh.read()
这是一个老问题,但确实是个好问题。:)
我写了一些自动化脚本,我们在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
为了保持简洁,我在上面的代码中省略了裸金属。
也许这样做是有效果的:
if [ -z $(docker ps -q) ]; then
echo "There is not process currently running"
else
echo "There are processes running"
fi
这是你想要的吗?希望能有所帮助=)
截至2022年,在lxd v4.0+中,到目前为止,没有一个答案可以同时适用于docker和lxc。
dockerenv文件不适用于非docker容器。 检查/proc/1/cgroup中的所有层次结构都是/有点可能工作。然而,非容器上的一些层次结构是/init。scope (Ubuntu 20.04 cgroup 0和1).所以也不完全可靠。 在/proc/1/environ中检查container=lxc适用于lxc,但不适用于docker。此外,它还需要根权限。
到目前为止,我发现唯一一种在CentOS和Ubuntu上使用lxc(4.0)容器和Docker可靠工作的方法,而且不需要root权限,就是检查PID 2。
在所有主机系统中,PID 2是kthread:
$ ps -p 2
PID TTY TIME CMD
2 ? 00:00:00 kthreadd
在容器中,这个PID要么不存在,要么不是kthread。docker和lxc都显示:
root@85396f8bce58:/# ps -p 2
PID TTY TIME CMD
root@85396f8bce58:/#
最好的方法似乎是检查/proc/2/status:
$ head -n1 /proc/2/status
Name: kthreadd
所以像这样的东西似乎是有效的:
if [ -n "$(grep 'kthreadd' /proc/2/status 2>/dev/null)" ]; then
echo "Not in container"
else
echo "In container";
fi