How to determine if a process runs inside lxc/Docker?


Introduction

The main goal of this article is to find out the if the process is on the container. We have discussed several methods that could help us to filter out the non-container machine from the container once. Simple commands and some special kernel files are used to conclude our point.

Pre-requisite

To implement the complete article on your setup machine, you need to have the below-listed prerequisites −

  • Linux OS: Ubuntu

  • Docker Daemon and Client

Methods

Some of the methods that help identify the machine are listed below. The machine could be a container or a non-container.

  • Using Environmental Variables

  • Using the .dockerenv file

  • Using the Control group information

  • Using the CPU information

  • Using Process ID.

Using the Docker Environments

Environment variables are used to save/store information. The information can be a path to a specific file, username, password, etc.

Here we will create an environment variable that stores the text “DockerContainer”. This environment variable will be passed to the container image while running.

Step 1: Create a Dockerfile

Here we have created a minimal version of the Dockerfile that is needed to fulfill our requirements of creating a Docker image with the environment variable.

# 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"

Step 2: Build the image

Now build a Docker image for this Dockerfile.

Example

$ docker build -t env_test:latest.

Output

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

Step 3: Run the container

Here we have run the container and also passed the environment variable.

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

Step 4: Check if you are now in a container

$echo $TEST_ENV

Now let us get inside the container and check again

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

Output

Docker-Container

Hence this proves that we are inside the Docker container.

Using .dockerenv file

While creating a Docker container, a file “.dockerenv” is created at the root of the container. So, searching for this file could help us to know if we are inside the docker container or not.

On the Non-Container machine −

$ ls -la | grep ./dockerenv

This gives no output, hence the file is missing.

Now try on the Container machine −

/ # ls -la | grep .dockerenv

Output

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

Hence this proves we are on the container.

Using the proc file system

Specials files are a strong part of the Linux file system. One of the special systems is the proc file system. This is used to store the states of the kernel.

We have Control Groups and CPU schedules in this proc file system. The control group's information is stored at a specific location. These groups have different data for the non-container and container machines. The path for the control group is /proc/1/cgroup and for the CPU schedule is /proc/1/sched

Step 1: Non-Container machine

Data on both locations on Non-container machines (e.g. Ubuntu) −

Example

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

Output

systemd (1, #threads: 1)

In the control group.

Example

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

Output

0::/init.scope

Step 2: Container machine

Now on the container.

Example

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

Output

bash (1, #threads: 1)

The above output shows that the first scheduling is for bash or the entry point command in the container. But for the non-container machine, it is systemd(Ubuntu).

For the control group −

Example

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

Output

0::/

Using the process ID

Every process in Linux has a unique ID known as PID. There is a process kthread that is only present on non-container-based machines. Its PID is fixed to number two. So, by checking PID 2 we can identify if we are in a container or not.

At non-container machine

Example

$ ps 2

Output

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

At the container machine, it might not show any process. Process other than the kthread is possible as well.

Conclusions

The use of kernel files is assumed to be the best approach of all the methods mentioned above. Sometimes for the Docker container .dockerinit files are used to know if you are in a container or not.

Updated on: 05-Jan-2023

462 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements