如何确定进程是否在LXC/Docker容器内运行?


简介

本文的主要目标是确定进程是否在容器中运行。我们讨论了几种方法,可以帮助我们将非容器机器从容器中过滤出来。我们使用简单的命令和一些特殊的内核文件来总结我们的观点。

先决条件

要在您的设置机器上实现本文的完整内容,您需要具备以下列出的先决条件:

  • Linux操作系统:Ubuntu

  • Docker守护进程和客户端

方法

下面列出了一些有助于识别机器的方法。该机器可能是容器或非容器。

  • 使用环境变量

  • 使用.dockerenv文件

  • 使用控制组信息

  • 使用CPU信息

  • 使用进程ID。

使用Docker环境

环境变量用于保存/存储信息。信息可以是特定文件的路径、用户名、密码等。

在这里,我们将创建一个存储文本“DockerContainer”的环境变量。运行时,此环境变量将传递到容器镜像。

步骤1:创建Dockerfile

在这里,我们创建了一个Dockerfile的最小版本,这是满足我们创建带有环境变量的Docker镜像的要求所需的。

# the bash image we are using is Busybox:latest FROM busybox:latest #create an environment variable needed when starting this image as a container ENV TEST_ENV="Docker-Container"

步骤2:构建镜像

现在为这个Dockerfile构建一个Docker镜像。

示例

$ docker build -t env_test:latest.

输出

Sending build context to Docker daemon 2.048kB
Step 1/2 : FROM busybox:latest
---> 9d5226e6ce3f
Step 2/2 : ENV TEST_ENV="Docker-Container"
---> Running in b993407fa937
Removing intermediate container b993407fa937
---> c9e931c275be
Successfully built c9e931c275be
Successfully tagged env_test:latest

步骤3:运行容器

在这里,我们运行了容器,并传递了环境变量。

$docker run -itd -e TEST_ENV="Docker-Container" --name cont env_test:latest

步骤4:检查您现在是否在容器中

$echo $TEST_ENV

现在让我们进入容器并再次检查

$docker exec -it cont sh /# echo $TEST_ENV

输出

Docker-Container

因此,这证明了我们位于Docker容器内。

使用.dockerenv文件

创建Docker容器时,会在容器的根目录下创建一个“.dockerenv”文件。因此,搜索此文件可以帮助我们了解我们是在Docker容器内还是容器外。

在非容器机器上:

$ ls -la | grep ./dockerenv

这没有输出,因此文件不存在。

现在尝试在容器机器上:

/ # ls -la | grep .dockerenv

输出

-rwxr-xr-x 1 root root 0 Dec 18 14:00 .dockerenv

因此,这证明我们位于容器中。

使用proc文件系统

特殊文件是Linux文件系统的重要组成部分。其中一个特殊系统是proc文件系统。它用于存储内核的状态。

我们在proc文件系统中具有控制组和CPU调度。控制组的信息存储在特定位置。这些组对于非容器和容器机器具有不同的数据。控制组的路径是 /proc/1/cgroup,CPU调度的路径是 /proc/1/sched

步骤1:非容器机器

非容器机器(例如Ubuntu)上这两个位置的数据:

示例

$ cat /proc/1/sched | head -n 1

输出

systemd (1, #threads: 1)

在控制组中。

示例

$ cat /proc/1/cgroup | head -n 1

输出

0::/init.scope

步骤2:容器机器

现在在容器中。

示例

/# cat /proc/1/sched | head -n 1

输出

bash (1, #threads: 1)

上述输出显示第一个调度程序是用于bash或容器中的入口点命令。但对于非容器机器,它是systemd(Ubuntu)。

对于控制组:

示例

/ # cat /proc/1/cgroup | head -n 1

输出

0::/

使用进程ID

Linux中的每个进程都有一个唯一的ID,称为PID。有一个进程kthread,它仅存在于基于非容器的机器上。它的PID固定为2。因此,通过检查PID 2,我们可以识别我们是否在容器中。

在非容器机器上

示例

$ ps 2

输出

PID TTY  STAT TIME  COMMAND
2   ?    S   0:00   [kthreadd]

在容器机器上,它可能不会显示任何进程。除了kthread之外的进程也是可能的。

结论

使用内核文件被认为是上述所有方法中最好的方法。有时,对于Docker容器,.dockerinit文件用于了解您是否在容器中。

更新于:2023年1月5日

浏览量:582

启动您的职业生涯

通过完成课程获得认证

开始
广告