有没有办法确定进程(脚本)是否在lxc容器(~ Docker运行时)中运行?我知道有些程序能够检测它们是否在虚拟机中运行,是否有类似的方法适用于lxc/docker?
Docker在容器内部的目录树根目录创建了一个.dockerenv
文件。可以通过执行ls -la /.dockerenv
来查看它是否在容器启动时被创建。
您可以运行此脚本进行验证:
#!/bin/bash
if [ -f /.dockerenv ]; then
echo "I'm inside matrix ;(";
else
echo "I'm living in real world!";
fi
更多信息:
Ubuntu实际上有一个Bash脚本:/bin/running-in-container
,它可以返回所调用的容器类型。这可能会很有帮助。不过其他主要的发行版我就不清楚了。/.dockerenv
在ubuntu:20.04和alpine:3.12上都可用,所以我认为这绝对是最好的答案。 - Meir Gabay/bin/running-in-container
。 - Daniel Griscom最可靠的方法是检查 /proc/1/cgroup
。它会告诉你 init 进程的控制组,当你不在容器内时,所有层级的控制组都将显示为/
。当你在容器内部时,你将看到主机点的名称。针对 LXC/Docker 容器,分别为 /lxc/<containerid>
或 /docker/<containerid>
。
docker
而不是lxc
。 - Andygrep 'docker\|lxc' /proc/1/cgroup
对我有效。 - rypel在一个新的ubuntu 16.04系统上,使用新的systemd和lxc 2.0版本。
sudo grep -qa container=lxc /proc/1/environ
grep -q container=lxc /proc/1/environ
不足以吗? - Alek/proc/$$/environ
用空字节分隔环境变量。如果没有使用 -a
,则 man 手册中的以下内容适用:默认情况下,TYPE 是二进制的,当 grep 发现 null 输入二进制数据后,它会抑制输出。- Adam Azarchs
/proc/1/environ
包含 container=podman
。因此我使用了 grep -qa '^container='
。 - fstamour在bash脚本中检查Docker/LXC的简洁方法是:
#!/bin/bash
if grep -sq 'docker\|lxc' /proc/1/cgroup; then
echo "I am running on Docker."
fi
一个检查是否在 Docker 中运行的 Python 实用函数:
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()
kubepods
。 - rookie099root@33044d65037c:~# cat /proc/1/sched | head -n 1
bash (5276, #threads: 1)
在非容器主机上:
$ cat /proc/1/sched | head -n 1
init (1, #threads: 1)
这有助于区分您是否在容器中。
sh
而不是 init
,但在任何一个中都可以是几乎任何东西。 - Jan Hudecbash-5.0# cat /proc/1/sched bash (1, #threads: 1)
- shalomb$ ps -p 2
PID TTY TIME CMD
2 ? 00:00:00 kthreadd
在容器中,此PID要么不存在,要么不是kthreadd。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
最简单的方法是检查环境。如果你有container=lxc
变量,那么你就在容器里。
否则,如果你是root用户,可以尝试执行mknod
或mount
操作,如果失败了,那么你很可能在一个被削弱能力的容器中。
/proc/1/cgroup
无法让你检测到。 - Draco AterFROM 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
为了简洁起见,在上述代码中我省略了baremetal。
/proc/self/cgroup
被挂载到主机上的控制组。例如,在一个容器中:# awk -F: '/cpuset/' /proc/self/cgroup
3:cpuset:/docker/22bd0c154fb4e0d1b6c748faf1f1a12116acc21ce287618a115ad2bea41256b3
然而,在主机上相同的情况下
$ awk -F: '/cpuset/' /proc/self/cgroup
3:cpuset:/
使用shell中的某个东西进行低调测试
is_running_in_container() {
awk -F: '/cpuset/ && $3 ~ /^\/$/ { c=1 } END{ exit c }' /proc/self/cgroup
}
if is_running_in_container; then
echo "Aye!! I'm in a container"
else
echo "Nay!! I'm not in a container"
fi