Tutorial  on  ContainersLinux

Containers are processes

A core benefit of using containers is that most of the time you don’t have to think about what’s happening under the hood. Tools like Docker and Kubernetes do a great job of hiding complexity from their users.

However, when you need to debug and secure containerized environments, it can be very helpful to understand how to interact with containers at a low level. Fortunately, because most containerization tools are built on Linux, you can use existing Linux tools to interact with and debug them.

When securing containerized environments, it’s also vital to understand how containers use layers of isolation—and how those layers can fail—so you can mitigate any risks.

This series will break down how containers work and walk through some practical ideas for securing and troubleshooting containerized environments. We’ll mainly focus on standard Docker-style containers throughout this series, but our examples will also apply to other container runtimes like Podman, containerd, and CRI-O.

In this tutorial, we'll demonstrate that containers are processes, use Linux tools to interact with containers, and explore what this means for securing container environments.

Containers are just processes

The first thing to understand about containers is that, from an operating system perspective, they’re processes—just like any other application that runs directly on the host. To demonstrate this, we can create a Linux virtual machine and install Docker on it. Note: if you’re interested in following along with the practical examples in this series, we recommend using a standard Linux VM instead of Docker for Windows/MacOS, as those tools add some complexity that makes it harder to see what’s happening.

Let's start by checking if there are any active processes named nginx on our tutorial playground. If you haven't already, click the "Start playground" button on the right. Then we can run the command below to look for nginx instances

ps -fC nginx

This should return an empty list, as we don’t have any NGINX web servers running at the moment.

Now, let's start a Docker container by using the nginx image from Docker Hub.

docker run --name webserver -d nginx:latest

Once the container is up, we'll run our ps command again:

ps -fC nginx

This time, we get back something like the below, which shows us that several NGINX processes are now running on the machine. As far as our Linux machine is concerned, someone just ran NGINX on the host.

As we dig deeper into the notion that containers are processes, one initial question might be: how do you tell the difference between an NGINX server started from a Docker image and one that’s just been installed on a VM? There are a couple of ways to do that, but the first, easiest one is to check for running containers with docker ps:

Alternatively, we could use Linux process tools to determine if the web server is running as a container for example with the --forest option on ps.

ps -ef --forest

This lets us see a hierarchy of processes. In this case, our NGINX processes have a parent process of containerd-shim-runc-v2. You should see a shim process for each container running on the host. This shim process is part of containerd and is used by Docker to manage contained processes. The goal of this shim process is to allow containerd or the Docker daemon to be restarted without having to restart all the containers running on the host.

Interacting with a container as a process

We now know that containers are just processes—but what does that mean in terms of how we can interact with them? Being able to interact with them as processes is useful for both troubleshooting their operation and investigating changes in running containers (for example, in a forensic investigation). There are a couple of things to keep in mind here, but the first is that we can use the /proc filesystem to get more information about our running containers.

The /proc filesystem in Linux is a virtual or pseudo filesystem. It doesn’t contain real files—instead, it is populated with information about the running system. As long as a user has the right privileges on a host that runs Docker, they can use /proc to access information about any container running on the host.

Let’s look at some information about the NGINX container we started up earlier. first we'll get a note of the PID of our nginx container, this time using docker inspect which shows details of the running container

docker inspect --format '{{.State.Pid}}' webserver

Next we'll list the files in /proc.

ls /proc

We will see a numbered directory for every process on the host including the PID that you got as output from the docker inspect command. Each of these directories contains a variety of files and directories with information about that process, meaning that we can navigate into the directory for our container to find out more about our contained process.

It can also be helpful to use Linux tooling to work with containers that have been hardened to remove tools such as file editors or process monitors. Hardening container images is a common security recommendation, but it does make debugging trickier. You can edit files inside the container by accessing the container’s root filesystem from the /proc directory on the host. Navigating to /proc/[PID]/root will give you the directory listing of the contained process that has that PID.

You can run the command below, replacing [PID] with the process ID of your container to see that output.

sudo ls /proc/[PID]/root

The result should look a lot like this.

We can confirm that this is the filesystem for our container, by creating a new file inside the container using docker exec and then seeing the result in the proc filesystem

First run this docker exec command to create a new file in the container

docker exec webserver touch /test_file

Then run the ls command again, replacing [PID] with the process ID of your container.

sudo ls /proc/[PID]/root

Conclusion

One of the first steps to understanding how containers work and how their security isolation is implemented, is realising that they're just processes.

Discussion:  Discord
Categories: ContainersLinux
Tags:  #docker

Level up your Server Side game — Join 10,000 engineers who receive insightful learning materials straight to their inbox