Mat*_*rga 152 linux bash docker
有没有办法确定进程(脚本)是否在lxc容器(~Docker运行时)内运行?我知道有些程序能够检测它们是否在虚拟机内运行,是否类似于lxc/docker?
jpe*_*zzo 154
最可靠的方法是检查/proc/1/cgroup.它将告诉您init进程的控制组,当您不在容器中时,它将/适用于所有层次结构.当您在容器内时,您将看到锚点的名称; 其中,与LXC/Docker容器,将会像/lxc/<containerid>或/docker/<containerid>分别.
at0*_*t0S 149
Docker .dockerenv在容器内的目录树的根目录下创建一个文件.您可以运行此脚本进行验证
#!/bin/bash
if [ -f /.dockerenv ]; then
echo "I'm inside matrix ;(";
else
echo "I'm living in real world!";
fi
Run Code Online (Sandbox Code Playgroud)
更多:
Ubuntu实际上有一个bash脚本:/bin/running-in-container它实际上可以返回它被调用的容器类型.可能会有所帮助.但不知道其他主要发行版.
小智 19
在新的ubuntu 16.04系统上,新的systemd和lxc 2.0
sudo grep -qa container=lxc /proc/1/environ
Run Code Online (Sandbox Code Playgroud)
小智 15
在bash脚本中检查docker的简明方法是:
#!/bin/bash
if grep docker /proc/1/cgroup -qa; then
echo I'm running on docker.
fi
Run Code Online (Sandbox Code Playgroud)
JJC*_*JJC 13
方便的Python函数来检查是否在Docker中运行(仅限linux,obvs.):
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()
Run Code Online (Sandbox Code Playgroud)
Fer*_*der 12
截至 2022 年,对于 lxd v4.0+,迄今为止没有一个答案适用于 docker 和 lxc。
.dockerenv不适用于非 docker 容器。/proc/1/cgroup是否/都可行。然而,非容器上的一些层次结构是/init.scope(Ubuntu 20.04 cgroup 0 和 1)。所以也不完全可靠。container=lxcin/proc/1/environ适用于 lxc,但不适用于 docker。此外,它需要 root 权限。到目前为止,我发现在带有 lxc (4.0) 容器和 Docker 的 CentOS 和 Ubuntu 上可靠工作且不需要root 权限的唯一方法是检查 PID 2。
在所有主机系统上,PID 2 为kthreadd:
$ ps -p 2
PID TTY TIME CMD
2 ? 00:00:00 kthreadd
Run Code Online (Sandbox Code Playgroud)
在容器中,这个 PID 要么不存在,要么不是 kthreadd。docker 和 lxc 都显示:
root@85396f8bce58:/# ps -p 2
PID TTY TIME CMD
root@85396f8bce58:/#
Run Code Online (Sandbox Code Playgroud)
最好的方法似乎是检查/proc/2/status:
$ head -n1 /proc/2/status
Name: kthreadd
Run Code Online (Sandbox Code Playgroud)
所以这样的事情似乎有效:
if [ -n "$(grep 'kthreadd' /proc/2/status 2>/dev/null)" ]; then
echo "Not in container"
else
echo "In container";
fi
Run Code Online (Sandbox Code Playgroud)
小智 9
我们使用proc的sched(/ proc/$ PID/sched)来提取进程的PID.容器内的进程的PID将与主机上的PID(非容器系统)不同.
例如,容器上的/ proc/1/sched输出将返回:
root@33044d65037c:~# cat /proc/1/sched | head -n 1
bash (5276, #threads: 1)
Run Code Online (Sandbox Code Playgroud)
在非容器主机上:
$ cat /proc/1/sched | head -n 1
init (1, #threads: 1)
Run Code Online (Sandbox Code Playgroud)
这有助于区分您是否在容器中.
最简单的方法是检查环境.如果您有container=lxc变量,则您位于容器中.
否则,如果您是root用户,则可以尝试执行mknod或mount操作,如果失败,您很可能在具有已删除功能的容器中.
小智 6
这是一个老问题,但却是一个非常好的问题。:)
我编写了一些自动化脚本,我们在裸机、虚拟机和 Docker 容器中运行,并根据脚本执行的平台进行逻辑分支。就我而言,我有权创建容器和 docker 映像,因此只有当您控制整个堆栈时,此解决方案才有效:
Dockerfile 的片段:
FROM ubuntu:18.04
ENV PLATFORM="docker"
RUN apt update; \
...
Run Code Online (Sandbox Code Playgroud)
$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
Run Code Online (Sandbox Code Playgroud)
为了保持简洁,我在上面的代码中省略了 baremetal。
检查以上所有Python解决方案:
import os
import subprocess
def in_container():
# type: () -> bool
""" Determines if we're running in an lxc/docker container. """
out = subprocess.check_output('cat /proc/1/sched', shell=True)
out = out.decode('utf-8').lower()
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', None) is not None
]
return any(checks)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
51827 次 |
| 最近记录: |