有什么方法可以确定一个进程(脚本)是否在lxc容器中运行(~ Docker runtime)?我知道一些程序能够检测它们是否在虚拟机中运行,lxc/docker是否也有类似的功能?
当前回答
在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
其他回答
Docker每天都在发展,所以我们不能肯定他们将来是否会保留.dockerenv .dockerinit。
在大多数Linux版本中,init是第一个启动的进程。但在容器的情况下,这不是真的。
#!/bin/bash
if ps -p1|grep -q init;then
echo "non-docker"
else
echo "docker"
fi
这个SO问答:“找出操作系统是否在虚拟环境中运行”;虽然与OP的问题不一样,但它确实回答了找到你所在容器的常见情况(如果有的话)。
特别是,安装并阅读这个bash脚本的代码,它似乎工作得很好:
virt-what:
sudo apt install virt-what
这是一个老问题,但确实是个好问题。:)
我写了一些自动化脚本,我们在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
为了保持简洁,我在上面的代码中省略了裸金属。
最简单的方法是检查环境。如果你有container=lxc变量,你就在一个容器中。
否则,如果您是根用户,您可以尝试执行mknod或mount操作,如果失败,则很可能处于已删除功能的容器中。
我们使用进程的调度(/proc/$PID/sched)来提取进程的PID。容器内进程的PID与主机上的PID不同(非容器系统)。
例如,容器上的/proc/1/sched的输出 将返回:
root@33044d65037c:~# cat /proc/1/sched | head -n 1
bash (5276, #threads: 1)
在非容器主机上:
$ cat /proc/1/sched | head -n 1
init (1, #threads: 1)
这有助于区分您是否在容器中。
推荐文章
- 为什么用反斜杠开始shell命令?
- 如何找到Java堆大小和内存使用(Linux)?
- 在Bash Shell脚本中生成1到10之间的随机数
- 遍历带空格的文件列表
- 如何在bash中使用mod操作符?
- 在Bash中检查传递的参数是否为文件或目录
- Bash:无限睡眠(无限阻塞)
- 递归复制文件夹,不包括一些文件夹
- 在Bash中传递带有空格的字符串作为函数参数
- 如何使Python脚本在Linux中像服务或守护进程一样运行
- 如何在文件中grep不区分大小写的字符串?
- 如何使用文件的行作为命令的参数?
- time_t最终的类型定义是什么?
- 如何从DockerFile运行docker实例?
- 我是否试图连接到启用TLS的没有TLS的守护进程?